aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2009-12-22 22:51:08 +0100
committerGravatar Gael Guennebaud <g.gael@free.fr>2009-12-22 22:51:08 +0100
commiteaaba30cacf078335ad41314bf1e4ce993f0b3b4 (patch)
tree61156273b56dc19fc4e661a5aeb42d8e6112a307
parente182e9c6166840b8db44e0be459a2e26d26fda0f (diff)
parenteeec7d842e05394703c42e7569230835f7842089 (diff)
merge with default branch
-rw-r--r--.hgignore4
-rw-r--r--CMakeLists.txt58
-rw-r--r--COPYING.LGPL2
-rw-r--r--Eigen/Array2
-rw-r--r--Eigen/CMakeLists.txt9
-rw-r--r--Eigen/Cholesky1
-rw-r--r--Eigen/Core7
-rw-r--r--Eigen/Eigenvalues1
-rw-r--r--Eigen/Geometry2
-rw-r--r--Eigen/Householder3
-rw-r--r--Eigen/Jacobi2
-rw-r--r--Eigen/LU5
-rw-r--r--Eigen/LeastSquares1
-rw-r--r--Eigen/QR1
-rw-r--r--Eigen/QtAlignedMalloc1
-rw-r--r--Eigen/SVD1
-rw-r--r--Eigen/Sparse3
-rw-r--r--Eigen/StdVector2
-rw-r--r--Eigen/src/Array/Functors.h16
-rw-r--r--Eigen/src/Array/Random.h4
-rw-r--r--Eigen/src/Array/Replicate.h3
-rw-r--r--Eigen/src/Array/Select.h8
-rw-r--r--Eigen/src/Array/VectorwiseOp.h50
-rw-r--r--Eigen/src/Cholesky/LLT.h8
-rw-r--r--Eigen/src/Core/AnyMatrixBase.h8
-rw-r--r--Eigen/src/Core/Assign.h158
-rw-r--r--Eigen/src/Core/BandMatrix.h10
-rw-r--r--Eigen/src/Core/Coeffs.h32
-rw-r--r--Eigen/src/Core/CommaInitializer.h3
-rw-r--r--Eigen/src/Core/CwiseBinaryOp.h11
-rw-r--r--Eigen/src/Core/DenseBase.h39
-rw-r--r--Eigen/src/Core/DenseStorageBase.h17
-rw-r--r--Eigen/src/Core/DiagonalMatrix.h51
-rw-r--r--Eigen/src/Core/Dot.h26
-rw-r--r--Eigen/src/Core/ExpressionMaker.h6
-rw-r--r--Eigen/src/Core/Functors.h58
-rw-r--r--Eigen/src/Core/MathFunctions.h58
-rw-r--r--Eigen/src/Core/Matrix.h4
-rw-r--r--Eigen/src/Core/MatrixBase.h20
-rw-r--r--Eigen/src/Core/MatrixStorage.h3
-rw-r--r--Eigen/src/Core/Minor.h5
-rw-r--r--Eigen/src/Core/NestByValue.h3
-rw-r--r--Eigen/src/Core/NoAlias.h3
-rw-r--r--Eigen/src/Core/PermutationMatrix.h162
-rw-r--r--Eigen/src/Core/Product.h14
-rw-r--r--Eigen/src/Core/ProductBase.h10
-rw-r--r--Eigen/src/Core/Redux.h33
-rw-r--r--Eigen/src/Core/SelfAdjointView.h1
-rw-r--r--Eigen/src/Core/Swap.h3
-rw-r--r--Eigen/src/Core/Transpose.h80
-rw-r--r--Eigen/src/Core/TriangularMatrix.h134
-rw-r--r--Eigen/src/Core/arch/SSE/MathFunctions.h2
-rw-r--r--Eigen/src/Core/arch/SSE/PacketMath.h8
-rw-r--r--Eigen/src/Core/products/GeneralUnrolled.h28
-rw-r--r--Eigen/src/Core/util/BlasUtil.h18
-rw-r--r--Eigen/src/Core/util/Constants.h38
-rw-r--r--Eigen/src/Core/util/DisableMSVCWarnings.h7
-rw-r--r--Eigen/src/Core/util/Macros.h4
-rw-r--r--Eigen/src/Core/util/Memory.h16
-rw-r--r--Eigen/src/Core/util/XprHelper.h53
-rw-r--r--Eigen/src/Eigen2Support/Cwise.h5
-rw-r--r--Eigen/src/Eigenvalues/HessenbergDecomposition.h6
-rw-r--r--Eigen/src/Eigenvalues/Tridiagonalization.h13
-rw-r--r--Eigen/src/Geometry/AlignedBox.h2
-rw-r--r--Eigen/src/Geometry/AngleAxis.h4
-rw-r--r--Eigen/src/Geometry/EulerAngles.h2
-rw-r--r--Eigen/src/Geometry/Homogeneous.h10
-rw-r--r--Eigen/src/Geometry/Hyperplane.h6
-rw-r--r--Eigen/src/Geometry/OrthoMethods.h5
-rw-r--r--Eigen/src/Geometry/ParametrizedLine.h2
-rw-r--r--Eigen/src/Geometry/Quaternion.h58
-rw-r--r--Eigen/src/Geometry/Rotation2D.h2
-rw-r--r--Eigen/src/Geometry/Scaling.h2
-rw-r--r--Eigen/src/Geometry/Transform.h4
-rw-r--r--Eigen/src/Geometry/Translation.h2
-rw-r--r--Eigen/src/Geometry/arch/Geometry_SSE.h6
-rw-r--r--Eigen/src/Householder/HouseholderSequence.h38
-rw-r--r--Eigen/src/LU/CMakeLists.txt2
-rw-r--r--Eigen/src/LU/Determinant.h4
-rw-r--r--Eigen/src/LU/FullPivLU.h73
-rw-r--r--Eigen/src/LU/Inverse.h111
-rw-r--r--Eigen/src/LU/PartialPivLU.h29
-rw-r--r--Eigen/src/LU/arch/CMakeLists.txt6
-rw-r--r--Eigen/src/LU/arch/Inverse_SSE.h151
-rw-r--r--Eigen/src/QR/ColPivHouseholderQR.h249
-rw-r--r--Eigen/src/QR/FullPivHouseholderQR.h20
-rw-r--r--Eigen/src/QR/HouseholderQR.h13
-rw-r--r--Eigen/src/SVD/JacobiSVD.h15
-rw-r--r--Eigen/src/SVD/SVD.h5
-rw-r--r--Eigen/src/Sparse/AmbiVector.h6
-rw-r--r--Eigen/src/Sparse/CompressedStorage.h6
-rw-r--r--Eigen/src/Sparse/DynamicSparseMatrix.h16
-rw-r--r--Eigen/src/Sparse/RandomSetter.h2
-rw-r--r--Eigen/src/Sparse/SparseDiagonalProduct.h9
-rw-r--r--Eigen/src/Sparse/SparseExpressionMaker.h42
-rw-r--r--Eigen/src/Sparse/SparseLDLT.h4
-rw-r--r--Eigen/src/Sparse/SparseLLT.h4
-rw-r--r--Eigen/src/Sparse/SparseLU.h4
-rw-r--r--Eigen/src/Sparse/SparseMatrix.h15
-rw-r--r--Eigen/src/Sparse/SparseMatrixBase.h38
-rw-r--r--Eigen/src/Sparse/SparseNestByValue.h84
-rw-r--r--Eigen/src/Sparse/SparseUtil.h11
-rw-r--r--Eigen/src/Sparse/SparseVector.h15
-rw-r--r--Eigen/src/misc/Image.h6
-rw-r--r--Eigen/src/misc/Kernel.h4
-rw-r--r--Eigen/src/misc/Solve.h4
-rw-r--r--bench/BenchTimer.h15
-rw-r--r--bench/quat_slerp.cpp245
-rw-r--r--blas/README.txt4
-rw-r--r--blas/common.h12
-rw-r--r--cmake/EigenTesting.cmake67
-rw-r--r--cmake/FindEigen2.cmake8
-rw-r--r--cmake/FindEigen3.cmake80
-rw-r--r--debug/gdb/__init__.py1
-rw-r--r--debug/gdb/printers.py161
-rw-r--r--debug/msvc/eigen_autoexp_part.dat306
-rw-r--r--doc/C01_QuickStartGuide.dox4
-rw-r--r--doc/C05_TutorialLinearAlgebra.dox4
-rw-r--r--doc/CMakeLists.txt2
-rw-r--r--doc/D11_UnalignedArrayAssert.dox2
-rw-r--r--doc/Doxyfile.in25
-rw-r--r--doc/I00_CustomizingEigen.dox2
-rw-r--r--doc/I01_TopicLazyEvaluation.dox6
-rw-r--r--doc/Overview.dox2
-rw-r--r--doc/examples/class_CwiseBinaryOp.cpp3
-rw-r--r--doc/snippets/MatrixBase_extract.cpp4
-rw-r--r--doc/snippets/MatrixBase_marked.cpp4
-rw-r--r--doc/snippets/MatrixBase_part.cpp4
-rw-r--r--doc/snippets/PartialPivLU_solve.cpp (renamed from doc/snippets/PartialLU_solve.cpp)0
-rw-r--r--doc/snippets/class_FullPivLU.cpp6
-rw-r--r--eigen3.pc.in (renamed from eigen2.pc.in)3
-rw-r--r--scripts/CMakeLists.txt3
-rwxr-xr-xscripts/buildtests.in (renamed from test/buildtests.in)9
-rwxr-xr-xscripts/check.in8
-rwxr-xr-xscripts/eigen_gen_credits4
-rw-r--r--signature_of_eigen3_matrix_library1
-rw-r--r--test/CMakeLists.txt8
-rw-r--r--test/adjoint.cpp8
-rw-r--r--test/bandmatrix.cpp4
-rw-r--r--test/cholesky.cpp4
-rw-r--r--test/eigensolver_complex.cpp1
-rw-r--r--test/geo_hyperplane.cpp2
-rw-r--r--test/geo_quaternion.cpp2
-rw-r--r--test/inverse.cpp19
-rw-r--r--test/jacobisvd.cpp3
-rw-r--r--test/lu.cpp17
-rw-r--r--test/main.h102
-rw-r--r--test/permutationmatrices.cpp35
-rw-r--r--test/prec_inverse_4x4.cpp80
-rw-r--r--test/product.h2
-rw-r--r--test/product_selfadjoint.cpp8
-rw-r--r--test/product_syrk.cpp12
-rw-r--r--test/product_trsm.cpp2
-rw-r--r--test/qr.cpp10
-rw-r--r--test/qr_colpivoting.cpp36
-rw-r--r--test/qr_fullpivoting.cpp5
-rwxr-xr-xtest/runtest.sh2
-rw-r--r--test/sparse_basic.cpp4
-rw-r--r--test/stable_norm.cpp8
-rw-r--r--test/testsuite.cmake8
-rw-r--r--test/triangular.cpp196
-rw-r--r--test/unalignedassert.cpp1
-rw-r--r--test/vectorization_logic.cpp55
-rw-r--r--unsupported/Eigen/AlignedVector32
-rw-r--r--unsupported/Eigen/AutoDiff2
-rw-r--r--unsupported/Eigen/FFT39
-rw-r--r--unsupported/Eigen/MatrixFunctions12
-rw-r--r--unsupported/Eigen/NonLinearOptimization6
-rw-r--r--unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h24
-rw-r--r--unsupported/Eigen/src/AutoDiff/AutoDiffVector.h10
-rw-r--r--unsupported/Eigen/src/BVH/BVAlgorithms.h4
-rw-r--r--unsupported/Eigen/src/BVH/KdBVH.h4
-rw-r--r--unsupported/Eigen/src/CMakeLists.txt4
-rw-r--r--unsupported/Eigen/src/FFT/ei_kissfft_impl.h12
-rw-r--r--unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h28
-rw-r--r--unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h475
-rw-r--r--unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h86
-rw-r--r--unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h65
-rw-r--r--unsupported/Eigen/src/NonLinearOptimization/lmpar.h46
-rw-r--r--unsupported/Eigen/src/NonLinearOptimization/qrfac.h11
-rw-r--r--unsupported/Eigen/src/NonLinearOptimization/qrsolv.h170
-rw-r--r--unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h39
-rw-r--r--unsupported/Eigen/src/NumericalDiff/NumericalDiff.h5
-rw-r--r--unsupported/Eigen/src/Skyline/SkylineInplaceLU.h2
-rw-r--r--unsupported/Eigen/src/Skyline/SkylineMatrix.h2
-rw-r--r--unsupported/Eigen/src/Skyline/SkylineStorage.h2
-rw-r--r--unsupported/README.txt2
-rw-r--r--unsupported/doc/CMakeLists.txt6
-rw-r--r--unsupported/doc/Doxyfile.in11
-rw-r--r--unsupported/doc/examples/BVH_Example.cpp4
-rw-r--r--unsupported/doc/examples/CMakeLists.txt8
-rw-r--r--unsupported/doc/examples/MatrixExponential.cpp18
-rw-r--r--unsupported/doc/examples/MatrixFunction.cpp23
-rw-r--r--unsupported/doc/snippets/CMakeLists.txt2
-rw-r--r--unsupported/test/CMakeLists.txt5
-rw-r--r--unsupported/test/Complex.cpp2
-rw-r--r--unsupported/test/FFT.cpp13
-rw-r--r--unsupported/test/FFTW.cpp3
-rw-r--r--unsupported/test/autodiff.cpp12
-rw-r--r--unsupported/test/matrixExponential.cpp50
200 files changed, 3643 insertions, 1630 deletions
diff --git a/.hgignore b/.hgignore
index 9432702ba..3f08ce8d5 100644
--- a/.hgignore
+++ b/.hgignore
@@ -12,7 +12,7 @@ core
core.*
*.bak
*~
-build
+build*
*.moc.*
*.moc
ui_*
@@ -21,4 +21,4 @@ tags
.*.swp
activity.png
*.out
-*.php* \ No newline at end of file
+*.php*
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3a23479d7..a7d4089c0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,18 +3,18 @@ project(Eigen)
cmake_minimum_required(VERSION 2.6.2)
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
- message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there.")
+ message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. (you may need to remove CMakeCache.txt ")
endif()
# automatically parse the version number
-file(READ "${CMAKE_SOURCE_DIR}/Eigen/src/Core/util/Macros.h" _eigen2_version_header)
-string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen2_world_version_match "${_eigen2_version_header}")
-set(EIGEN2_WORLD_VERSION "${CMAKE_MATCH_1}")
-string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen2_major_version_match "${_eigen2_version_header}")
-set(EIGEN2_MAJOR_VERSION "${CMAKE_MATCH_1}")
-string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen2_minor_version_match "${_eigen2_version_header}")
-set(EIGEN2_MINOR_VERSION "${CMAKE_MATCH_1}")
-set(EIGEN_VERSION_NUMBER ${EIGEN2_WORLD_VERSION}.${EIGEN2_MAJOR_VERSION}.${EIGEN2_MINOR_VERSION})
+file(READ "${CMAKE_SOURCE_DIR}/Eigen/src/Core/util/Macros.h" _eigen_version_header)
+string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen_world_version_match "${_eigen_version_header}")
+set(EIGEN_WORLD_VERSION "${CMAKE_MATCH_1}")
+string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen_major_version_match "${_eigen_version_header}")
+set(EIGEN_MAJOR_VERSION "${CMAKE_MATCH_1}")
+string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen_minor_version_match "${_eigen_version_header}")
+set(EIGEN_MINOR_VERSION "${CMAKE_MATCH_1}")
+set(EIGEN_VERSION_NUMBER ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})
# if the mercurial program is absent, this will leave the EIGEN_HG_CHANGESET string empty,
# but won't stop CMake.
@@ -63,31 +63,43 @@ if(CMAKE_COMPILER_IS_GNUCXX)
if(NOT EIGEN_TEST_LIB)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
- endif(NOT EIGEN_TEST_LIB)
+ endif()
option(EIGEN_TEST_SSE2 "Enable/Disable SSE2 in tests/examples" OFF)
if(EIGEN_TEST_SSE2)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2")
message("Enabling SSE2 in tests/examples")
- endif(EIGEN_TEST_SSE2)
+ endif()
option(EIGEN_TEST_SSE3 "Enable/Disable SSE3 in tests/examples" OFF)
if(EIGEN_TEST_SSE3)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse3")
message("Enabling SSE3 in tests/examples")
- endif(EIGEN_TEST_SSE3)
+ endif()
option(EIGEN_TEST_SSSE3 "Enable/Disable SSSE3 in tests/examples" OFF)
if(EIGEN_TEST_SSSE3)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mssse3")
message("Enabling SSSE3 in tests/examples")
- endif(EIGEN_TEST_SSSE3)
+ endif()
+
+ option(EIGEN_TEST_SSE4_1 "Enable/Disable SSE4.1 in tests/examples" OFF)
+ if(EIGEN_TEST_SSE4_1)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1")
+ message("Enabling SSE4.1 in tests/examples")
+ endif()
+
+ option(EIGEN_TEST_SSE4_2 "Enable/Disable SSE4.2 in tests/examples" OFF)
+ if(EIGEN_TEST_SSE4_2)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.2")
+ message("Enabling SSE4.2 in tests/examples")
+ endif()
option(EIGEN_TEST_ALTIVEC "Enable/Disable altivec in tests/examples" OFF)
if(EIGEN_TEST_ALTIVEC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maltivec -mabi=altivec")
message("Enabling AltiVec in tests/examples")
- endif(EIGEN_TEST_ALTIVEC)
+ endif()
endif(CMAKE_SYSTEM_NAME MATCHES Linux)
endif(CMAKE_COMPILER_IS_GNUCXX)
@@ -112,19 +124,25 @@ endif(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)
option(EIGEN_TEST_C++0x "Enables all C++0x features." OFF)
-option(EIGEN_TEST_RVALUE_REF_SUPPORT "Enable rvalue references for unit tests." OFF)
+option(EIGEN_TEST_MAX_WARNING_LEVEL "Sets the warning level to /Wall while building the unit tests." OFF)
+mark_as_advanced(EIGEN_TEST_MAX_WARNING_LEVEL)
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
set(INCLUDE_INSTALL_DIR
- "${CMAKE_INSTALL_PREFIX}/include/eigen2"
+ "${CMAKE_INSTALL_PREFIX}/include/eigen3"
CACHE PATH
"The directory where we install the header files"
)
+install(FILES
+ signature_of_eigen3_matrix_library
+ DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel
+ )
+
if(EIGEN_BUILD_PKGCONFIG)
- configure_file(eigen2.pc.in eigen2.pc)
- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/eigen2.pc
+ configure_file(eigen3.pc.in eigen3.pc)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/eigen3.pc
DESTINATION share/pkgconfig
)
endif(EIGEN_BUILD_PKGCONFIG)
@@ -135,6 +153,9 @@ add_subdirectory(doc EXCLUDE_FROM_ALL)
include(CTest)
enable_testing() # must be called from the root CMakeLists, see man page
+include(EigenTesting)
+ei_init_testing()
+
if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
add_subdirectory(test) # can't do EXCLUDE_FROM_ALL here, breaks CTest
else()
@@ -147,6 +168,7 @@ add_subdirectory(demos EXCLUDE_FROM_ALL)
add_subdirectory(blas EXCLUDE_FROM_ALL)
+# must be after test and unsupported, for configuring buildtests.in
add_subdirectory(scripts EXCLUDE_FROM_ALL)
# TODO: consider also replacing EIGEN_BUILD_BTL by a custom target "make btl"?
diff --git a/COPYING.LGPL b/COPYING.LGPL
index fc8a5de7e..0e4fa8aaf 100644
--- a/COPYING.LGPL
+++ b/COPYING.LGPL
@@ -1,4 +1,4 @@
- GNU LESSER GENERAL PUBLIC LICENSE
+ GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
diff --git a/Eigen/Array b/Eigen/Array
index 276fdec2f..b35242f1a 100644
--- a/Eigen/Array
+++ b/Eigen/Array
@@ -45,3 +45,5 @@ namespace Eigen {
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_ARRAY_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
+
diff --git a/Eigen/CMakeLists.txt b/Eigen/CMakeLists.txt
index e0eb837a5..af90db2fe 100644
--- a/Eigen/CMakeLists.txt
+++ b/Eigen/CMakeLists.txt
@@ -1,7 +1,12 @@
-set(Eigen_HEADERS Core LU Cholesky QR Geometry Sparse Array SVD LeastSquares QtAlignedMalloc StdVector Householder Jacobi Eigenvalues)
+file(GLOB Eigen_directory_files "*")
+foreach(f ${Eigen_directory_files})
+ if(NOT f MATCHES ".txt" AND NOT f MATCHES "src")
+ list(APPEND Eigen_directory_files_to_install ${f})
+ endif()
+endforeach(f ${Eigen_directory_files})
install(FILES
- ${Eigen_HEADERS}
+ ${Eigen_directory_files_to_install}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen COMPONENT Devel
)
diff --git a/Eigen/Cholesky b/Eigen/Cholesky
index d4e80e46b..a0e0d146b 100644
--- a/Eigen/Cholesky
+++ b/Eigen/Cholesky
@@ -63,3 +63,4 @@ namespace Eigen {
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_CHOLESKY_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/Eigen/Core b/Eigen/Core
index fe1f1a5bf..d452a6cd9 100644
--- a/Eigen/Core
+++ b/Eigen/Core
@@ -71,6 +71,12 @@
#ifdef __SSSE3__
#include <tmmintrin.h>
#endif
+ #ifdef __SSE4_1__
+ #include <smmintrin.h>
+ #endif
+ #ifdef __SSE4_2__
+ #include <nmmintrin.h>
+ #endif
#elif defined __ALTIVEC__
#define EIGEN_VECTORIZE
#define EIGEN_VECTORIZE_ALTIVEC
@@ -216,3 +222,4 @@ struct Dense {};
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_CORE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/Eigen/Eigenvalues b/Eigen/Eigenvalues
index 8c6841549..1ae0cf098 100644
--- a/Eigen/Eigenvalues
+++ b/Eigen/Eigenvalues
@@ -73,3 +73,4 @@ namespace Eigen {
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_EIGENVALUES_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/Eigen/Geometry b/Eigen/Geometry
index c931f28fe..4fa715a3a 100644
--- a/Eigen/Geometry
+++ b/Eigen/Geometry
@@ -57,3 +57,5 @@ namespace Eigen {
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_GEOMETRY_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
+
diff --git a/Eigen/Householder b/Eigen/Householder
index ef3e61373..dcaeeeae8 100644
--- a/Eigen/Householder
+++ b/Eigen/Householder
@@ -8,7 +8,7 @@
namespace Eigen {
/** \defgroup Householder_Module Householder module
- * This module provides householder transformations.
+ * This module provides Householder transformations.
*
* \code
* #include <Eigen/Householder>
@@ -23,3 +23,4 @@ namespace Eigen {
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_HOUSEHOLDER_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/Eigen/Jacobi b/Eigen/Jacobi
index da67d2a6a..ce6ac1bff 100644
--- a/Eigen/Jacobi
+++ b/Eigen/Jacobi
@@ -26,3 +26,5 @@ namespace Eigen {
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_JACOBI_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
+
diff --git a/Eigen/LU b/Eigen/LU
index e4aa3ecde..9ef9c97ec 100644
--- a/Eigen/LU
+++ b/Eigen/LU
@@ -26,8 +26,13 @@ namespace Eigen {
#include "src/LU/Determinant.h"
#include "src/LU/Inverse.h"
+#if defined EIGEN_VECTORIZE_SSE
+ #include "src/LU/arch/Inverse_SSE.h"
+#endif
+
} // namespace Eigen
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_LU_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/Eigen/LeastSquares b/Eigen/LeastSquares
index 75620a349..61b83bbc8 100644
--- a/Eigen/LeastSquares
+++ b/Eigen/LeastSquares
@@ -25,3 +25,4 @@ namespace Eigen {
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_REGRESSION_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/Eigen/QR b/Eigen/QR
index de0179865..825cfb149 100644
--- a/Eigen/QR
+++ b/Eigen/QR
@@ -67,3 +67,4 @@ namespace Eigen {
#include "Eigenvalues"
#endif // EIGEN_QR_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/Eigen/QtAlignedMalloc b/Eigen/QtAlignedMalloc
index fce7edf9b..698607faa 100644
--- a/Eigen/QtAlignedMalloc
+++ b/Eigen/QtAlignedMalloc
@@ -31,3 +31,4 @@ void *qRealloc(void *ptr, size_t size)
#endif
#endif // EIGEN_QTMALLOC_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/Eigen/SVD b/Eigen/SVD
index 44f0f4b31..200aea351 100644
--- a/Eigen/SVD
+++ b/Eigen/SVD
@@ -31,3 +31,4 @@ namespace Eigen {
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_SVD_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/Eigen/Sparse b/Eigen/Sparse
index f4dcad07e..f027d3e6c 100644
--- a/Eigen/Sparse
+++ b/Eigen/Sparse
@@ -87,7 +87,6 @@ struct Sparse {};
#include "src/Sparse/SparseUtil.h"
#include "src/Sparse/SparseMatrixBase.h"
-#include "src/Sparse/SparseNestByValue.h"
#include "src/Sparse/CompressedStorage.h"
#include "src/Sparse/AmbiVector.h"
#include "src/Sparse/RandomSetter.h"
@@ -134,3 +133,5 @@ struct Sparse {};
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_SPARSE_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
+
diff --git a/Eigen/StdVector b/Eigen/StdVector
index f37de5ff6..b6dbde8a2 100644
--- a/Eigen/StdVector
+++ b/Eigen/StdVector
@@ -166,3 +166,5 @@ class vector<T,Eigen::aligned_allocator<T> >
}
#endif // EIGEN_STDVECTOR_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
+
diff --git a/Eigen/src/Array/Functors.h b/Eigen/src/Array/Functors.h
index fd259f7bc..975fd9c7f 100644
--- a/Eigen/src/Array/Functors.h
+++ b/Eigen/src/Array/Functors.h
@@ -56,7 +56,8 @@ struct ei_functor_traits<ei_scalar_add_op<Scalar> >
*
* \sa class CwiseUnaryOp, Cwise::sqrt()
*/
-template<typename Scalar> struct ei_scalar_sqrt_op EIGEN_EMPTY_STRUCT {
+template<typename Scalar> struct ei_scalar_sqrt_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_sqrt_op)
inline const Scalar operator() (const Scalar& a) const { return ei_sqrt(a); }
typedef typename ei_packet_traits<Scalar>::type Packet;
inline Packet packetOp(const Packet& a) const { return ei_psqrt(a); }
@@ -77,7 +78,8 @@ struct ei_functor_traits<ei_scalar_sqrt_op<Scalar> >
*
* \sa class CwiseUnaryOp, Cwise::cos()
*/
-template<typename Scalar> struct ei_scalar_cos_op EIGEN_EMPTY_STRUCT {
+template<typename Scalar> struct ei_scalar_cos_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_cos_op)
inline Scalar operator() (const Scalar& a) const { return ei_cos(a); }
typedef typename ei_packet_traits<Scalar>::type Packet;
inline Packet packetOp(const Packet& a) const { return ei_pcos(a); }
@@ -87,7 +89,7 @@ struct ei_functor_traits<ei_scalar_cos_op<Scalar> >
{
enum {
Cost = 5 * NumTraits<Scalar>::MulCost,
- PacketAccess = ei_packet_traits<Scalar>::HasCos && EIGEN_FAST_MATH
+ PacketAccess = ei_packet_traits<Scalar>::HasCos
};
};
@@ -99,7 +101,8 @@ struct ei_functor_traits<ei_scalar_cos_op<Scalar> >
*
* \sa class CwiseUnaryOp, Cwise::sin()
*/
-template<typename Scalar> struct ei_scalar_sin_op EIGEN_EMPTY_STRUCT {
+template<typename Scalar> struct ei_scalar_sin_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_sin_op)
inline const Scalar operator() (const Scalar& a) const { return ei_sin(a); }
typedef typename ei_packet_traits<Scalar>::type Packet;
inline Packet packetOp(const Packet& a) const { return ei_psin(a); }
@@ -109,7 +112,7 @@ struct ei_functor_traits<ei_scalar_sin_op<Scalar> >
{
enum {
Cost = 5 * NumTraits<Scalar>::MulCost,
- PacketAccess = ei_packet_traits<Scalar>::HasSin && EIGEN_FAST_MATH
+ PacketAccess = ei_packet_traits<Scalar>::HasSin
};
};
@@ -143,6 +146,7 @@ struct ei_functor_traits<ei_scalar_pow_op<Scalar> >
*/
template<typename Scalar>
struct ei_scalar_inverse_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_inverse_op)
inline Scalar operator() (const Scalar& a) const { return Scalar(1)/a; }
template<typename PacketScalar>
inline const PacketScalar packetOp(const PacketScalar& a) const
@@ -162,6 +166,7 @@ struct ei_functor_traits<ei_scalar_inverse_op<Scalar> >
*/
template<typename Scalar>
struct ei_scalar_square_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_square_op)
inline Scalar operator() (const Scalar& a) const { return a*a; }
template<typename PacketScalar>
inline const PacketScalar packetOp(const PacketScalar& a) const
@@ -181,6 +186,7 @@ struct ei_functor_traits<ei_scalar_square_op<Scalar> >
*/
template<typename Scalar>
struct ei_scalar_cube_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_cube_op)
inline Scalar operator() (const Scalar& a) const { return a*a*a; }
template<typename PacketScalar>
inline const PacketScalar packetOp(const PacketScalar& a) const
diff --git a/Eigen/src/Array/Random.h b/Eigen/src/Array/Random.h
index 34b835776..97ca0fba3 100644
--- a/Eigen/src/Array/Random.h
+++ b/Eigen/src/Array/Random.h
@@ -25,8 +25,8 @@
#ifndef EIGEN_RANDOM_H
#define EIGEN_RANDOM_H
-template<typename Scalar> struct ei_scalar_random_op EIGEN_EMPTY_STRUCT {
- inline ei_scalar_random_op(void) {}
+template<typename Scalar> struct ei_scalar_random_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_random_op)
inline const Scalar operator() (int, int) const { return ei_random<Scalar>(); }
};
template<typename Scalar>
diff --git a/Eigen/src/Array/Replicate.h b/Eigen/src/Array/Replicate.h
index 5a9b10738..3f87e09fe 100644
--- a/Eigen/src/Array/Replicate.h
+++ b/Eigen/src/Array/Replicate.h
@@ -97,9 +97,6 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
const typename MatrixType::Nested m_matrix;
const ei_int_if_dynamic<RowFactor> m_rowFactor;
const ei_int_if_dynamic<ColFactor> m_colFactor;
-
- private:
- Replicate& operator=(const Replicate&);
};
/** \nonstableyet
diff --git a/Eigen/src/Array/Select.h b/Eigen/src/Array/Select.h
index 1983bd870..b1fab69c9 100644
--- a/Eigen/src/Array/Select.h
+++ b/Eigen/src/Array/Select.h
@@ -134,11 +134,11 @@ DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
*/
template<typename Derived>
template<typename ThenDerived>
-inline const Select<Derived,ThenDerived, NestByValue<typename ThenDerived::ConstantReturnType> >
+inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
typename ThenDerived::Scalar elseScalar) const
{
- return Select<Derived,ThenDerived,NestByValue<typename ThenDerived::ConstantReturnType> >(
+ return Select<Derived,ThenDerived,typename ThenDerived::ConstantReturnType>(
derived(), thenMatrix.derived(), ThenDerived::Constant(rows(),cols(),elseScalar));
}
@@ -151,11 +151,11 @@ DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
*/
template<typename Derived>
template<typename ElseDerived>
-inline const Select<Derived, NestByValue<typename ElseDerived::ConstantReturnType>, ElseDerived >
+inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
DenseBase<Derived>::select(typename ElseDerived::Scalar thenScalar,
const DenseBase<ElseDerived>& elseMatrix) const
{
- return Select<Derived,NestByValue<typename ElseDerived::ConstantReturnType>,ElseDerived>(
+ return Select<Derived,typename ElseDerived::ConstantReturnType,ElseDerived>(
derived(), ElseDerived::Constant(rows(),cols(),thenScalar), elseMatrix.derived());
}
diff --git a/Eigen/src/Array/VectorwiseOp.h b/Eigen/src/Array/VectorwiseOp.h
index f6774a019..05dd69789 100644
--- a/Eigen/src/Array/VectorwiseOp.h
+++ b/Eigen/src/Array/VectorwiseOp.h
@@ -113,7 +113,8 @@ class PartialReduxExpr : ei_no_assignment_operator,
#define EIGEN_MEMBER_FUNCTOR(MEMBER,COST) \
template <typename ResultType> \
- struct ei_member_##MEMBER EIGEN_EMPTY_STRUCT { \
+ struct ei_member_##MEMBER { \
+ EIGEN_EMPTY_STRUCT_CTOR(ei_member_##MEMBER) \
typedef ResultType result_type; \
template<typename Scalar, int Size> struct Cost \
{ enum { value = COST }; }; \
@@ -124,6 +125,9 @@ class PartialReduxExpr : ei_no_assignment_operator,
EIGEN_MEMBER_FUNCTOR(squaredNorm, Size * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
EIGEN_MEMBER_FUNCTOR(norm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
+EIGEN_MEMBER_FUNCTOR(stableNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
+EIGEN_MEMBER_FUNCTOR(blueNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
+EIGEN_MEMBER_FUNCTOR(hypotNorm, (Size-1) * ei_functor_traits<ei_scalar_hypot_op<Scalar> >::Cost );
EIGEN_MEMBER_FUNCTOR(sum, (Size-1)*NumTraits<Scalar>::AddCost);
EIGEN_MEMBER_FUNCTOR(mean, (Size-1)*NumTraits<Scalar>::AddCost + NumTraits<Scalar>::MulCost);
EIGEN_MEMBER_FUNCTOR(minCoeff, (Size-1)*NumTraits<Scalar>::AddCost);
@@ -291,6 +295,33 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
const typename ReturnType<ei_member_norm>::Type norm() const
{ return _expression(); }
+
+ /** \returns a row (or column) vector expression of the norm
+ * of each column (or row) of the referenced expression, using
+ * blue's algorithm.
+ *
+ * \sa MatrixBase::blueNorm() */
+ const typename ReturnType<ei_member_blueNorm>::Type blueNorm() const
+ { return _expression(); }
+
+
+ /** \returns a row (or column) vector expression of the norm
+ * of each column (or row) of the referenced expression, avoiding
+ * underflow and overflow.
+ *
+ * \sa MatrixBase::stableNorm() */
+ const typename ReturnType<ei_member_stableNorm>::Type stableNorm() const
+ { return _expression(); }
+
+
+ /** \returns a row (or column) vector expression of the norm
+ * of each column (or row) of the referenced expression, avoiding
+ * underflow and overflow using a concatenation of hypot() calls.
+ *
+ * \sa MatrixBase::hypotNorm() */
+ const typename ReturnType<ei_member_hypotNorm>::Type hypotNorm() const
+ { return _expression(); }
+
/** \returns a row (or column) vector expression of the sum
* of each column (or row) of the referenced expression.
*
@@ -409,22 +440,22 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
template<typename OtherDerived>
CwiseBinaryOp<ei_scalar_sum_op<Scalar>,
ExpressionType,
- NestByValue<typename ExtendedType<OtherDerived>::Type> >
+ typename ExtendedType<OtherDerived>::Type>
operator+(const MatrixBase<OtherDerived>& other) const
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived);
- return m_matrix + extendedTo(other).nestByValue();
+ return m_matrix + extendedTo(other);
}
/** Returns the expression of the difference between each subvector of \c *this and the vector \a other */
template<typename OtherDerived>
CwiseBinaryOp<ei_scalar_difference_op<Scalar>,
ExpressionType,
- NestByValue<typename ExtendedType<OtherDerived>::Type> >
+ typename ExtendedType<OtherDerived>::Type>
operator-(const MatrixBase<OtherDerived>& other) const
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived);
- return m_matrix - extendedTo(other).nestByValue();
+ return m_matrix - extendedTo(other);
}
/////////// Geometry module ///////////
@@ -451,19 +482,16 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
Direction==Horizontal ? 1 : int(ei_traits<ExpressionType>::ColsAtCompileTime)>
HNormalized_Factors;
typedef CwiseBinaryOp<ei_scalar_quotient_op<typename ei_traits<ExpressionType>::Scalar>,
- NestByValue<HNormalized_Block>,
- NestByValue<Replicate<NestByValue<HNormalized_Factors>,
+ HNormalized_Block,
+ Replicate<HNormalized_Factors,
Direction==Vertical ? HNormalized_SizeMinusOne : 1,
- Direction==Horizontal ? HNormalized_SizeMinusOne : 1> > >
+ Direction==Horizontal ? HNormalized_SizeMinusOne : 1> >
HNormalizedReturnType;
const HNormalizedReturnType hnormalized() const;
protected:
ExpressionTypeNested m_matrix;
-
- private:
- VectorwiseOp& operator=(const VectorwiseOp&);
};
/** \array_module
diff --git a/Eigen/src/Cholesky/LLT.h b/Eigen/src/Cholesky/LLT.h
index a1706e53e..ad737aaeb 100644
--- a/Eigen/src/Cholesky/LLT.h
+++ b/Eigen/src/Cholesky/LLT.h
@@ -224,18 +224,18 @@ template<> struct ei_llt_inplace<UpperTriangular>
template<typename MatrixType> struct LLT_Traits<MatrixType,LowerTriangular>
{
typedef TriangularView<MatrixType, LowerTriangular> MatrixL;
- typedef TriangularView<NestByValue<typename MatrixType::AdjointReturnType>, UpperTriangular> MatrixU;
+ typedef TriangularView<typename MatrixType::AdjointReturnType, UpperTriangular> MatrixU;
inline static MatrixL getL(const MatrixType& m) { return m; }
- inline static MatrixU getU(const MatrixType& m) { return m.adjoint().nestByValue(); }
+ inline static MatrixU getU(const MatrixType& m) { return m.adjoint(); }
static bool inplace_decomposition(MatrixType& m)
{ return ei_llt_inplace<LowerTriangular>::blocked(m); }
};
template<typename MatrixType> struct LLT_Traits<MatrixType,UpperTriangular>
{
- typedef TriangularView<NestByValue<typename MatrixType::AdjointReturnType>, LowerTriangular> MatrixL;
+ typedef TriangularView<typename MatrixType::AdjointReturnType, LowerTriangular> MatrixL;
typedef TriangularView<MatrixType, UpperTriangular> MatrixU;
- inline static MatrixL getL(const MatrixType& m) { return m.adjoint().nestByValue(); }
+ inline static MatrixL getL(const MatrixType& m) { return m.adjoint(); }
inline static MatrixU getU(const MatrixType& m) { return m; }
static bool inplace_decomposition(MatrixType& m)
{ return ei_llt_inplace<UpperTriangular>::blocked(m); }
diff --git a/Eigen/src/Core/AnyMatrixBase.h b/Eigen/src/Core/AnyMatrixBase.h
index 0522c1d5e..d1c16923b 100644
--- a/Eigen/src/Core/AnyMatrixBase.h
+++ b/Eigen/src/Core/AnyMatrixBase.h
@@ -57,7 +57,7 @@ template<typename Derived> struct AnyMatrixBase
{ derived().evalTo(dst); }
/** \internal Don't use it, but do the equivalent: \code dst += *this; \endcode */
- template<typename Dest> inline void addToDense(Dest& dst) const
+ template<typename Dest> inline void addTo(Dest& dst) const
{
// This is the default implementation,
// derived class can reimplement it in a more optimized way.
@@ -67,7 +67,7 @@ template<typename Derived> struct AnyMatrixBase
}
/** \internal Don't use it, but do the equivalent: \code dst -= *this; \endcode */
- template<typename Dest> inline void subToDense(Dest& dst) const
+ template<typename Dest> inline void subTo(Dest& dst) const
{
// This is the default implementation,
// derived class can reimplement it in a more optimized way.
@@ -114,7 +114,7 @@ template<typename Derived>
template<typename OtherDerived>
Derived& DenseBase<Derived>::operator+=(const AnyMatrixBase<OtherDerived> &other)
{
- other.derived().addToDense(derived());
+ other.derived().addTo(derived());
return derived();
}
@@ -122,7 +122,7 @@ template<typename Derived>
template<typename OtherDerived>
Derived& DenseBase<Derived>::operator-=(const AnyMatrixBase<OtherDerived> &other)
{
- other.derived().subToDense(derived());
+ other.derived().subTo(derived());
return derived();
}
diff --git a/Eigen/src/Core/Assign.h b/Eigen/src/Core/Assign.h
index 466205208..d6bf37c6e 100644
--- a/Eigen/src/Core/Assign.h
+++ b/Eigen/src/Core/Assign.h
@@ -28,7 +28,7 @@
#define EIGEN_ASSIGN_H
/***************************************************************************
-* Part 1 : the logic deciding a strategy for vectorization and unrolling
+* Part 1 : the logic deciding a strategy for traversal and unrolling *
***************************************************************************/
template <typename Derived, typename OtherDerived>
@@ -53,44 +53,53 @@ private:
};
enum {
- MightVectorize = (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit)
- && ((int(Derived::Flags)&RowMajorBit)==(int(OtherDerived::Flags)&RowMajorBit)),
+ StorageOrdersAgree = (int(Derived::Flags)&RowMajorBit)==(int(OtherDerived::Flags)&RowMajorBit),
+ MightVectorize = StorageOrdersAgree
+ && (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit),
MayInnerVectorize = MightVectorize && int(InnerSize)!=Dynamic && int(InnerSize)%int(PacketSize)==0
&& int(DstIsAligned) && int(SrcIsAligned),
- MayLinearVectorize = MightVectorize && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit)
- && (DstIsAligned || InnerMaxSize == Dynamic),/* If the destination isn't aligned,
- we have to do runtime checks and we don't unroll, so it's only good for large enough sizes. See remark below
- about InnerMaxSize. */
- MaySliceVectorize = MightVectorize && int(InnerMaxSize)>=3*PacketSize /* slice vectorization can be slow, so we only
- want it if the slices are big, which is indicated by InnerMaxSize rather than InnerSize, think of the case
- of a dynamic block in a fixed-size matrix */
+ MayLinearize = StorageOrdersAgree && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit),
+ MayLinearVectorize = MightVectorize && MayLinearize
+ && (DstIsAligned || InnerMaxSize == Dynamic),
+ /* If the destination isn't aligned, we have to do runtime checks and we don't unroll,
+ so it's only good for large enough sizes. See remark below about InnerMaxSize. */
+ MaySliceVectorize = MightVectorize && int(InnerMaxSize)>=3*PacketSize
+ /* slice vectorization can be slow, so we only want it if the slices are big, which is
+ indicated by InnerMaxSize rather than InnerSize, think of the case of a dynamic block
+ in a fixed-size matrix */
};
public:
enum {
- Vectorization = int(MayInnerVectorize) ? int(InnerVectorization)
- : int(MayLinearVectorize) ? int(LinearVectorization)
- : int(MaySliceVectorize) ? int(SliceVectorization)
- : int(NoVectorization)
+ Traversal = int(MayInnerVectorize) ? int(InnerVectorizedTraversal)
+ : int(MayLinearVectorize) ? int(LinearVectorizedTraversal)
+ : int(MaySliceVectorize) ? int(SliceVectorizedTraversal)
+ : int(MayLinearize) ? int(LinearTraversal)
+ : int(DefaultTraversal),
+ Vectorized = int(Traversal) == InnerVectorizedTraversal
+ || int(Traversal) == LinearVectorizedTraversal
+ || int(Traversal) == SliceVectorizedTraversal
};
private:
enum {
- UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Vectorization) == int(NoVectorization) ? 1 : int(PacketSize)),
+ UnrollingLimit = EIGEN_UNROLLING_LIMIT * (Vectorized ? int(PacketSize) : 1),
MayUnrollCompletely = int(Derived::SizeAtCompileTime) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit),
- MayUnrollInner = int(InnerSize * OtherDerived::CoeffReadCost) <= int(UnrollingLimit)
+ MayUnrollInner = int(InnerSize) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit)
};
public:
enum {
- Unrolling = (int(Vectorization) == int(InnerVectorization) || int(Vectorization) == int(NoVectorization))
- ? (
- int(MayUnrollCompletely) ? int(CompleteUnrolling)
- : int(MayUnrollInner) ? int(InnerUnrolling)
- : int(NoUnrolling)
- )
- : int(Vectorization) == int(LinearVectorization)
- ? ( int(MayUnrollCompletely) && int(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) )
+ Unrolling = (int(Traversal) == int(InnerVectorizedTraversal) || int(Traversal) == int(DefaultTraversal))
+ ? (
+ int(MayUnrollCompletely) ? int(CompleteUnrolling)
+ : int(MayUnrollInner) ? int(InnerUnrolling)
+ : int(NoUnrolling)
+ )
+ : int(Traversal) == int(LinearVectorizedTraversal)
+ ? ( int(MayUnrollCompletely) && int(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) )
+ : int(Traversal) == int(LinearTraversal)
+ ? ( int(MayUnrollCompletely) ? int(CompleteUnrolling) : int(NoUnrolling) )
: int(NoUnrolling)
};
@@ -102,11 +111,12 @@ public:
EIGEN_DEBUG_VAR(InnerSize)
EIGEN_DEBUG_VAR(InnerMaxSize)
EIGEN_DEBUG_VAR(PacketSize)
+ EIGEN_DEBUG_VAR(StorageOrdersAgree)
EIGEN_DEBUG_VAR(MightVectorize)
EIGEN_DEBUG_VAR(MayInnerVectorize)
EIGEN_DEBUG_VAR(MayLinearVectorize)
EIGEN_DEBUG_VAR(MaySliceVectorize)
- EIGEN_DEBUG_VAR(Vectorization)
+ EIGEN_DEBUG_VAR(Traversal)
EIGEN_DEBUG_VAR(UnrollingLimit)
EIGEN_DEBUG_VAR(MayUnrollCompletely)
EIGEN_DEBUG_VAR(MayUnrollInner)
@@ -118,12 +128,12 @@ public:
* Part 2 : meta-unrollers
***************************************************************************/
-/***********************
-*** No vectorization ***
-***********************/
+/************************
+*** Default traversal ***
+************************/
template<typename Derived1, typename Derived2, int Index, int Stop>
-struct ei_assign_novec_CompleteUnrolling
+struct ei_assign_DefaultTraversal_CompleteUnrolling
{
enum {
row = int(Derived1::Flags)&RowMajorBit
@@ -137,18 +147,18 @@ struct ei_assign_novec_CompleteUnrolling
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
dst.copyCoeff(row, col, src);
- ei_assign_novec_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src);
+ ei_assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src);
}
};
template<typename Derived1, typename Derived2, int Stop>
-struct ei_assign_novec_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
+struct ei_assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
{
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {}
};
template<typename Derived1, typename Derived2, int Index, int Stop>
-struct ei_assign_novec_InnerUnrolling
+struct ei_assign_DefaultTraversal_InnerUnrolling
{
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int row_or_col)
{
@@ -156,16 +166,36 @@ struct ei_assign_novec_InnerUnrolling
const int row = rowMajor ? row_or_col : Index;
const int col = rowMajor ? Index : row_or_col;
dst.copyCoeff(row, col, src);
- ei_assign_novec_InnerUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src, row_or_col);
+ ei_assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src, row_or_col);
}
};
template<typename Derived1, typename Derived2, int Stop>
-struct ei_assign_novec_InnerUnrolling<Derived1, Derived2, Stop, Stop>
+struct ei_assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Stop, Stop>
{
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &, int) {}
};
+/***********************
+*** Linear traversal ***
+***********************/
+
+template<typename Derived1, typename Derived2, int Index, int Stop>
+struct ei_assign_LinearTraversal_CompleteUnrolling
+{
+ EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
+ {
+ dst.copyCoeff(Index, src);
+ ei_assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src);
+ }
+};
+
+template<typename Derived1, typename Derived2, int Stop>
+struct ei_assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
+{
+ EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {}
+};
+
/**************************
*** Inner vectorization ***
**************************/
@@ -221,16 +251,16 @@ struct ei_assign_innervec_InnerUnrolling<Derived1, Derived2, Stop, Stop>
***************************************************************************/
template<typename Derived1, typename Derived2,
- int Vectorization = ei_assign_traits<Derived1, Derived2>::Vectorization,
+ int Traversal = ei_assign_traits<Derived1, Derived2>::Traversal,
int Unrolling = ei_assign_traits<Derived1, Derived2>::Unrolling>
struct ei_assign_impl;
-/***********************
-*** No vectorization ***
-***********************/
+/************************
+*** Default traversal ***
+************************/
template<typename Derived1, typename Derived2>
-struct ei_assign_impl<Derived1, Derived2, NoVectorization, NoUnrolling>
+struct ei_assign_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling>
{
inline static void run(Derived1 &dst, const Derived2 &src)
{
@@ -248,17 +278,17 @@ struct ei_assign_impl<Derived1, Derived2, NoVectorization, NoUnrolling>
};
template<typename Derived1, typename Derived2>
-struct ei_assign_impl<Derived1, Derived2, NoVectorization, CompleteUnrolling>
+struct ei_assign_impl<Derived1, Derived2, DefaultTraversal, CompleteUnrolling>
{
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
- ei_assign_novec_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
+ ei_assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
::run(dst, src);
}
};
template<typename Derived1, typename Derived2>
-struct ei_assign_impl<Derived1, Derived2, NoVectorization, InnerUnrolling>
+struct ei_assign_impl<Derived1, Derived2, DefaultTraversal, InnerUnrolling>
{
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
@@ -266,17 +296,42 @@ struct ei_assign_impl<Derived1, Derived2, NoVectorization, InnerUnrolling>
const int innerSize = rowMajor ? Derived1::ColsAtCompileTime : Derived1::RowsAtCompileTime;
const int outerSize = dst.outerSize();
for(int j = 0; j < outerSize; ++j)
- ei_assign_novec_InnerUnrolling<Derived1, Derived2, 0, innerSize>
+ ei_assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, 0, innerSize>
::run(dst, src, j);
}
};
+/***********************
+*** Linear traversal ***
+***********************/
+
+template<typename Derived1, typename Derived2>
+struct ei_assign_impl<Derived1, Derived2, LinearTraversal, NoUnrolling>
+{
+ inline static void run(Derived1 &dst, const Derived2 &src)
+ {
+ const int size = dst.size();
+ for(int i = 0; i < size; ++i)
+ dst.copyCoeff(i, src);
+ }
+};
+
+template<typename Derived1, typename Derived2>
+struct ei_assign_impl<Derived1, Derived2, LinearTraversal, CompleteUnrolling>
+{
+ EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
+ {
+ ei_assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
+ ::run(dst, src);
+ }
+};
+
/**************************
*** Inner vectorization ***
**************************/
template<typename Derived1, typename Derived2>
-struct ei_assign_impl<Derived1, Derived2, InnerVectorization, NoUnrolling>
+struct ei_assign_impl<Derived1, Derived2, InnerVectorizedTraversal, NoUnrolling>
{
inline static void run(Derived1 &dst, const Derived2 &src)
{
@@ -295,7 +350,7 @@ struct ei_assign_impl<Derived1, Derived2, InnerVectorization, NoUnrolling>
};
template<typename Derived1, typename Derived2>
-struct ei_assign_impl<Derived1, Derived2, InnerVectorization, CompleteUnrolling>
+struct ei_assign_impl<Derived1, Derived2, InnerVectorizedTraversal, CompleteUnrolling>
{
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
@@ -305,7 +360,7 @@ struct ei_assign_impl<Derived1, Derived2, InnerVectorization, CompleteUnrolling>
};
template<typename Derived1, typename Derived2>
-struct ei_assign_impl<Derived1, Derived2, InnerVectorization, InnerUnrolling>
+struct ei_assign_impl<Derived1, Derived2, InnerVectorizedTraversal, InnerUnrolling>
{
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
@@ -323,7 +378,7 @@ struct ei_assign_impl<Derived1, Derived2, InnerVectorization, InnerUnrolling>
***************************/
template<typename Derived1, typename Derived2>
-struct ei_assign_impl<Derived1, Derived2, LinearVectorization, NoUnrolling>
+struct ei_assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling>
{
inline static void run(Derived1 &dst, const Derived2 &src)
{
@@ -347,7 +402,7 @@ struct ei_assign_impl<Derived1, Derived2, LinearVectorization, NoUnrolling>
};
template<typename Derived1, typename Derived2>
-struct ei_assign_impl<Derived1, Derived2, LinearVectorization, CompleteUnrolling>
+struct ei_assign_impl<Derived1, Derived2, LinearVectorizedTraversal, CompleteUnrolling>
{
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
@@ -356,7 +411,7 @@ struct ei_assign_impl<Derived1, Derived2, LinearVectorization, CompleteUnrolling
const int alignedSize = (size/packetSize)*packetSize;
ei_assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, alignedSize>::run(dst, src);
- ei_assign_novec_CompleteUnrolling<Derived1, Derived2, alignedSize, size>::run(dst, src);
+ ei_assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, alignedSize, size>::run(dst, src);
}
};
@@ -365,7 +420,7 @@ struct ei_assign_impl<Derived1, Derived2, LinearVectorization, CompleteUnrolling
***************************/
template<typename Derived1, typename Derived2>
-struct ei_assign_impl<Derived1, Derived2, SliceVectorization, NoUnrolling>
+struct ei_assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling>
{
inline static void run(Derived1 &dst, const Derived2 &src)
{
@@ -430,6 +485,9 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>
#ifdef EIGEN_DEBUG_ASSIGN
ei_assign_traits<Derived, OtherDerived>::debug();
#endif
+#ifndef EIGEN_NO_DEBUG
+ checkTransposeAliasing(other.derived());
+#endif
return derived();
}
diff --git a/Eigen/src/Core/BandMatrix.h b/Eigen/src/Core/BandMatrix.h
index 841d1786a..7943e6280 100644
--- a/Eigen/src/Core/BandMatrix.h
+++ b/Eigen/src/Core/BandMatrix.h
@@ -70,7 +70,7 @@ class BandMatrix : public AnyMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs
MaxColsAtCompileTime = ei_traits<BandMatrix>::MaxColsAtCompileTime
};
typedef typename ei_traits<BandMatrix>::Scalar Scalar;
- typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> PlainMatrixType;
+ typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> DenseMatrixType;
protected:
enum {
@@ -87,7 +87,7 @@ class BandMatrix : public AnyMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs
: m_data(1+supers+subs,cols),
m_rows(rows), m_supers(supers), m_subs(subs)
{
- m_data.setConstant(666);
+ //m_data.setConstant(666);
}
/** \returns the number of columns */
@@ -141,7 +141,7 @@ class BandMatrix : public AnyMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs
};
typedef Block<DataType,1, DiagonalSize> BuildType;
typedef typename ei_meta_if<Conjugate,
- CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>,NestByValue<BuildType> >,
+ CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>,BuildType >,
BuildType>::ret Type;
};
@@ -171,9 +171,9 @@ class BandMatrix : public AnyMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs
return Block<DataType,1,Dynamic>(m_data, supers()-i, std::max(0,i), 1, diagonalLength(i));
}
- PlainMatrixType toDense() const
+ DenseMatrixType toDenseMatrix() const
{
- PlainMatrixType res(rows(),cols());
+ DenseMatrixType res(rows(),cols());
res.setZero();
res.diagonal() = diagonal();
for (int i=1; i<=supers();++i)
diff --git a/Eigen/src/Core/Coeffs.h b/Eigen/src/Core/Coeffs.h
index c8bc9db85..b8af2531e 100644
--- a/Eigen/src/Core/Coeffs.h
+++ b/Eigen/src/Core/Coeffs.h
@@ -379,6 +379,38 @@ EIGEN_STRONG_INLINE void DenseBase<Derived>::copyPacket(int index, const DenseBa
other.derived().template packet<LoadMode>(index));
}
+
+template<typename Derived, typename Integer, bool JustReturnZero>
+struct ei_alignmentOffset_impl
+{
+ inline static Integer run(const DenseBase<Derived>&, Integer)
+ { return 0; }
+};
+
+template<typename Derived, typename Integer>
+struct ei_alignmentOffset_impl<Derived, Integer, false>
+{
+ inline static Integer run(const DenseBase<Derived>& m, Integer maxOffset)
+ {
+ return ei_alignmentOffset(&m.const_cast_derived().coeffRef(0,0), maxOffset);
+ }
+};
+
+/** \internal \returns the number of elements which have to be skipped, starting
+ * from the address of coeffRef(0,0), to find the first 16-byte aligned element.
+ *
+ * \note If the expression doesn't have the DirectAccessBit, this function returns 0.
+ *
+ * There is also the variant ei_alignmentOffset(const Scalar*, Integer) defined in Memory.h.
+ */
+template<typename Derived, typename Integer>
+inline static Integer ei_alignmentOffset(const DenseBase<Derived>& m, Integer maxOffset)
+{
+ return ei_alignmentOffset_impl<Derived, Integer,
+ (Derived::Flags & AlignedBit) || !(Derived::Flags & DirectAccessBit)>
+ ::run(m, maxOffset);
+}
+
#endif
#endif // EIGEN_COEFFS_H
diff --git a/Eigen/src/Core/CommaInitializer.h b/Eigen/src/Core/CommaInitializer.h
index 428e4d82d..a312b40f5 100644
--- a/Eigen/src/Core/CommaInitializer.h
+++ b/Eigen/src/Core/CommaInitializer.h
@@ -116,9 +116,6 @@ struct CommaInitializer
int m_row; // current row id
int m_col; // current col id
int m_currentBlockRows; // current block height
-
-private:
- CommaInitializer& operator=(const CommaInitializer&);
};
/** \anchor MatrixBaseCommaInitRef
diff --git a/Eigen/src/Core/CwiseBinaryOp.h b/Eigen/src/Core/CwiseBinaryOp.h
index 954ea9275..4d7ab6598 100644
--- a/Eigen/src/Core/CwiseBinaryOp.h
+++ b/Eigen/src/Core/CwiseBinaryOp.h
@@ -65,11 +65,16 @@ struct ei_traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > : ei_traits<Lhs>
RhsCoeffReadCost = _RhsNested::CoeffReadCost,
LhsFlags = _LhsNested::Flags,
RhsFlags = _RhsNested::Flags,
+ StorageOrdersAgree = (int(Lhs::Flags)&RowMajorBit)==(int(Rhs::Flags)&RowMajorBit),
Flags = (int(LhsFlags) | int(RhsFlags)) & (
HereditaryBits
- | (int(LhsFlags) & int(RhsFlags) & (LinearAccessBit | AlignedBit))
- | (ei_functor_traits<BinaryOp>::PacketAccess && ((int(LhsFlags) & RowMajorBit)==(int(RhsFlags) & RowMajorBit))
- ? (int(LhsFlags) & int(RhsFlags) & PacketAccessBit) : 0)),
+ | (int(LhsFlags) & int(RhsFlags) &
+ ( AlignedBit
+ | (StorageOrdersAgree ? LinearAccessBit : 0)
+ | (ei_functor_traits<BinaryOp>::PacketAccess && StorageOrdersAgree ? PacketAccessBit : 0)
+ )
+ )
+ ),
CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + ei_functor_traits<BinaryOp>::Cost
};
};
diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h
index ea6383998..a7e74b81d 100644
--- a/Eigen/src/Core/DenseBase.h
+++ b/Eigen/src/Core/DenseBase.h
@@ -274,21 +274,12 @@ template<typename Derived> class DenseBase
Eigen::Transpose<Derived> transpose();
const Eigen::Transpose<Derived> transpose() const;
void transposeInPlace();
- #ifndef EIGEN_NO_DEBUG
- template<typename OtherDerived>
- Derived& lazyAssign(const Transpose<OtherDerived>& other);
- template<typename DerivedA, typename DerivedB>
- Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,Transpose<DerivedA>,DerivedB>& other);
- template<typename DerivedA, typename DerivedB>
- Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,Transpose<DerivedB> >& other);
-
+#ifndef EIGEN_NO_DEBUG
+ protected:
template<typename OtherDerived>
- Derived& lazyAssign(const CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<OtherDerived> > >& other);
- template<typename DerivedA, typename DerivedB>
- Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedA> > >,DerivedB>& other);
- template<typename DerivedA, typename DerivedB>
- Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedB> > > >& other);
- #endif
+ void checkTransposeAliasing(const OtherDerived& other) const;
+ public:
+#endif
RowXpr row(int i);
const RowXpr row(int i) const;
@@ -382,18 +373,19 @@ template<typename Derived> class DenseBase
template<typename OtherDerived>
bool isApprox(const DenseBase<OtherDerived>& other,
- RealScalar prec = precision<Scalar>()) const;
+ RealScalar prec = dummy_precision<Scalar>()) const;
bool isMuchSmallerThan(const RealScalar& other,
- RealScalar prec = precision<Scalar>()) const;
+ RealScalar prec = dummy_precision<Scalar>()) const;
template<typename OtherDerived>
bool isMuchSmallerThan(const DenseBase<OtherDerived>& other,
- RealScalar prec = precision<Scalar>()) const;
+ RealScalar prec = dummy_precision<Scalar>()) const;
- bool isApproxToConstant(const Scalar& value, RealScalar prec = precision<Scalar>()) const;
- bool isConstant(const Scalar& value, RealScalar prec = precision<Scalar>()) const;
- bool isZero(RealScalar prec = precision<Scalar>()) const;
- bool isOnes(RealScalar prec = precision<Scalar>()) const;
+ bool isApproxToConstant(const Scalar& value, RealScalar prec = dummy_precision<Scalar>()) const;
+ bool isConstant(const Scalar& value, RealScalar prec = dummy_precision<Scalar>()) const;
+ bool isZero(RealScalar prec = dummy_precision<Scalar>()) const;
+ bool isOnes(RealScalar prec = dummy_precision<Scalar>()) const;
+ // FIXME
EIGEN_STRONG_INLINE Derived& operator*=(const Scalar& other)
{
SelfCwiseBinaryOp<ei_scalar_product_op<Scalar>, Derived> tmp(derived());
@@ -409,6 +401,7 @@ template<typename Derived> class DenseBase
return derived();
}
+ // FIXME
// template<typename OtherDerived>
// inline bool operator==(const DenseBase<OtherDerived>& other) const
// { return cwiseEqual(other).all(); }
@@ -487,11 +480,11 @@ template<typename Derived> class DenseBase
const DenseBase<ElseDerived>& elseMatrix) const;
template<typename ThenDerived>
- inline const Select<Derived,ThenDerived, NestByValue<typename ThenDerived::ConstantReturnType> >
+ inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
select(const DenseBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const;
template<typename ElseDerived>
- inline const Select<Derived, NestByValue<typename ElseDerived::ConstantReturnType>, ElseDerived >
+ inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
select(typename ElseDerived::Scalar thenScalar, const DenseBase<ElseDerived>& elseMatrix) const;
template<int p> RealScalar lpNorm() const;
diff --git a/Eigen/src/Core/DenseStorageBase.h b/Eigen/src/Core/DenseStorageBase.h
index ed116d708..7dc8d38c4 100644
--- a/Eigen/src/Core/DenseStorageBase.h
+++ b/Eigen/src/Core/DenseStorageBase.h
@@ -175,8 +175,14 @@ class DenseStorageBase : public _Base<Derived>
&& (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
&& (MaxColsAtCompileTime == Dynamic || MaxColsAtCompileTime >= cols)
&& (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
- m_storage.resize(rows * cols, rows, cols);
- EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
+ #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
+ int size = rows*cols;
+ bool size_changed = size != this->size();
+ m_storage.resize(size, rows, cols);
+ if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
+ #else
+ m_storage.resize(rows*cols, rows, cols);
+ #endif
}
/** Resizes \c *this to a vector of length \a size
@@ -194,11 +200,16 @@ class DenseStorageBase : public _Base<Derived>
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(DenseStorageBase)
ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
+ #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
+ bool size_changed = size != this->size();
+ #endif
if(RowsAtCompileTime == 1)
m_storage.resize(size, 1, size);
else
m_storage.resize(size, size, 1);
- EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
+ #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
+ if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
+ #endif
}
/** Resizes the matrix, changing only the number of columns. For the parameter of type NoChange_t, just pass the special value \c NoChange
diff --git a/Eigen/src/Core/DiagonalMatrix.h b/Eigen/src/Core/DiagonalMatrix.h
index 6f93737ff..bd23b2e09 100644
--- a/Eigen/src/Core/DiagonalMatrix.h
+++ b/Eigen/src/Core/DiagonalMatrix.h
@@ -26,6 +26,7 @@
#ifndef EIGEN_DIAGONALMATRIX_H
#define EIGEN_DIAGONALMATRIX_H
+#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename Derived>
class DiagonalBase : public AnyMatrixBase<Derived>
{
@@ -44,19 +45,17 @@ class DiagonalBase : public AnyMatrixBase<Derived>
typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, 0, MaxRowsAtCompileTime, MaxColsAtCompileTime> DenseMatrixType;
- #ifndef EIGEN_PARSED_BY_DOXYGEN
inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
inline Derived& derived() { return *static_cast<Derived*>(this); }
- #endif // not EIGEN_PARSED_BY_DOXYGEN
DenseMatrixType toDenseMatrix() const { return derived(); }
template<typename DenseDerived>
void evalTo(MatrixBase<DenseDerived> &other) const;
template<typename DenseDerived>
- void addToDense(MatrixBase<DenseDerived> &other) const
+ void addTo(MatrixBase<DenseDerived> &other) const
{ other.diagonal() += diagonal(); }
template<typename DenseDerived>
- void subToDense(MatrixBase<DenseDerived> &other) const
+ void subTo(MatrixBase<DenseDerived> &other) const
{ other.diagonal() -= diagonal(); }
inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); }
@@ -83,16 +82,18 @@ void DiagonalBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
other.setZero();
other.diagonal() = diagonal();
}
+#endif
/** \class DiagonalMatrix
- * \nonstableyet
*
* \brief Represents a diagonal matrix with its storage
*
* \param _Scalar the type of coefficients
- * \param _Size the dimension of the matrix, or Dynamic
+ * \param SizeAtCompileTime the dimension of the matrix, or Dynamic
+ * \param MaxSizeAtCompileTime the dimension of the matrix, or Dynamic. This parameter is optional and defaults
+ * to SizeAtCompileTime. Most of the time, you do not need to specify it.
*
- * \sa class Matrix
+ * \sa class DiagonalWrapper
*/
template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime>
struct ei_traits<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> >
@@ -106,10 +107,11 @@ class DiagonalMatrix
: public DiagonalBase<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> >
{
public:
-
+ #ifndef EIGEN_PARSED_BY_DOXYGEN
typedef typename ei_traits<DiagonalMatrix>::DiagonalVectorType DiagonalVectorType;
typedef const DiagonalMatrix& Nested;
typedef _Scalar Scalar;
+ #endif
protected:
@@ -117,7 +119,9 @@ class DiagonalMatrix
public:
+ /** const version of diagonal(). */
inline const DiagonalVectorType& diagonal() const { return m_diagonal; }
+ /** \returns a reference to the stored vector of diagonal coefficients. */
inline DiagonalVectorType& diagonal() { return m_diagonal; }
/** Default constructor without initialization */
@@ -126,23 +130,27 @@ class DiagonalMatrix
/** Constructs a diagonal matrix with given dimension */
inline DiagonalMatrix(int dim) : m_diagonal(dim) {}
- /** 2D only */
+ /** 2D constructor. */
inline DiagonalMatrix(const Scalar& x, const Scalar& y) : m_diagonal(x,y) {}
- /** 3D only */
+ /** 3D constructor. */
inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {}
+ /** Copy constructor. */
template<typename OtherDerived>
inline DiagonalMatrix(const DiagonalBase<OtherDerived>& other) : m_diagonal(other.diagonal()) {}
+ #ifndef EIGEN_PARSED_BY_DOXYGEN
/** copy constructor. prevent a default copy constructor from hiding the other templated constructor */
inline DiagonalMatrix(const DiagonalMatrix& other) : m_diagonal(other.diagonal()) {}
+ #endif
/** generic constructor from expression of the diagonal coefficients */
template<typename OtherDerived>
explicit inline DiagonalMatrix(const MatrixBase<OtherDerived>& other) : m_diagonal(other)
{}
+ /** Copy operator. */
template<typename OtherDerived>
DiagonalMatrix& operator=(const DiagonalBase<OtherDerived>& other)
{
@@ -150,6 +158,7 @@ class DiagonalMatrix
return *this;
}
+ #ifndef EIGEN_PARSED_BY_DOXYGEN
/** This is a special case of the templated operator=. Its purpose is to
* prevent a default operator= from hiding the templated operator=.
*/
@@ -158,23 +167,28 @@ class DiagonalMatrix
m_diagonal = other.m_diagonal();
return *this;
}
+ #endif
+ /** Resizes to given size. */
inline void resize(int size) { m_diagonal.resize(size); }
+ /** Sets all coefficients to zero. */
inline void setZero() { m_diagonal.setZero(); }
+ /** Resizes and sets all coefficients to zero. */
inline void setZero(int size) { m_diagonal.setZero(size); }
+ /** Sets this matrix to be the identity matrix of the current size. */
inline void setIdentity() { m_diagonal.setOnes(); }
+ /** Sets this matrix to be the identity matrix of the given size. */
inline void setIdentity(int size) { m_diagonal.setOnes(size); }
};
/** \class DiagonalWrapper
- * \nonstableyet
*
* \brief Expression of a diagonal matrix
*
* \param _DiagonalVectorType the type of the vector of diagonal coefficients
*
- * This class is an expression of a diagonal matrix with given vector of diagonal
- * coefficients. It is the return type of MatrixBase::asDiagonal()
+ * This class is an expression of a diagonal matrix, but not storing its own vector of diagonal coefficients,
+ * instead wrapping an existing vector expression. It is the return type of MatrixBase::asDiagonal()
* and most of the time this is the only way that it is used.
*
* \sa class DiagonalMatrix, class DiagonalBase, MatrixBase::asDiagonal()
@@ -198,18 +212,22 @@ class DiagonalWrapper
: public DiagonalBase<DiagonalWrapper<_DiagonalVectorType> >, ei_no_assignment_operator
{
public:
+ #ifndef EIGEN_PARSED_BY_DOXYGEN
typedef _DiagonalVectorType DiagonalVectorType;
typedef DiagonalWrapper Nested;
+ #endif
+ /** Constructor from expression of diagonal coefficients to wrap. */
inline DiagonalWrapper(const DiagonalVectorType& diagonal) : m_diagonal(diagonal) {}
+
+ /** \returns a const reference to the wrapped expression of diagonal coefficients. */
const DiagonalVectorType& diagonal() const { return m_diagonal; }
protected:
const typename DiagonalVectorType::Nested m_diagonal;
};
-/** \nonstableyet
- * \returns a pseudo-expression of a diagonal matrix with *this as vector of diagonal coefficients
+/** \returns a pseudo-expression of a diagonal matrix with *this as vector of diagonal coefficients
*
* \only_for_vectors
*
@@ -225,8 +243,7 @@ MatrixBase<Derived>::asDiagonal() const
return derived();
}
-/** \nonstableyet
- * \returns true if *this is approximately equal to a diagonal matrix,
+/** \returns true if *this is approximately equal to a diagonal matrix,
* within the precision given by \a prec.
*
* Example: \include MatrixBase_isDiagonal.cpp
diff --git a/Eigen/src/Core/Dot.h b/Eigen/src/Core/Dot.h
index 4a164a99e..f0c520b1f 100644
--- a/Eigen/src/Core/Dot.h
+++ b/Eigen/src/Core/Dot.h
@@ -34,10 +34,10 @@ struct ei_dot_traits
{
public:
enum {
- Vectorization = (int(Derived1::Flags)&int(Derived2::Flags)&ActualPacketAccessBit)
+ Traversal = (int(Derived1::Flags)&int(Derived2::Flags)&ActualPacketAccessBit)
&& (int(Derived1::Flags)&int(Derived2::Flags)&LinearAccessBit)
- ? LinearVectorization
- : NoVectorization
+ ? LinearVectorizedTraversal
+ : DefaultTraversal
};
private:
@@ -46,7 +46,7 @@ private:
PacketSize = ei_packet_traits<Scalar>::size,
Cost = Derived1::SizeAtCompileTime * (Derived1::CoeffReadCost + Derived2::CoeffReadCost + NumTraits<Scalar>::MulCost)
+ (Derived1::SizeAtCompileTime-1) * NumTraits<Scalar>::AddCost,
- UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Vectorization) == int(NoVectorization) ? 1 : int(PacketSize))
+ UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Traversal) == int(DefaultTraversal) ? 1 : int(PacketSize))
};
public:
@@ -142,13 +142,13 @@ struct ei_dot_vec_unroller<Derived1, Derived2, Index, Stop, true>
***************************************************************************/
template<typename Derived1, typename Derived2,
- int Vectorization = ei_dot_traits<Derived1, Derived2>::Vectorization,
+ int Traversal = ei_dot_traits<Derived1, Derived2>::Traversal,
int Unrolling = ei_dot_traits<Derived1, Derived2>::Unrolling
>
struct ei_dot_impl;
template<typename Derived1, typename Derived2>
-struct ei_dot_impl<Derived1, Derived2, NoVectorization, NoUnrolling>
+struct ei_dot_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling>
{
typedef typename Derived1::Scalar Scalar;
static Scalar run(const Derived1& v1, const Derived2& v2)
@@ -163,12 +163,12 @@ struct ei_dot_impl<Derived1, Derived2, NoVectorization, NoUnrolling>
};
template<typename Derived1, typename Derived2>
-struct ei_dot_impl<Derived1, Derived2, NoVectorization, CompleteUnrolling>
+struct ei_dot_impl<Derived1, Derived2, DefaultTraversal, CompleteUnrolling>
: public ei_dot_novec_unroller<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
{};
template<typename Derived1, typename Derived2>
-struct ei_dot_impl<Derived1, Derived2, LinearVectorization, NoUnrolling>
+struct ei_dot_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling>
{
typedef typename Derived1::Scalar Scalar;
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
@@ -221,20 +221,20 @@ struct ei_dot_impl<Derived1, Derived2, LinearVectorization, NoUnrolling>
};
template<typename Derived1, typename Derived2>
-struct ei_dot_impl<Derived1, Derived2, LinearVectorization, CompleteUnrolling>
+struct ei_dot_impl<Derived1, Derived2, LinearVectorizedTraversal, CompleteUnrolling>
{
typedef typename Derived1::Scalar Scalar;
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
enum {
PacketSize = ei_packet_traits<Scalar>::size,
Size = Derived1::SizeAtCompileTime,
- VectorizationSize = (Size / PacketSize) * PacketSize
+ VectorizedSize = (Size / PacketSize) * PacketSize
};
static Scalar run(const Derived1& v1, const Derived2& v2)
{
- Scalar res = ei_predux(ei_dot_vec_unroller<Derived1, Derived2, 0, VectorizationSize>::run(v1, v2));
- if (VectorizationSize != Size)
- res += ei_dot_novec_unroller<Derived1, Derived2, VectorizationSize, Size-VectorizationSize>::run(v1, v2);
+ Scalar res = ei_predux(ei_dot_vec_unroller<Derived1, Derived2, 0, VectorizedSize>::run(v1, v2));
+ if (VectorizedSize != Size)
+ res += ei_dot_novec_unroller<Derived1, Derived2, VectorizedSize, Size-VectorizedSize>::run(v1, v2);
return res;
}
};
diff --git a/Eigen/src/Core/ExpressionMaker.h b/Eigen/src/Core/ExpressionMaker.h
index 1d265b63c..7e2b81d4a 100644
--- a/Eigen/src/Core/ExpressionMaker.h
+++ b/Eigen/src/Core/ExpressionMaker.h
@@ -37,12 +37,6 @@ template<typename XprType> struct ei_shape_of
// matrix. Unless we change the overall design, here is a workaround.
// There is an example in unsuported/Eigen/src/AutoDiff/AutoDiffScalar.
-template<typename XprType, int Shape = ei_shape_of<XprType>::ret>
-struct MakeNestByValue
-{
- typedef NestByValue<XprType> Type;
-};
-
template<typename Func, typename XprType, int Shape = ei_shape_of<XprType>::ret>
struct MakeCwiseUnaryOp
{
diff --git a/Eigen/src/Core/Functors.h b/Eigen/src/Core/Functors.h
index 259f40244..aa3eba5cc 100644
--- a/Eigen/src/Core/Functors.h
+++ b/Eigen/src/Core/Functors.h
@@ -32,7 +32,8 @@
*
* \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, MatrixBase::sum()
*/
-template<typename Scalar> struct ei_scalar_sum_op EIGEN_EMPTY_STRUCT {
+template<typename Scalar> struct ei_scalar_sum_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_sum_op)
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; }
template<typename PacketScalar>
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
@@ -54,7 +55,8 @@ struct ei_functor_traits<ei_scalar_sum_op<Scalar> > {
*
* \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux()
*/
-template<typename Scalar> struct ei_scalar_product_op EIGEN_EMPTY_STRUCT {
+template<typename Scalar> struct ei_scalar_product_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_product_op)
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a * b; }
template<typename PacketScalar>
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
@@ -76,7 +78,8 @@ struct ei_functor_traits<ei_scalar_product_op<Scalar> > {
*
* \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff()
*/
-template<typename Scalar> struct ei_scalar_min_op EIGEN_EMPTY_STRUCT {
+template<typename Scalar> struct ei_scalar_min_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_min_op)
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::min(a, b); }
template<typename PacketScalar>
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
@@ -98,7 +101,8 @@ struct ei_functor_traits<ei_scalar_min_op<Scalar> > {
*
* \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff()
*/
-template<typename Scalar> struct ei_scalar_max_op EIGEN_EMPTY_STRUCT {
+template<typename Scalar> struct ei_scalar_max_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_max_op)
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::max(a, b); }
template<typename PacketScalar>
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
@@ -120,7 +124,8 @@ struct ei_functor_traits<ei_scalar_max_op<Scalar> > {
*
* \sa MatrixBase::stableNorm(), class Redux
*/
-template<typename Scalar> struct ei_scalar_hypot_op EIGEN_EMPTY_STRUCT {
+template<typename Scalar> struct ei_scalar_hypot_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_hypot_op)
// typedef typename NumTraits<Scalar>::Real result_type;
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const
{
@@ -142,7 +147,8 @@ struct ei_functor_traits<ei_scalar_hypot_op<Scalar> > {
*
* \sa class CwiseBinaryOp, MatrixBase::operator-
*/
-template<typename Scalar> struct ei_scalar_difference_op EIGEN_EMPTY_STRUCT {
+template<typename Scalar> struct ei_scalar_difference_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_difference_op)
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; }
template<typename PacketScalar>
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
@@ -161,7 +167,8 @@ struct ei_functor_traits<ei_scalar_difference_op<Scalar> > {
*
* \sa class CwiseBinaryOp, Cwise::operator/()
*/
-template<typename Scalar> struct ei_scalar_quotient_op EIGEN_EMPTY_STRUCT {
+template<typename Scalar> struct ei_scalar_quotient_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_quotient_op)
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; }
template<typename PacketScalar>
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
@@ -185,7 +192,8 @@ struct ei_functor_traits<ei_scalar_quotient_op<Scalar> > {
*
* \sa class CwiseUnaryOp, MatrixBase::operator-
*/
-template<typename Scalar> struct ei_scalar_opposite_op EIGEN_EMPTY_STRUCT {
+template<typename Scalar> struct ei_scalar_opposite_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_opposite_op)
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; }
template<typename PacketScalar>
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
@@ -203,7 +211,8 @@ struct ei_functor_traits<ei_scalar_opposite_op<Scalar> >
*
* \sa class CwiseUnaryOp, Cwise::abs
*/
-template<typename Scalar> struct ei_scalar_abs_op EIGEN_EMPTY_STRUCT {
+template<typename Scalar> struct ei_scalar_abs_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_abs_op)
typedef typename NumTraits<Scalar>::Real result_type;
EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return ei_abs(a); }
template<typename PacketScalar>
@@ -224,7 +233,8 @@ struct ei_functor_traits<ei_scalar_abs_op<Scalar> >
*
* \sa class CwiseUnaryOp, Cwise::abs2
*/
-template<typename Scalar> struct ei_scalar_abs2_op EIGEN_EMPTY_STRUCT {
+template<typename Scalar> struct ei_scalar_abs2_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_abs2_op)
typedef typename NumTraits<Scalar>::Real result_type;
EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return ei_abs2(a); }
template<typename PacketScalar>
@@ -240,7 +250,8 @@ struct ei_functor_traits<ei_scalar_abs2_op<Scalar> >
*
* \sa class CwiseUnaryOp, MatrixBase::conjugate()
*/
-template<typename Scalar> struct ei_scalar_conjugate_op EIGEN_EMPTY_STRUCT {
+template<typename Scalar> struct ei_scalar_conjugate_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_conjugate_op)
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return ei_conj(a); }
template<typename PacketScalar>
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const { return a; }
@@ -260,7 +271,8 @@ struct ei_functor_traits<ei_scalar_conjugate_op<Scalar> >
* \sa class CwiseUnaryOp, MatrixBase::cast()
*/
template<typename Scalar, typename NewType>
-struct ei_scalar_cast_op EIGEN_EMPTY_STRUCT {
+struct ei_scalar_cast_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_cast_op)
typedef NewType result_type;
EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return static_cast<NewType>(a); }
};
@@ -274,7 +286,8 @@ struct ei_functor_traits<ei_scalar_cast_op<Scalar,NewType> >
* \sa class CwiseUnaryOp, MatrixBase::real()
*/
template<typename Scalar>
-struct ei_scalar_real_op EIGEN_EMPTY_STRUCT {
+struct ei_scalar_real_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_real_op)
typedef typename NumTraits<Scalar>::Real result_type;
EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return ei_real(a); }
EIGEN_STRONG_INLINE result_type& operator() (Scalar& a) const { return ei_real_ref(a); }
@@ -289,7 +302,8 @@ struct ei_functor_traits<ei_scalar_real_op<Scalar> >
* \sa class CwiseUnaryOp, MatrixBase::imag()
*/
template<typename Scalar>
-struct ei_scalar_imag_op EIGEN_EMPTY_STRUCT {
+struct ei_scalar_imag_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_imag_op)
typedef typename NumTraits<Scalar>::Real result_type;
EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return ei_imag(a); }
EIGEN_STRONG_INLINE result_type& operator() (Scalar& a) const { return ei_imag_ref(a); }
@@ -304,7 +318,8 @@ struct ei_functor_traits<ei_scalar_imag_op<Scalar> >
*
* \sa class CwiseUnaryOp, Cwise::exp()
*/
-template<typename Scalar> struct ei_scalar_exp_op EIGEN_EMPTY_STRUCT {
+template<typename Scalar> struct ei_scalar_exp_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_exp_op)
inline const Scalar operator() (const Scalar& a) const { return ei_exp(a); }
typedef typename ei_packet_traits<Scalar>::type Packet;
inline Packet packetOp(const Packet& a) const { return ei_pexp(a); }
@@ -319,7 +334,8 @@ struct ei_functor_traits<ei_scalar_exp_op<Scalar> >
*
* \sa class CwiseUnaryOp, Cwise::log()
*/
-template<typename Scalar> struct ei_scalar_log_op EIGEN_EMPTY_STRUCT {
+template<typename Scalar> struct ei_scalar_log_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_log_op)
inline const Scalar operator() (const Scalar& a) const { return ei_log(a); }
typedef typename ei_packet_traits<Scalar>::type Packet;
inline Packet packetOp(const Packet& a) const { return ei_plog(a); }
@@ -351,8 +367,6 @@ struct ei_scalar_multiple_op {
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
{ return ei_pmul(a, ei_pset1(m_other)); }
typename ei_makeconst<typename NumTraits<Scalar>::Nested>::type m_other;
-private:
- ei_scalar_multiple_op& operator=(const ei_scalar_multiple_op&);
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_multiple_op<Scalar> >
@@ -380,8 +394,6 @@ struct ei_scalar_quotient1_impl {
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
{ return ei_pmul(a, ei_pset1(m_other)); }
const Scalar m_other;
-private:
- ei_scalar_quotient1_impl& operator=(const ei_scalar_quotient1_impl&);
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_quotient1_impl<Scalar,true> >
@@ -427,15 +439,13 @@ struct ei_scalar_constant_op {
EIGEN_STRONG_INLINE const Scalar operator() (int, int = 0) const { return m_other; }
EIGEN_STRONG_INLINE const PacketScalar packetOp() const { return ei_pset1(m_other); }
const Scalar m_other;
-private:
- ei_scalar_constant_op& operator=(const ei_scalar_constant_op&);
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_constant_op<Scalar> >
{ enum { Cost = 1, PacketAccess = ei_packet_traits<Scalar>::size>1, IsRepeatable = true }; };
-template<typename Scalar> struct ei_scalar_identity_op EIGEN_EMPTY_STRUCT {
- EIGEN_STRONG_INLINE ei_scalar_identity_op(void) {}
+template<typename Scalar> struct ei_scalar_identity_op {
+ EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_identity_op)
EIGEN_STRONG_INLINE const Scalar operator() (int row, int col) const { return row==col ? Scalar(1) : Scalar(0); }
};
template<typename Scalar>
diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h
index 05469b340..7ffddcbf8 100644
--- a/Eigen/src/Core/MathFunctions.h
+++ b/Eigen/src/Core/MathFunctions.h
@@ -30,7 +30,7 @@ template<typename T> inline typename NumTraits<T>::Real epsilon()
return std::numeric_limits<typename NumTraits<T>::Real>::epsilon();
}
-template<typename T> inline typename NumTraits<T>::Real precision();
+template<typename T> inline typename NumTraits<T>::Real dummy_precision();
template<typename T> inline T ei_random(T a, T b);
template<typename T> inline T ei_random();
@@ -55,7 +55,7 @@ template<typename T> inline typename NumTraits<T>::Real ei_hypot(T x, T y)
*** int ***
**************/
-template<> inline int precision<int>() { return 0; }
+template<> inline int dummy_precision<int>() { return 0; }
inline int ei_real(int x) { return x; }
inline int& ei_real_ref(int& x) { return x; }
inline int ei_imag(int) { return 0; }
@@ -92,15 +92,15 @@ template<> inline int ei_random()
{
return ei_random<int>(-ei_random_amplitude<int>(), ei_random_amplitude<int>());
}
-inline bool ei_isMuchSmallerThan(int a, int, int = precision<int>())
+inline bool ei_isMuchSmallerThan(int a, int, int = dummy_precision<int>())
{
return a == 0;
}
-inline bool ei_isApprox(int a, int b, int = precision<int>())
+inline bool ei_isApprox(int a, int b, int = dummy_precision<int>())
{
return a == b;
}
-inline bool ei_isApproxOrLessThan(int a, int b, int = precision<int>())
+inline bool ei_isApproxOrLessThan(int a, int b, int = dummy_precision<int>())
{
return a <= b;
}
@@ -109,7 +109,7 @@ inline bool ei_isApproxOrLessThan(int a, int b, int = precision<int>())
*** float ***
**************/
-template<> inline float precision<float>() { return 1e-5f; }
+template<> inline float dummy_precision<float>() { return 1e-5f; }
inline float ei_real(float x) { return x; }
inline float& ei_real_ref(float& x) { return x; }
inline float ei_imag(float) { return 0.f; }
@@ -140,15 +140,15 @@ template<> inline float ei_random()
{
return ei_random<float>(-ei_random_amplitude<float>(), ei_random_amplitude<float>());
}
-inline bool ei_isMuchSmallerThan(float a, float b, float prec = precision<float>())
+inline bool ei_isMuchSmallerThan(float a, float b, float prec = dummy_precision<float>())
{
return ei_abs(a) <= ei_abs(b) * prec;
}
-inline bool ei_isApprox(float a, float b, float prec = precision<float>())
+inline bool ei_isApprox(float a, float b, float prec = dummy_precision<float>())
{
return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec;
}
-inline bool ei_isApproxOrLessThan(float a, float b, float prec = precision<float>())
+inline bool ei_isApproxOrLessThan(float a, float b, float prec = dummy_precision<float>())
{
return a <= b || ei_isApprox(a, b, prec);
}
@@ -157,7 +157,7 @@ inline bool ei_isApproxOrLessThan(float a, float b, float prec = precision<float
*** double ***
**************/
-template<> inline double precision<double>() { return 1e-12; }
+template<> inline double dummy_precision<double>() { return 1e-12; }
inline double ei_real(double x) { return x; }
inline double& ei_real_ref(double& x) { return x; }
@@ -189,15 +189,15 @@ template<> inline double ei_random()
{
return ei_random<double>(-ei_random_amplitude<double>(), ei_random_amplitude<double>());
}
-inline bool ei_isMuchSmallerThan(double a, double b, double prec = precision<double>())
+inline bool ei_isMuchSmallerThan(double a, double b, double prec = dummy_precision<double>())
{
return ei_abs(a) <= ei_abs(b) * prec;
}
-inline bool ei_isApprox(double a, double b, double prec = precision<double>())
+inline bool ei_isApprox(double a, double b, double prec = dummy_precision<double>())
{
return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec;
}
-inline bool ei_isApproxOrLessThan(double a, double b, double prec = precision<double>())
+inline bool ei_isApproxOrLessThan(double a, double b, double prec = dummy_precision<double>())
{
return a <= b || ei_isApprox(a, b, prec);
}
@@ -206,7 +206,7 @@ inline bool ei_isApproxOrLessThan(double a, double b, double prec = precision<do
*** complex<float> ***
*********************/
-template<> inline float precision<std::complex<float> >() { return precision<float>(); }
+template<> inline float dummy_precision<std::complex<float> >() { return dummy_precision<float>(); }
inline float ei_real(const std::complex<float>& x) { return std::real(x); }
inline float ei_imag(const std::complex<float>& x) { return std::imag(x); }
inline float& ei_real_ref(std::complex<float>& x) { return reinterpret_cast<float*>(&x)[0]; }
@@ -224,15 +224,15 @@ template<> inline std::complex<float> ei_random()
{
return std::complex<float>(ei_random<float>(), ei_random<float>());
}
-inline bool ei_isMuchSmallerThan(const std::complex<float>& a, const std::complex<float>& b, float prec = precision<float>())
+inline bool ei_isMuchSmallerThan(const std::complex<float>& a, const std::complex<float>& b, float prec = dummy_precision<float>())
{
return ei_abs2(a) <= ei_abs2(b) * prec * prec;
}
-inline bool ei_isMuchSmallerThan(const std::complex<float>& a, float b, float prec = precision<float>())
+inline bool ei_isMuchSmallerThan(const std::complex<float>& a, float b, float prec = dummy_precision<float>())
{
return ei_abs2(a) <= ei_abs2(b) * prec * prec;
}
-inline bool ei_isApprox(const std::complex<float>& a, const std::complex<float>& b, float prec = precision<float>())
+inline bool ei_isApprox(const std::complex<float>& a, const std::complex<float>& b, float prec = dummy_precision<float>())
{
return ei_isApprox(ei_real(a), ei_real(b), prec)
&& ei_isApprox(ei_imag(a), ei_imag(b), prec);
@@ -243,7 +243,7 @@ inline bool ei_isApprox(const std::complex<float>& a, const std::complex<float>&
*** complex<double> ***
**********************/
-template<> inline double precision<std::complex<double> >() { return precision<double>(); }
+template<> inline double dummy_precision<std::complex<double> >() { return dummy_precision<double>(); }
inline double ei_real(const std::complex<double>& x) { return std::real(x); }
inline double ei_imag(const std::complex<double>& x) { return std::imag(x); }
inline double& ei_real_ref(std::complex<double>& x) { return reinterpret_cast<double*>(&x)[0]; }
@@ -261,15 +261,15 @@ template<> inline std::complex<double> ei_random()
{
return std::complex<double>(ei_random<double>(), ei_random<double>());
}
-inline bool ei_isMuchSmallerThan(const std::complex<double>& a, const std::complex<double>& b, double prec = precision<double>())
+inline bool ei_isMuchSmallerThan(const std::complex<double>& a, const std::complex<double>& b, double prec = dummy_precision<double>())
{
return ei_abs2(a) <= ei_abs2(b) * prec * prec;
}
-inline bool ei_isMuchSmallerThan(const std::complex<double>& a, double b, double prec = precision<double>())
+inline bool ei_isMuchSmallerThan(const std::complex<double>& a, double b, double prec = dummy_precision<double>())
{
return ei_abs2(a) <= ei_abs2(b) * prec * prec;
}
-inline bool ei_isApprox(const std::complex<double>& a, const std::complex<double>& b, double prec = precision<double>())
+inline bool ei_isApprox(const std::complex<double>& a, const std::complex<double>& b, double prec = dummy_precision<double>())
{
return ei_isApprox(ei_real(a), ei_real(b), prec)
&& ei_isApprox(ei_imag(a), ei_imag(b), prec);
@@ -281,7 +281,7 @@ inline bool ei_isApprox(const std::complex<double>& a, const std::complex<double
*** long double ***
******************/
-template<> inline long double precision<long double>() { return precision<double>(); }
+template<> inline long double dummy_precision<long double>() { return dummy_precision<double>(); }
inline long double ei_real(long double x) { return x; }
inline long double& ei_real_ref(long double& x) { return x; }
inline long double ei_imag(long double) { return 0.; }
@@ -304,15 +304,15 @@ template<> inline long double ei_random()
{
return ei_random<double>(-ei_random_amplitude<double>(), ei_random_amplitude<double>());
}
-inline bool ei_isMuchSmallerThan(long double a, long double b, long double prec = precision<long double>())
+inline bool ei_isMuchSmallerThan(long double a, long double b, long double prec = dummy_precision<long double>())
{
return ei_abs(a) <= ei_abs(b) * prec;
}
-inline bool ei_isApprox(long double a, long double b, long double prec = precision<long double>())
+inline bool ei_isApprox(long double a, long double b, long double prec = dummy_precision<long double>())
{
return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec;
}
-inline bool ei_isApproxOrLessThan(long double a, long double b, long double prec = precision<long double>())
+inline bool ei_isApproxOrLessThan(long double a, long double b, long double prec = dummy_precision<long double>())
{
return a <= b || ei_isApprox(a, b, prec);
}
@@ -321,7 +321,7 @@ inline bool ei_isApproxOrLessThan(long double a, long double b, long double prec
*** bool ***
**************/
-template<> inline bool precision<bool>() { return 0; }
+template<> inline bool dummy_precision<bool>() { return 0; }
inline bool ei_real(bool x) { return x; }
inline bool& ei_real_ref(bool& x) { return x; }
inline bool ei_imag(bool) { return 0; }
@@ -334,15 +334,15 @@ template<> inline bool ei_random()
{
return (ei_random<int>(0,1) == 1);
}
-inline bool ei_isMuchSmallerThan(bool a, bool, bool = precision<bool>())
+inline bool ei_isMuchSmallerThan(bool a, bool, bool = dummy_precision<bool>())
{
return !a;
}
-inline bool ei_isApprox(bool a, bool b, bool = precision<bool>())
+inline bool ei_isApprox(bool a, bool b, bool = dummy_precision<bool>())
{
return a == b;
}
-inline bool ei_isApproxOrLessThan(bool a, bool b, bool = precision<bool>())
+inline bool ei_isApproxOrLessThan(bool a, bool b, bool = dummy_precision<bool>())
{
return int(a) <= int(b);
}
diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h
index 75c0a73b5..24c618549 100644
--- a/Eigen/src/Core/Matrix.h
+++ b/Eigen/src/Core/Matrix.h
@@ -152,7 +152,6 @@ class Matrix
using Base::coeff;
using Base::coeffRef;
-
/** Copies the value of the expression \a other into \c *this with automatic resizing.
*
* *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
@@ -286,9 +285,6 @@ class Matrix
other.evalTo(*this);
}
- /** Destructor */
- inline ~Matrix() {}
-
/** \sa MatrixBase::operator=(const AnyMatrixBase<OtherDerived>&) */
template<typename OtherDerived>
EIGEN_STRONG_INLINE Matrix(const AnyMatrixBase<OtherDerived> &other)
diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h
index 53dd6f991..f7b32a650 100644
--- a/Eigen/src/Core/MatrixBase.h
+++ b/Eigen/src/Core/MatrixBase.h
@@ -144,7 +144,7 @@ template<typename Derived> class MatrixBase
typedef CwiseNullaryOp<ei_scalar_constant_op<Scalar>,Derived> ConstantReturnType;
/** \internal the return type of MatrixBase::adjoint() */
typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
- CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<Derived> > >,
+ CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::Transpose<Derived> >,
Transpose<Derived>
>::ret AdjointReturnType;
/** \internal the return type of MatrixBase::eigenvalues() */
@@ -259,16 +259,16 @@ template<typename Derived> class MatrixBase
Derived& setIdentity();
- bool isIdentity(RealScalar prec = precision<Scalar>()) const;
- bool isDiagonal(RealScalar prec = precision<Scalar>()) const;
+ bool isIdentity(RealScalar prec = dummy_precision<Scalar>()) const;
+ bool isDiagonal(RealScalar prec = dummy_precision<Scalar>()) const;
- bool isUpperTriangular(RealScalar prec = precision<Scalar>()) const;
- bool isLowerTriangular(RealScalar prec = precision<Scalar>()) const;
+ bool isUpperTriangular(RealScalar prec = dummy_precision<Scalar>()) const;
+ bool isLowerTriangular(RealScalar prec = dummy_precision<Scalar>()) const;
template<typename OtherDerived>
bool isOrthogonal(const MatrixBase<OtherDerived>& other,
- RealScalar prec = precision<Scalar>()) const;
- bool isUnitary(RealScalar prec = precision<Scalar>()) const;
+ RealScalar prec = dummy_precision<Scalar>()) const;
+ bool isUnitary(RealScalar prec = dummy_precision<Scalar>()) const;
/** \returns true if each coefficients of \c *this and \a other are all exactly equal.
* \warning When using floating point scalar values you probably should rather use a
@@ -332,13 +332,13 @@ template<typename Derived> class MatrixBase
ResultType& inverse,
typename ResultType::Scalar& determinant,
bool& invertible,
- const RealScalar& absDeterminantThreshold = precision<Scalar>()
+ const RealScalar& absDeterminantThreshold = dummy_precision<Scalar>()
) const;
template<typename ResultType>
void computeInverseWithCheck(
ResultType& inverse,
bool& invertible,
- const RealScalar& absDeterminantThreshold = precision<Scalar>()
+ const RealScalar& absDeterminantThreshold = dummy_precision<Scalar>()
) const;
Scalar determinant() const;
@@ -376,7 +376,7 @@ template<typename Derived> class MatrixBase
ei_traits<Derived>::ColsAtCompileTime==1 ? SizeMinusOne : 1,
ei_traits<Derived>::ColsAtCompileTime==1 ? 1 : SizeMinusOne> StartMinusOne;
typedef CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>,
- NestByValue<StartMinusOne> > HNormalizedReturnType;
+ StartMinusOne > HNormalizedReturnType;
const HNormalizedReturnType hnormalized() const;
typedef Homogeneous<Derived,MatrixBase<Derived>::ColsAtCompileTime==1?Vertical:Horizontal> HomogeneousReturnType;
diff --git a/Eigen/src/Core/MatrixStorage.h b/Eigen/src/Core/MatrixStorage.h
index 73b17e63e..8bfa728b6 100644
--- a/Eigen/src/Core/MatrixStorage.h
+++ b/Eigen/src/Core/MatrixStorage.h
@@ -117,7 +117,6 @@ template<typename T, int Size, int _Options> class ei_matrix_storage<T, Size, Dy
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
: m_data(ei_constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
inline ei_matrix_storage(int, int rows, int cols) : m_rows(rows), m_cols(cols) {}
- inline ~ei_matrix_storage() {}
inline void swap(ei_matrix_storage& other)
{ std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
inline int rows(void) const {return m_rows;}
@@ -141,7 +140,6 @@ template<typename T, int Size, int _Cols, int _Options> class ei_matrix_storage<
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
: m_data(ei_constructor_without_unaligned_array_assert()), m_rows(0) {}
inline ei_matrix_storage(int, int rows, int) : m_rows(rows) {}
- inline ~ei_matrix_storage() {}
inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
inline int rows(void) const {return m_rows;}
inline int cols(void) const {return _Cols;}
@@ -163,7 +161,6 @@ template<typename T, int Size, int _Rows, int _Options> class ei_matrix_storage<
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
: m_data(ei_constructor_without_unaligned_array_assert()), m_cols(0) {}
inline ei_matrix_storage(int, int, int cols) : m_cols(cols) {}
- inline ~ei_matrix_storage() {}
inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
inline int rows(void) const {return _Rows;}
inline int cols(void) const {return m_cols;}
diff --git a/Eigen/src/Core/Minor.h b/Eigen/src/Core/Minor.h
index 3ed0fec6b..629dbe609 100644
--- a/Eigen/src/Core/Minor.h
+++ b/Eigen/src/Core/Minor.h
@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
+// Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -54,7 +54,8 @@ struct ei_traits<Minor<MatrixType> >
MaxColsAtCompileTime = (MatrixType::MaxColsAtCompileTime != Dynamic) ?
int(MatrixType::MaxColsAtCompileTime) - 1 : Dynamic,
Flags = _MatrixTypeNested::Flags & HereditaryBits,
- CoeffReadCost = _MatrixTypeNested::CoeffReadCost
+ CoeffReadCost = _MatrixTypeNested::CoeffReadCost // minor is used typically on tiny matrices,
+ // where loops are unrolled and the 'if' evaluates at compile time
};
};
diff --git a/Eigen/src/Core/NestByValue.h b/Eigen/src/Core/NestByValue.h
index 94a8f8078..85a672779 100644
--- a/Eigen/src/Core/NestByValue.h
+++ b/Eigen/src/Core/NestByValue.h
@@ -102,9 +102,6 @@ template<typename ExpressionType> class NestByValue
protected:
const ExpressionType m_expression;
-
- private:
- NestByValue& operator=(const NestByValue&);
};
/** \returns an expression of the temporary version of *this.
diff --git a/Eigen/src/Core/NoAlias.h b/Eigen/src/Core/NoAlias.h
index 7ed848bce..bfea5c91d 100644
--- a/Eigen/src/Core/NoAlias.h
+++ b/Eigen/src/Core/NoAlias.h
@@ -73,9 +73,6 @@ class NoAlias
protected:
ExpressionType& m_expression;
-
- private:
- NoAlias& operator=(const NoAlias&);
};
/** \returns a pseudo expression of \c *this with an operator= assuming
diff --git a/Eigen/src/Core/PermutationMatrix.h b/Eigen/src/Core/PermutationMatrix.h
index aaccb4e7b..284baf678 100644
--- a/Eigen/src/Core/PermutationMatrix.h
+++ b/Eigen/src/Core/PermutationMatrix.h
@@ -25,18 +25,24 @@
#ifndef EIGEN_PERMUTATIONMATRIX_H
#define EIGEN_PERMUTATIONMATRIX_H
-/** \nonstableyet
- * \class PermutationMatrix
+/** \class PermutationMatrix
*
* \brief Permutation matrix
*
* \param SizeAtCompileTime the number of rows/cols, or Dynamic
- * \param MaxSizeAtCompileTime the maximum number of rows/cols, or Dynamic. This optional parameter defaults to SizeAtCompileTime.
+ * \param MaxSizeAtCompileTime the maximum number of rows/cols, or Dynamic. This optional parameter defaults to SizeAtCompileTime. Most of the time, you should not have to specify it.
*
* This class represents a permutation matrix, internally stored as a vector of integers.
- * The convention followed here is the same as on <a href="http://en.wikipedia.org/wiki/Permutation_matrix">Wikipedia</a>,
- * namely: the matrix of permutation \a p is the matrix such that on each row \a i, the only nonzero coefficient is
- * in column p(i).
+ * The convention followed here is that if \f$ \sigma \f$ is a permutation, the corresponding permutation matrix
+ * \f$ P_\sigma \f$ is such that if \f$ (e_1,\ldots,e_p) \f$ is the canonical basis, we have:
+ * \f[ P_\sigma(e_i) = e_{\sigma(i)}. \f]
+ * This convention ensures that for any two permutations \f$ \sigma, \tau \f$, we have:
+ * \f[ P_{\sigma\circ\tau} = P_\sigma P_\tau. \f]
+ *
+ * Permutation matrices are square and invertible.
+ *
+ * Notice that in addition to the member functions and operators listed here, there also are non-member
+ * operator* to multiply a PermutationMatrix with any kind of matrix expression (MatrixBase) on either side.
*
* \sa class DiagonalMatrix
*/
@@ -53,6 +59,7 @@ class PermutationMatrix : public AnyMatrixBase<PermutationMatrix<SizeAtCompileTi
{
public:
+ #ifndef EIGEN_PARSED_BY_DOXYGEN
typedef ei_traits<PermutationMatrix> Traits;
typedef Matrix<int,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime>
DenseMatrixType;
@@ -65,25 +72,37 @@ class PermutationMatrix : public AnyMatrixBase<PermutationMatrix<SizeAtCompileTi
MaxColsAtCompileTime = Traits::MaxColsAtCompileTime
};
typedef typename Traits::Scalar Scalar;
+ #endif
- typedef Matrix<int, RowsAtCompileTime, 1, 0, MaxRowsAtCompileTime, 1> IndicesType;
+ typedef Matrix<int, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType;
inline PermutationMatrix()
{
}
+ /** Copy constructor. */
template<int OtherSize, int OtherMaxSize>
inline PermutationMatrix(const PermutationMatrix<OtherSize, OtherMaxSize>& other)
: m_indices(other.indices()) {}
- /** copy constructor. prevent a default copy constructor from hiding the other templated constructor */
+ #ifndef EIGEN_PARSED_BY_DOXYGEN
+ /** Standard copy constructor. Defined only to prevent a default copy constructor
+ * from hiding the other templated constructor */
inline PermutationMatrix(const PermutationMatrix& other) : m_indices(other.indices()) {}
+ #endif
- /** generic constructor from expression of the indices */
+ /** Generic constructor from expression of the indices. The indices
+ * array has the meaning that the permutations sends each integer i to indices[i].
+ *
+ * \warning It is your responsibility to check that the indices array that you passes actually
+ * describes a permutation, i.e., each value between 0 and n-1 occurs exactly once, where n is the
+ * array's size.
+ */
template<typename Other>
- explicit inline PermutationMatrix(const MatrixBase<Other>& other) : m_indices(other)
+ explicit inline PermutationMatrix(const MatrixBase<Other>& indices) : m_indices(indices)
{}
+ /** Copies the other permutation into *this */
template<int OtherSize, int OtherMaxSize>
PermutationMatrix& operator=(const PermutationMatrix<OtherSize, OtherMaxSize>& other)
{
@@ -91,42 +110,143 @@ class PermutationMatrix : public AnyMatrixBase<PermutationMatrix<SizeAtCompileTi
return *this;
}
+ #ifndef EIGEN_PARSED_BY_DOXYGEN
/** This is a special case of the templated operator=. Its purpose is to
* prevent a default operator= from hiding the templated operator=.
*/
PermutationMatrix& operator=(const PermutationMatrix& other)
{
- m_indices = other.m_indices();
+ m_indices = other.m_indices;
return *this;
}
+ #endif
- inline PermutationMatrix(int rows, int cols) : m_indices(rows)
- {
- ei_assert(rows == cols);
- }
+ /** Constructs an uninitialized permutation matrix of given size.
+ */
+ inline PermutationMatrix(int size) : m_indices(size)
+ {}
- /** \returns the number of columns */
+ /** \returns the number of rows */
inline int rows() const { return m_indices.size(); }
- /** \returns the number of rows */
+ /** \returns the number of columns */
inline int cols() const { return m_indices.size(); }
+ #ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename DenseDerived>
void evalTo(MatrixBase<DenseDerived>& other) const
{
other.setZero();
for (int i=0; i<rows();++i)
- other.coeffRef(i,m_indices.coeff(i)) = typename DenseDerived::Scalar(1);
+ other.coeffRef(m_indices.coeff(i),i) = typename DenseDerived::Scalar(1);
}
+ #endif
+ /** \returns a Matrix object initialized from this permutation matrix. Notice that it
+ * is inefficient to return this Matrix object by value. For efficiency, favor using
+ * the Matrix constructor taking AnyMatrixBase objects.
+ */
DenseMatrixType toDenseMatrix() const
{
return *this;
}
+ /** const version of indices(). */
const IndicesType& indices() const { return m_indices; }
+ /** \returns a reference to the stored array representing the permutation. */
IndicesType& indices() { return m_indices; }
-
+
+ /** Resizes to given size.
+ */
+ inline void resize(int size)
+ {
+ m_indices.resize(size);
+ }
+
+ /** Sets *this to be the identity permutation matrix */
+ void setIdentity()
+ {
+ for(int i = 0; i < m_indices.size(); ++i)
+ m_indices.coeffRef(i) = i;
+ }
+
+ /** Sets *this to be the identity permutation matrix of given size.
+ */
+ void setIdentity(int size)
+ {
+ resize(size);
+ setIdentity();
+ }
+
+ /** Multiplies *this by the transposition \f$(ij)\f$ on the left.
+ *
+ * \returns a reference to *this.
+ *
+ * \warning This is much slower than applyTranspositionOnTheRight(int,int):
+ * this has linear complexity and requires a lot of branching.
+ *
+ * \sa applyTranspositionOnTheRight(int,int)
+ */
+ PermutationMatrix& applyTranspositionOnTheLeft(int i, int j)
+ {
+ ei_assert(i>=0 && j>=0 && i<m_indices.size() && j<m_indices.size());
+ for(int k = 0; k < m_indices.size(); ++k)
+ {
+ if(m_indices.coeff(k) == i) m_indices.coeffRef(k) = j;
+ else if(m_indices.coeff(k) == j) m_indices.coeffRef(k) = i;
+ }
+ return *this;
+ }
+
+ /** Multiplies *this by the transposition \f$(ij)\f$ on the right.
+ *
+ * \returns a reference to *this.
+ *
+ * This is a fast operation, it only consists in swapping two indices.
+ *
+ * \sa applyTranspositionOnTheLeft(int,int)
+ */
+ PermutationMatrix& applyTranspositionOnTheRight(int i, int j)
+ {
+ ei_assert(i>=0 && j>=0 && i<m_indices.size() && j<m_indices.size());
+ std::swap(m_indices.coeffRef(i), m_indices.coeffRef(j));
+ return *this;
+ }
+
+ /**** inversion and multiplication helpers to hopefully get RVO ****/
+
+#ifndef EIGEN_PARSED_BY_DOXYGEN
+ protected:
+ enum Inverse_t {Inverse};
+ PermutationMatrix(Inverse_t, const PermutationMatrix& other)
+ : m_indices(other.m_indices.size())
+ {
+ for (int i=0; i<rows();++i) m_indices.coeffRef(other.m_indices.coeff(i)) = i;
+ }
+ enum Product_t {Product};
+ PermutationMatrix(Product_t, const PermutationMatrix& lhs, const PermutationMatrix& rhs)
+ : m_indices(lhs.m_indices.size())
+ {
+ ei_assert(lhs.cols() == rhs.rows());
+ for (int i=0; i<rows();++i) m_indices.coeffRef(i) = lhs.m_indices.coeff(rhs.m_indices.coeff(i));
+ }
+#endif
+
+ public:
+ /** \returns the inverse permutation matrix.
+ *
+ * \note \note_try_to_help_rvo
+ */
+ inline PermutationMatrix inverse() const
+ { return PermutationMatrix(Inverse, *this); }
+ /** \returns the product permutation matrix.
+ *
+ * \note \note_try_to_help_rvo
+ */
+ template<int OtherSize, int OtherMaxSize>
+ inline PermutationMatrix operator*(const PermutationMatrix<OtherSize, OtherMaxSize>& other) const
+ { return PermutationMatrix(Product, *this, other); }
+
protected:
IndicesType m_indices;
@@ -185,7 +305,7 @@ struct ei_permut_matrix_product_retval
Dest,
Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime,
Side==OnTheRight ? 1 : Dest::ColsAtCompileTime
- >(dst, Side==OnTheRight ? m_permutation.indices().coeff(i) : i)
+ >(dst, Side==OnTheLeft ? m_permutation.indices().coeff(i) : i)
=
@@ -193,7 +313,7 @@ struct ei_permut_matrix_product_retval
MatrixTypeNestedCleaned,
Side==OnTheLeft ? 1 : MatrixType::RowsAtCompileTime,
Side==OnTheRight ? 1 : MatrixType::ColsAtCompileTime
- >(m_matrix, Side==OnTheLeft ? m_permutation.indices().coeff(i) : i);
+ >(m_matrix, Side==OnTheRight ? m_permutation.indices().coeff(i) : i);
}
}
diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h
index 7db35eaad..15f44de89 100644
--- a/Eigen/src/Core/Product.h
+++ b/Eigen/src/Core/Product.h
@@ -58,10 +58,12 @@ enum { OuterProduct, InnerProduct, UnrolledProduct, GemvProduct, GemmProduct };
template<typename Lhs, typename Rhs> struct ei_product_type
{
+ typedef typename ei_cleantype<Lhs>::type _Lhs;
+ typedef typename ei_cleantype<Rhs>::type _Rhs;
enum {
- Rows = Lhs::RowsAtCompileTime,
- Cols = Rhs::ColsAtCompileTime,
- Depth = EIGEN_ENUM_MIN(Lhs::ColsAtCompileTime,Rhs::RowsAtCompileTime)
+ Rows = _Lhs::RowsAtCompileTime,
+ Cols = _Rhs::ColsAtCompileTime,
+ Depth = EIGEN_ENUM_MIN(_Lhs::ColsAtCompileTime,_Rhs::RowsAtCompileTime)
};
// the splitting into different lines of code here, introducing the _select enums and the typedef below,
@@ -211,9 +213,6 @@ class GeneralProduct<Lhs, Rhs, OuterProduct>
{
ei_outer_product_selector<(int(Dest::Flags)&RowMajorBit) ? RowMajor : ColMajor>::run(*this, dest, alpha);
}
-
- private:
- GeneralProduct& operator=(const GeneralProduct&);
};
template<> struct ei_outer_product_selector<ColMajor> {
@@ -279,9 +278,6 @@ class GeneralProduct<Lhs, Rhs, GemvProduct>
ei_gemv_selector<Side,(int(MatrixType::Flags)&RowMajorBit) ? RowMajor : ColMajor,
bool(ei_blas_traits<MatrixType>::ActualAccess)>::run(*this, dst, alpha);
}
-
-private:
- GeneralProduct& operator=(const GeneralProduct&);
};
// The vector is on the left => transposition
diff --git a/Eigen/src/Core/ProductBase.h b/Eigen/src/Core/ProductBase.h
index d835f16b7..3248e7293 100644
--- a/Eigen/src/Core/ProductBase.h
+++ b/Eigen/src/Core/ProductBase.h
@@ -114,14 +114,6 @@ class ProductBase : public MatrixBase<Derived>
template<typename Dest>
inline void scaleAndAddTo(Dest& dst,Scalar alpha) const { derived().scaleAndAddTo(dst,alpha); }
- PlainMatrixType eval() const
- {
- PlainMatrixType res(rows(), cols());
- res.setZero();
- derived().evalTo(res);
- return res;
- }
-
EIGEN_DEPRECATED const Flagged<ProductBase, 0, EvalBeforeAssigningBit> lazy() const
{ return *this; }
@@ -140,8 +132,6 @@ class ProductBase : public MatrixBase<Derived>
void coeffRef(int,int);
void coeff(int) const;
void coeffRef(int);
-
- ProductBase& operator=(const ProductBase&);
};
template<typename NestedProduct>
diff --git a/Eigen/src/Core/Redux.h b/Eigen/src/Core/Redux.h
index b6b28c00b..92522f86c 100644
--- a/Eigen/src/Core/Redux.h
+++ b/Eigen/src/Core/Redux.h
@@ -54,16 +54,16 @@ private:
public:
enum {
- Vectorization = int(MayLinearVectorize) ? int(LinearVectorization)
- : int(MaySliceVectorize) ? int(SliceVectorization)
- : int(NoVectorization)
+ Traversal = int(MayLinearVectorize) ? int(LinearVectorizedTraversal)
+ : int(MaySliceVectorize) ? int(SliceVectorizedTraversal)
+ : int(DefaultTraversal)
};
private:
enum {
Cost = Derived::SizeAtCompileTime * Derived::CoeffReadCost
+ (Derived::SizeAtCompileTime-1) * NumTraits<typename Derived::Scalar>::AddCost,
- UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Vectorization) == int(NoVectorization) ? 1 : int(PacketSize))
+ UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Traversal) == int(DefaultTraversal) ? 1 : int(PacketSize))
};
public:
@@ -171,13 +171,13 @@ struct ei_redux_vec_unroller<Func, Derived, Start, 1>
***************************************************************************/
template<typename Func, typename Derived,
- int Vectorization = ei_redux_traits<Func, Derived>::Vectorization,
+ int Traversal = ei_redux_traits<Func, Derived>::Traversal,
int Unrolling = ei_redux_traits<Func, Derived>::Unrolling
>
struct ei_redux_impl;
template<typename Func, typename Derived>
-struct ei_redux_impl<Func, Derived, NoVectorization, NoUnrolling>
+struct ei_redux_impl<Func, Derived, DefaultTraversal, NoUnrolling>
{
typedef typename Derived::Scalar Scalar;
static Scalar run(const Derived& mat, const Func& func)
@@ -195,12 +195,12 @@ struct ei_redux_impl<Func, Derived, NoVectorization, NoUnrolling>
};
template<typename Func, typename Derived>
-struct ei_redux_impl<Func,Derived, NoVectorization, CompleteUnrolling>
+struct ei_redux_impl<Func,Derived, DefaultTraversal, CompleteUnrolling>
: public ei_redux_novec_unroller<Func,Derived, 0, Derived::SizeAtCompileTime>
{};
template<typename Func, typename Derived>
-struct ei_redux_impl<Func, Derived, LinearVectorization, NoUnrolling>
+struct ei_redux_impl<Func, Derived, LinearVectorizedTraversal, NoUnrolling>
{
typedef typename Derived::Scalar Scalar;
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
@@ -209,10 +209,7 @@ struct ei_redux_impl<Func, Derived, LinearVectorization, NoUnrolling>
{
const int size = mat.size();
const int packetSize = ei_packet_traits<Scalar>::size;
- const int alignedStart = (Derived::Flags & AlignedBit)
- || !(Derived::Flags & DirectAccessBit)
- ? 0
- : ei_alignmentOffset(&mat.const_cast_derived().coeffRef(0), size);
+ const int alignedStart = ei_alignmentOffset(mat,size);
enum {
alignment = (Derived::Flags & DirectAccessBit) || (Derived::Flags & AlignedBit)
? Aligned : Unaligned
@@ -246,7 +243,7 @@ struct ei_redux_impl<Func, Derived, LinearVectorization, NoUnrolling>
};
template<typename Func, typename Derived>
-struct ei_redux_impl<Func, Derived, SliceVectorization, NoUnrolling>
+struct ei_redux_impl<Func, Derived, SliceVectorizedTraversal, NoUnrolling>
{
typedef typename Derived::Scalar Scalar;
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
@@ -277,7 +274,7 @@ struct ei_redux_impl<Func, Derived, SliceVectorization, NoUnrolling>
else // too small to vectorize anything.
// since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize.
{
- res = ei_redux_impl<Func, Derived, NoVectorization, NoUnrolling>::run(mat, func);
+ res = ei_redux_impl<Func, Derived, DefaultTraversal, NoUnrolling>::run(mat, func);
}
return res;
@@ -285,20 +282,20 @@ struct ei_redux_impl<Func, Derived, SliceVectorization, NoUnrolling>
};
template<typename Func, typename Derived>
-struct ei_redux_impl<Func, Derived, LinearVectorization, CompleteUnrolling>
+struct ei_redux_impl<Func, Derived, LinearVectorizedTraversal, CompleteUnrolling>
{
typedef typename Derived::Scalar Scalar;
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
enum {
PacketSize = ei_packet_traits<Scalar>::size,
Size = Derived::SizeAtCompileTime,
- VectorizationSize = (Size / PacketSize) * PacketSize
+ VectorizedSize = (Size / PacketSize) * PacketSize
};
EIGEN_STRONG_INLINE static Scalar run(const Derived& mat, const Func& func)
{
Scalar res = func.predux(ei_redux_vec_unroller<Func, Derived, 0, Size / PacketSize>::run(mat,func));
- if (VectorizationSize != Size)
- res = func(res,ei_redux_novec_unroller<Func, Derived, VectorizationSize, Size-VectorizationSize>::run(mat,func));
+ if (VectorizedSize != Size)
+ res = func(res,ei_redux_novec_unroller<Func, Derived, VectorizedSize, Size-VectorizedSize>::run(mat,func));
return res;
}
};
diff --git a/Eigen/src/Core/SelfAdjointView.h b/Eigen/src/Core/SelfAdjointView.h
index 3e435853c..9ab8cb2c1 100644
--- a/Eigen/src/Core/SelfAdjointView.h
+++ b/Eigen/src/Core/SelfAdjointView.h
@@ -150,7 +150,6 @@ template<typename MatrixType, unsigned int UpLo> class SelfAdjointView
const LDLT<PlainMatrixType> ldlt() const;
protected:
-
const typename MatrixType::Nested m_matrix;
};
diff --git a/Eigen/src/Core/Swap.h b/Eigen/src/Core/Swap.h
index 2af78485b..010d8bb8b 100644
--- a/Eigen/src/Core/Swap.h
+++ b/Eigen/src/Core/Swap.h
@@ -106,9 +106,6 @@ template<typename ExpressionType> class SwapWrapper
protected:
ExpressionType& m_expression;
-
- private:
- SwapWrapper& operator=(const SwapWrapper&);
};
/** swaps *this with the expression \a other.
diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h
index 513ce522a..63d77f134 100644
--- a/Eigen/src/Core/Transpose.h
+++ b/Eigen/src/Core/Transpose.h
@@ -215,7 +215,7 @@ template<typename Derived>
inline const typename MatrixBase<Derived>::AdjointReturnType
MatrixBase<Derived>::adjoint() const
{
- return this->transpose().nestByValue();
+ return this->transpose();
}
/***************************************************************************
@@ -297,13 +297,7 @@ inline void MatrixBase<Derived>::adjointInPlace()
#ifndef EIGEN_NO_DEBUG
-// The following is to detect aliasing problems in the following common cases:
-// a = a.transpose()
-// a = a.transpose() + X
-// a = X + a.transpose()
-// a = a.adjoint()
-// a = a.adjoint() + X
-// a = X + a.adjoint()
+// The following is to detect aliasing problems in most common cases.
template<typename T, int Access=ei_blas_traits<T>::ActualAccess>
struct ei_extract_data_selector {
@@ -323,63 +317,31 @@ template<typename T> typename T::Scalar* ei_extract_data(const T& m)
return ei_extract_data_selector<T>::run(m);
}
-template<typename Derived>
-template<typename OtherDerived>
-Derived& DenseBase<Derived>::lazyAssign(const Transpose<OtherDerived>& other)
-{
- ei_assert(ei_extract_data(other) != ei_extract_data(derived())
- && "aliasing detected during tranposition, please use transposeInPlace()");
- return lazyAssign(static_cast<const DenseBase<Transpose<OtherDerived> >& >(other));
-}
-
-template<typename Derived>
-template<typename DerivedA, typename DerivedB>
-Derived& DenseBase<Derived>::
-lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,Transpose<DerivedA>,DerivedB>& other)
-{
- ei_assert(ei_extract_data(derived()) != ei_extract_data(other.lhs())
- && "aliasing detected during tranposition, please evaluate your expression");
- return lazyAssign(static_cast<const DenseBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,Transpose<DerivedA>,DerivedB> >& >(other));
-}
-
-template<typename Derived>
-template<typename DerivedA, typename DerivedB>
-Derived& DenseBase<Derived>::
-lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,Transpose<DerivedB> >& other)
-{
- ei_assert(ei_extract_data(derived()) != ei_extract_data(other.rhs())
- && "aliasing detected during tranposition, please evaluate your expression");
- return lazyAssign(static_cast<const DenseBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,Transpose<DerivedB> > >& >(other));
-}
-
-template<typename Derived>
-template<typename OtherDerived> Derived&
-DenseBase<Derived>::
-lazyAssign(const CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<OtherDerived> > >& other)
+template<typename Scalar, bool DestIsTranposed, typename OtherDerived>
+struct ei_check_transpose_aliasing_selector
{
- ei_assert(ei_extract_data(other) != ei_extract_data(derived())
- && "aliasing detected during tranposition, please use adjointInPlace()");
- return lazyAssign(static_cast<const DenseBase<CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<OtherDerived> > > >& >(other));
-}
+ static bool run(const Scalar* dest, const OtherDerived& src)
+ {
+ return (ei_blas_traits<OtherDerived>::IsTransposed != DestIsTranposed) && (dest==(Scalar*)ei_extract_data(src));
+ }
+};
-template<typename Derived>
-template<typename DerivedA, typename DerivedB>
-Derived& DenseBase<Derived>::
-lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedA> > >,DerivedB>& other)
+template<typename Scalar, bool DestIsTranposed, typename BinOp, typename DerivedA, typename DerivedB>
+struct ei_check_transpose_aliasing_selector<Scalar,DestIsTranposed,CwiseBinaryOp<BinOp,DerivedA,DerivedB> >
{
- ei_assert(ei_extract_data(derived()) != ei_extract_data(other.lhs())
- && "aliasing detected during tranposition, please evaluate your expression");
- return lazyAssign(static_cast<const DenseBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedA> > >,DerivedB> >& >(other));
-}
+ static bool run(const Scalar* dest, const CwiseBinaryOp<BinOp,DerivedA,DerivedB>& src)
+ {
+ return ((ei_blas_traits<DerivedA>::IsTransposed != DestIsTranposed) && dest==(Scalar*)ei_extract_data(src.lhs()))
+ || ((ei_blas_traits<DerivedB>::IsTransposed != DestIsTranposed) && dest==(Scalar*)ei_extract_data(src.rhs()));
+ }
+};
template<typename Derived>
-template<typename DerivedA, typename DerivedB>
-Derived& DenseBase<Derived>::
-lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedB> > > >& other)
+template<typename OtherDerived>
+void DenseBase<Derived>::checkTransposeAliasing(const OtherDerived& other) const
{
- ei_assert(ei_extract_data(derived()) != ei_extract_data(other.rhs())
- && "aliasing detected during tranposition, please evaluate your expression");
- return lazyAssign(static_cast<const DenseBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedB> > > > >& >(other));
+ ei_assert((!ei_check_transpose_aliasing_selector<Scalar,ei_blas_traits<Derived>::IsTransposed,OtherDerived>::run(ei_extract_data(derived()), other))
+ && "aliasing detected during tranposition, use transposeInPlace() or evaluate the rhs into a temporary using .eval()");
}
#endif
diff --git a/Eigen/src/Core/TriangularMatrix.h b/Eigen/src/Core/TriangularMatrix.h
index e60d57e70..aaf781d1f 100644
--- a/Eigen/src/Core/TriangularMatrix.h
+++ b/Eigen/src/Core/TriangularMatrix.h
@@ -26,22 +26,11 @@
#ifndef EIGEN_TRIANGULARMATRIX_H
#define EIGEN_TRIANGULARMATRIX_H
-/** \nonstableyet
- * \class TriangularBase
- *
- * \brief Expression of a triangular matrix extracted from a given matrix
- *
- * \param MatrixType the type of the object in which we are taking the triangular part
- * \param Mode the kind of triangular matrix expression to construct. Can be UpperTriangular,
- * LowerTriangular, UpperSelfadjoint, or LowerSelfadjoint. This is in fact a bit field;
- * it must have either UpperBit or LowerBit, and additionnaly it may have either
- * TraingularBit or SelfadjointBit.
+/** \internal
*
- * This class represents an expression of the upper or lower triangular part of
- * a square matrix, possibly with a further assumption on the diagonal. It is the return type
- * of MatrixBase::part() and most of the time this is the only way it is used.
+ * \class TriangularBase
*
- * \sa MatrixBase::part()
+ * \brief Base class for triangular part in a matrix
*/
template<typename Derived> class TriangularBase : public AnyMatrixBase<Derived>
{
@@ -99,11 +88,11 @@ template<typename Derived> class TriangularBase : public AnyMatrixBase<Derived>
void check_coordinates(int row, int col)
{
- ei_assert(col>0 && col<cols() && row>0 && row<rows());
+ ei_assert(col>=0 && col<cols() && row>=0 && row<rows());
ei_assert( (Mode==UpperTriangular && col>=row)
|| (Mode==LowerTriangular && col<=row)
- || (Mode==StrictlyUpperTriangular && col>row)
- || (Mode==StrictlyLowerTriangular && col<row));
+ || ((Mode==StrictlyUpperTriangular || Mode==UnitUpperTriangular) && col>row)
+ || ((Mode==StrictlyLowerTriangular || Mode==UnitLowerTriangular) && col<row));
}
void check_coordinates_internal(int row, int col)
@@ -115,19 +104,21 @@ template<typename Derived> class TriangularBase : public AnyMatrixBase<Derived>
};
-
/** \class TriangularView
- * \nonstableyet
*
- * \brief Expression of a triangular part of a dense matrix
+ * \brief Base class for triangular part in a matrix
*
- * \param MatrixType the type of the dense matrix storing the coefficients
+ * \param MatrixType the type of the object in which we are taking the triangular part
+ * \param Mode the kind of triangular matrix expression to construct. Can be UpperTriangular,
+ * LowerTriangular, UpperSelfadjoint, or LowerSelfadjoint. This is in fact a bit field;
+ * it must have either UpperBit or LowerBit, and additionnaly it may have either
+ * TraingularBit or SelfadjointBit.
*
- * This class is an expression of a triangular part of a matrix with given dense
- * storage of the coefficients. It is the return type of MatrixBase::triangularPart()
- * and most of the time this is the only way that it is used.
+ * This class represents a triangular part of a matrix, not necessarily square. Strictly speaking, for rectangular
+ * matrices one should speak ok "trapezoid" parts. This class is the return type
+ * of MatrixBase::triangularView() and most of the time this is the only way it is used.
*
- * \sa class TriangularBase, MatrixBase::triangularPart(), class DiagonalWrapper
+ * \sa MatrixBase::triangularView()
*/
template<typename MatrixType, unsigned int _Mode>
struct ei_traits<TriangularView<MatrixType, _Mode> > : ei_traits<MatrixType>
@@ -155,7 +146,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
typedef TriangularBase<TriangularView> Base;
typedef typename ei_traits<TriangularView>::Scalar Scalar;
typedef _MatrixType MatrixType;
- typedef typename MatrixType::PlainMatrixType PlainMatrixType;
+ typedef typename MatrixType::PlainMatrixType DenseMatrixType;
typedef typename MatrixType::Nested MatrixTypeNested;
typedef typename ei_cleantype<MatrixTypeNested>::type _MatrixTypeNested;
@@ -231,23 +222,23 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
/** \sa MatrixBase::adjoint() */
- inline TriangularView<NestByValue<typename MatrixType::AdjointReturnType>,TransposeMode> adjoint()
- { return m_matrix.adjoint().nestByValue(); }
+ inline TriangularView<typename MatrixType::AdjointReturnType,TransposeMode> adjoint()
+ { return m_matrix.adjoint(); }
/** \sa MatrixBase::adjoint() const */
- inline const TriangularView<NestByValue<typename MatrixType::AdjointReturnType>,TransposeMode> adjoint() const
- { return m_matrix.adjoint().nestByValue(); }
+ inline const TriangularView<typename MatrixType::AdjointReturnType,TransposeMode> adjoint() const
+ { return m_matrix.adjoint(); }
/** \sa MatrixBase::transpose() */
- inline TriangularView<NestByValue<Transpose<MatrixType> >,TransposeMode> transpose()
- { return m_matrix.transpose().nestByValue(); }
+ inline TriangularView<Transpose<MatrixType>,TransposeMode> transpose()
+ { return m_matrix.transpose(); }
/** \sa MatrixBase::transpose() const */
- inline const TriangularView<NestByValue<Transpose<MatrixType> >,TransposeMode> transpose() const
- { return m_matrix.transpose().nestByValue(); }
+ inline const TriangularView<Transpose<MatrixType>,TransposeMode> transpose() const
+ { return m_matrix.transpose(); }
- PlainMatrixType toDense() const
+ DenseMatrixType toDenseMatrix() const
{
- PlainMatrixType res(rows(), cols());
- res = *this;
+ DenseMatrixType res(rows(), cols());
+ evalToLazy(res);
return res;
}
@@ -351,20 +342,7 @@ struct ei_triangular_assignment_selector
}
}
};
-template<typename Derived1, typename Derived2, unsigned int Mode, bool ClearOpposite>
-struct ei_triangular_assignment_selector<Derived1, Derived2, Mode, 1, ClearOpposite>
-{
- inline static void run(Derived1 &dst, const Derived2 &src)
- {
- if(Mode&UnitDiagBit)
- {
- if(ClearOpposite)
- dst.coeffRef(0, 0) = 1;
- }
- else if(!(Mode & ZeroDiagBit))
- dst.copyCoeff(0, 0, src);
- }
-};
+
// prevent buggy user code from causing an infinite recursion
template<typename Derived1, typename Derived2, unsigned int Mode, bool ClearOpposite>
struct ei_triangular_assignment_selector<Derived1, Derived2, Mode, 0, ClearOpposite>
@@ -379,14 +357,16 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, UpperTriangular, Dy
{
for(int j = 0; j < dst.cols(); ++j)
{
- for(int i = 0; i <= j; ++i)
+ int maxi = std::min(j, dst.rows()-1);
+ for(int i = 0; i <= maxi; ++i)
dst.copyCoeff(i, j, src);
if (ClearOpposite)
- for(int i = j+1; i < dst.rows(); ++i)
+ for(int i = maxi+1; i < dst.rows(); ++i)
dst.coeffRef(i, j) = 0;
}
}
};
+
template<typename Derived1, typename Derived2, bool ClearOpposite>
struct ei_triangular_assignment_selector<Derived1, Derived2, LowerTriangular, Dynamic, ClearOpposite>
{
@@ -396,8 +376,9 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, LowerTriangular, Dy
{
for(int i = j; i < dst.rows(); ++i)
dst.copyCoeff(i, j, src);
+ int maxi = std::min(j, dst.rows());
if (ClearOpposite)
- for(int i = 0; i < j; ++i)
+ for(int i = 0; i < maxi; ++i)
dst.coeffRef(i, j) = 0;
}
}
@@ -410,14 +391,16 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, StrictlyUpperTriang
{
for(int j = 0; j < dst.cols(); ++j)
{
- for(int i = 0; i < j; ++i)
+ int maxi = std::min(j, dst.rows());
+ for(int i = 0; i < maxi; ++i)
dst.copyCoeff(i, j, src);
if (ClearOpposite)
- for(int i = j; i < dst.rows(); ++i)
+ for(int i = maxi; i < dst.rows(); ++i)
dst.coeffRef(i, j) = 0;
}
}
};
+
template<typename Derived1, typename Derived2, bool ClearOpposite>
struct ei_triangular_assignment_selector<Derived1, Derived2, StrictlyLowerTriangular, Dynamic, ClearOpposite>
{
@@ -427,8 +410,9 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, StrictlyLowerTriang
{
for(int i = j+1; i < dst.rows(); ++i)
dst.copyCoeff(i, j, src);
+ int maxi = std::min(j, dst.rows()-1);
if (ClearOpposite)
- for(int i = 0; i <= j; ++i)
+ for(int i = 0; i <= maxi; ++i)
dst.coeffRef(i, j) = 0;
}
}
@@ -441,15 +425,16 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, UnitUpperTriangular
{
for(int j = 0; j < dst.cols(); ++j)
{
- for(int i = 0; i < j; ++i)
+ int maxi = std::min(j, dst.rows());
+ for(int i = 0; i < maxi; ++i)
dst.copyCoeff(i, j, src);
if (ClearOpposite)
{
- for(int i = j+1; i < dst.rows(); ++i)
+ for(int i = maxi+1; i < dst.rows(); ++i)
dst.coeffRef(i, j) = 0;
- dst.coeffRef(j, j) = 1;
}
}
+ dst.diagonal().setOnes();
}
};
template<typename Derived1, typename Derived2, bool ClearOpposite>
@@ -459,15 +444,16 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, UnitLowerTriangular
{
for(int j = 0; j < dst.cols(); ++j)
{
- for(int i = j+1; i < dst.rows(); ++i)
+ int maxi = std::min(j, dst.rows());
+ for(int i = maxi+1; i < dst.rows(); ++i)
dst.copyCoeff(i, j, src);
if (ClearOpposite)
{
- for(int i = 0; i < j; ++i)
+ for(int i = 0; i < maxi; ++i)
dst.coeffRef(i, j) = 0;
- dst.coeffRef(j, j) = 1;
}
}
+ dst.diagonal().setOnes();
}
};
@@ -514,7 +500,7 @@ TriangularView<MatrixType, Mode>::operator=(const TriangularBase<OtherDerived>&
ei_assert(Mode == OtherDerived::Mode);
if(ei_traits<OtherDerived>::Flags & EvalBeforeAssigningBit)
{
- typename OtherDerived::PlainMatrixType other_evaluated(other.rows(), other.cols());
+ typename OtherDerived::DenseMatrixType other_evaluated(other.rows(), other.cols());
other_evaluated.template triangularView<Mode>().lazyAssign(other.derived());
lazyAssign(other_evaluated);
}
@@ -633,17 +619,20 @@ const TriangularView<Derived, Mode> MatrixBase<Derived>::triangularView() const
template<typename Derived>
bool MatrixBase<Derived>::isUpperTriangular(RealScalar prec) const
{
- if(cols() != rows()) return false;
RealScalar maxAbsOnUpperTriangularPart = static_cast<RealScalar>(-1);
for(int j = 0; j < cols(); ++j)
- for(int i = 0; i <= j; ++i)
+ {
+ int maxi = std::min(j, rows()-1);
+ for(int i = 0; i <= maxi; ++i)
{
RealScalar absValue = ei_abs(coeff(i,j));
if(absValue > maxAbsOnUpperTriangularPart) maxAbsOnUpperTriangularPart = absValue;
}
- for(int j = 0; j < cols()-1; ++j)
+ }
+ RealScalar threshold = maxAbsOnUpperTriangularPart * prec;
+ for(int j = 0; j < cols(); ++j)
for(int i = j+1; i < rows(); ++i)
- if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnUpperTriangularPart, prec)) return false;
+ if(ei_abs(coeff(i, j)) > threshold) return false;
return true;
}
@@ -655,7 +644,6 @@ bool MatrixBase<Derived>::isUpperTriangular(RealScalar prec) const
template<typename Derived>
bool MatrixBase<Derived>::isLowerTriangular(RealScalar prec) const
{
- if(cols() != rows()) return false;
RealScalar maxAbsOnLowerTriangularPart = static_cast<RealScalar>(-1);
for(int j = 0; j < cols(); ++j)
for(int i = j; i < rows(); ++i)
@@ -663,9 +651,13 @@ bool MatrixBase<Derived>::isLowerTriangular(RealScalar prec) const
RealScalar absValue = ei_abs(coeff(i,j));
if(absValue > maxAbsOnLowerTriangularPart) maxAbsOnLowerTriangularPart = absValue;
}
+ RealScalar threshold = maxAbsOnLowerTriangularPart * prec;
for(int j = 1; j < cols(); ++j)
- for(int i = 0; i < j; ++i)
- if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnLowerTriangularPart, prec)) return false;
+ {
+ int maxi = std::min(j, rows()-1);
+ for(int i = 0; i < maxi; ++i)
+ if(ei_abs(coeff(i, j)) > threshold) return false;
+ }
return true;
}
diff --git a/Eigen/src/Core/arch/SSE/MathFunctions.h b/Eigen/src/Core/arch/SSE/MathFunctions.h
index 8399aac30..3c0020248 100644
--- a/Eigen/src/Core/arch/SSE/MathFunctions.h
+++ b/Eigen/src/Core/arch/SSE/MathFunctions.h
@@ -365,6 +365,8 @@ static EIGEN_DONT_INLINE EIGEN_UNUSED Packet4f ei_pcos(Packet4f x)
return _mm_xor_ps(y, sign_bit);
}
+// This is Quake3's fast inverse square root.
+// For detail see here: http://www.beyond3d.com/content/articles/8/
static EIGEN_UNUSED Packet4f ei_psqrt(Packet4f _x)
{
Packet4f half = ei_pmul(_x, ei_pset1(.5f));
diff --git a/Eigen/src/Core/arch/SSE/PacketMath.h b/Eigen/src/Core/arch/SSE/PacketMath.h
index 29c89c310..a633c7b7c 100644
--- a/Eigen/src/Core/arch/SSE/PacketMath.h
+++ b/Eigen/src/Core/arch/SSE/PacketMath.h
@@ -58,8 +58,8 @@ template<> struct ei_packet_traits<float> : ei_default_packet_traits
{
typedef Packet4f type; enum {size=4};
enum {
- HasSin = 1,
- HasCos = 1,
+ HasSin = EIGEN_FAST_MATH,
+ HasCos = EIGEN_FAST_MATH,
HasLog = 1,
HasExp = 1,
HasSqrt = 1
@@ -118,6 +118,9 @@ template<> EIGEN_STRONG_INLINE Packet4f ei_pmul<Packet4f>(const Packet4f& a, con
template<> EIGEN_STRONG_INLINE Packet2d ei_pmul<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_mul_pd(a,b); }
template<> EIGEN_STRONG_INLINE Packet4i ei_pmul<Packet4i>(const Packet4i& a, const Packet4i& b)
{
+#ifdef __SSE4_1__
+ return _mm_mullo_epi32(a,b);
+#else
// this version is slightly faster than 4 scalar products
return ei_vec4i_swizzle1(
ei_vec4i_swizzle2(
@@ -126,6 +129,7 @@ template<> EIGEN_STRONG_INLINE Packet4i ei_pmul<Packet4i>(const Packet4i& a, con
ei_vec4i_swizzle1(b,1,0,3,2)),
0,2,0,2),
0,2,1,3);
+#endif
}
template<> EIGEN_STRONG_INLINE Packet4f ei_pdiv<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_div_ps(a,b); }
diff --git a/Eigen/src/Core/products/GeneralUnrolled.h b/Eigen/src/Core/products/GeneralUnrolled.h
index 7e2eebf08..f04c27a95 100644
--- a/Eigen/src/Core/products/GeneralUnrolled.h
+++ b/Eigen/src/Core/products/GeneralUnrolled.h
@@ -36,7 +36,7 @@
* Note that here the inner-loops should always be unrolled.
*/
-template<int VectorizationMode, int Index, typename Lhs, typename Rhs, typename RetScalar>
+template<int Traversal, int Index, typename Lhs, typename Rhs, typename RetScalar>
struct ei_product_coeff_impl;
template<int StorageOrder, int Index, typename Lhs, typename Rhs, typename PacketScalar, int LoadMode>
@@ -118,7 +118,7 @@ template<typename LhsNested, typename RhsNested> class GeneralProduct<LhsNested,
CanVectorizeInner = ei_traits<GeneralProduct>::CanVectorizeInner
};
- typedef ei_product_coeff_impl<CanVectorizeInner ? InnerVectorization : NoVectorization,
+ typedef ei_product_coeff_impl<CanVectorizeInner ? InnerVectorizedTraversal : DefaultTraversal,
Unroll ? InnerSize-1 : Dynamic,
_LhsNested, _RhsNested, Scalar> ScalarCoeffImpl;
@@ -185,17 +185,17 @@ template<typename LhsNested, typename RhsNested> class GeneralProduct<LhsNested,
**************************************/
template<int Index, typename Lhs, typename Rhs, typename RetScalar>
-struct ei_product_coeff_impl<NoVectorization, Index, Lhs, Rhs, RetScalar>
+struct ei_product_coeff_impl<DefaultTraversal, Index, Lhs, Rhs, RetScalar>
{
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar &res)
{
- ei_product_coeff_impl<NoVectorization, Index-1, Lhs, Rhs, RetScalar>::run(row, col, lhs, rhs, res);
+ ei_product_coeff_impl<DefaultTraversal, Index-1, Lhs, Rhs, RetScalar>::run(row, col, lhs, rhs, res);
res += lhs.coeff(row, Index) * rhs.coeff(Index, col);
}
};
template<typename Lhs, typename Rhs, typename RetScalar>
-struct ei_product_coeff_impl<NoVectorization, 0, Lhs, Rhs, RetScalar>
+struct ei_product_coeff_impl<DefaultTraversal, 0, Lhs, Rhs, RetScalar>
{
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar &res)
{
@@ -204,7 +204,7 @@ struct ei_product_coeff_impl<NoVectorization, 0, Lhs, Rhs, RetScalar>
};
template<typename Lhs, typename Rhs, typename RetScalar>
-struct ei_product_coeff_impl<NoVectorization, Dynamic, Lhs, Rhs, RetScalar>
+struct ei_product_coeff_impl<DefaultTraversal, Dynamic, Lhs, Rhs, RetScalar>
{
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar& res)
{
@@ -217,7 +217,7 @@ struct ei_product_coeff_impl<NoVectorization, Dynamic, Lhs, Rhs, RetScalar>
// prevent buggy user code from causing an infinite recursion
template<typename Lhs, typename Rhs, typename RetScalar>
-struct ei_product_coeff_impl<NoVectorization, -1, Lhs, Rhs, RetScalar>
+struct ei_product_coeff_impl<DefaultTraversal, -1, Lhs, Rhs, RetScalar>
{
EIGEN_STRONG_INLINE static void run(int, int, const Lhs&, const Rhs&, RetScalar&) {}
};
@@ -247,7 +247,7 @@ struct ei_product_coeff_vectorized_unroller<0, Lhs, Rhs, PacketScalar>
};
template<int Index, typename Lhs, typename Rhs, typename RetScalar>
-struct ei_product_coeff_impl<InnerVectorization, Index, Lhs, Rhs, RetScalar>
+struct ei_product_coeff_impl<InnerVectorizedTraversal, Index, Lhs, Rhs, RetScalar>
{
typedef typename Lhs::PacketScalar PacketScalar;
enum { PacketSize = ei_packet_traits<typename Lhs::Scalar>::size };
@@ -255,7 +255,7 @@ struct ei_product_coeff_impl<InnerVectorization, Index, Lhs, Rhs, RetScalar>
{
PacketScalar pres;
ei_product_coeff_vectorized_unroller<Index+1-PacketSize, Lhs, Rhs, PacketScalar>::run(row, col, lhs, rhs, pres);
- ei_product_coeff_impl<NoVectorization,Index,Lhs,Rhs,RetScalar>::run(row, col, lhs, rhs, res);
+ ei_product_coeff_impl<DefaultTraversal,Index,Lhs,Rhs,RetScalar>::run(row, col, lhs, rhs, res);
res = ei_predux(pres);
}
};
@@ -268,7 +268,7 @@ struct ei_product_coeff_vectorized_dyn_selector
res = ei_dot_impl<
Block<Lhs, 1, ei_traits<Lhs>::ColsAtCompileTime>,
Block<Rhs, ei_traits<Rhs>::RowsAtCompileTime, 1>,
- LinearVectorization, NoUnrolling>::run(lhs.row(row), rhs.col(col));
+ LinearVectorizedTraversal, NoUnrolling>::run(lhs.row(row), rhs.col(col));
}
};
@@ -282,7 +282,7 @@ struct ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,RhsCols>
res = ei_dot_impl<
Lhs,
Block<Rhs, ei_traits<Rhs>::RowsAtCompileTime, 1>,
- LinearVectorization, NoUnrolling>::run(lhs, rhs.col(col));
+ LinearVectorizedTraversal, NoUnrolling>::run(lhs, rhs.col(col));
}
};
@@ -294,7 +294,7 @@ struct ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs,LhsRows,1>
res = ei_dot_impl<
Block<Lhs, 1, ei_traits<Lhs>::ColsAtCompileTime>,
Rhs,
- LinearVectorization, NoUnrolling>::run(lhs.row(row), rhs);
+ LinearVectorizedTraversal, NoUnrolling>::run(lhs.row(row), rhs);
}
};
@@ -306,12 +306,12 @@ struct ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,1>
res = ei_dot_impl<
Lhs,
Rhs,
- LinearVectorization, NoUnrolling>::run(lhs, rhs);
+ LinearVectorizedTraversal, NoUnrolling>::run(lhs, rhs);
}
};
template<typename Lhs, typename Rhs, typename RetScalar>
-struct ei_product_coeff_impl<InnerVectorization, Dynamic, Lhs, Rhs, RetScalar>
+struct ei_product_coeff_impl<InnerVectorizedTraversal, Dynamic, Lhs, Rhs, RetScalar>
{
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
{
diff --git a/Eigen/src/Core/util/BlasUtil.h b/Eigen/src/Core/util/BlasUtil.h
index 94154108c..fa21ceebb 100644
--- a/Eigen/src/Core/util/BlasUtil.h
+++ b/Eigen/src/Core/util/BlasUtil.h
@@ -160,6 +160,7 @@ template<typename XprType> struct ei_blas_traits
typedef XprType _ExtractType;
enum {
IsComplex = NumTraits<Scalar>::IsComplex,
+ IsTransposed = false,
NeedToConjugate = false,
ActualAccess = int(ei_traits<XprType>::Flags)&DirectAccessBit ? HasDirectAccess : NoDirectAccess
};
@@ -214,20 +215,6 @@ struct ei_blas_traits<CwiseUnaryOp<ei_scalar_opposite_op<Scalar>, NestedXpr> >
{ return - Base::extractScalarFactor(x._expression()); }
};
-// pop NestByValue
-template<typename NestedXpr>
-struct ei_blas_traits<NestByValue<NestedXpr> >
- : ei_blas_traits<NestedXpr>
-{
- typedef typename NestedXpr::Scalar Scalar;
- typedef ei_blas_traits<NestedXpr> Base;
- typedef NestByValue<NestedXpr> XprType;
- typedef typename Base::ExtractType ExtractType;
- static inline ExtractType extract(const XprType& x) { return Base::extract(static_cast<const NestedXpr&>(x)); }
- static inline Scalar extractScalarFactor(const XprType& x)
- { return Base::extractScalarFactor(static_cast<const NestedXpr&>(x)); }
-};
-
// pop/push transpose
template<typename NestedXpr>
struct ei_blas_traits<Transpose<NestedXpr> >
@@ -241,6 +228,9 @@ struct ei_blas_traits<Transpose<NestedXpr> >
ExtractType,
typename ExtractType::PlainMatrixType
>::ret DirectLinearAccessType;
+ enum {
+ IsTransposed = Base::IsTransposed ? 0 : 1
+ };
static inline const ExtractType extract(const XprType& x) { return Base::extract(x._expression()); }
static inline Scalar extractScalarFactor(const XprType& x) { return Base::extractScalarFactor(x._expression()); }
};
diff --git a/Eigen/src/Core/util/Constants.h b/Eigen/src/Core/util/Constants.h
index beb19cdaa..8483772df 100644
--- a/Eigen/src/Core/util/Constants.h
+++ b/Eigen/src/Core/util/Constants.h
@@ -195,16 +195,19 @@ enum DirectionType { Vertical, Horizontal, BothDirections };
enum ProductEvaluationMode { NormalProduct, CacheFriendlyProduct };
enum {
+ /** \internal Default traversal, no vectorization, no index-based access */
+ DefaultTraversal,
+ /** \internal No vectorization, use index-based access to have only one for loop instead of 2 nested loops */
+ LinearTraversal,
/** \internal Equivalent to a slice vectorization for fixed-size matrices having good alignment
* and good size */
- InnerVectorization,
+ InnerVectorizedTraversal,
/** \internal Vectorization path using a single loop plus scalar loops for the
* unaligned boundaries */
- LinearVectorization,
+ LinearVectorizedTraversal,
/** \internal Generic vectorization path using one vectorized loop per row/column with some
* scalar loops to handle the unaligned boundaries */
- SliceVectorization,
- NoVectorization
+ SliceVectorizedTraversal
};
enum {
@@ -218,8 +221,7 @@ enum {
RowMajor = 0x1, // it is only a coincidence that this is equal to RowMajorBit -- don't rely on that
/** \internal Align the matrix itself if it is vectorizable fixed-size */
AutoAlign = 0,
- /** \internal Don't require alignment for the matrix itself (the array of coefficients, if dynamically allocated, may still be
- requested to be aligned) */
+ /** \internal Don't require alignment for the matrix itself (the array of coefficients, if dynamically allocated, may still be requested to be aligned) */ // FIXME --- clarify the situation
DontAlign = 0x2
};
@@ -267,19 +269,23 @@ enum TransformTraits {
Projective = 0x20
};
-const int EiArch_Generic = 0x0;
-const int EiArch_SSE = 0x1;
-const int EiArch_AltiVec = 0x2;
-
-enum DenseStorageMatrix {};
-enum DenseStorageArray {};
-
+namespace Architecture
+{
+ enum Type {
+ Generic = 0x0,
+ SSE = 0x1,
+ AltiVec = 0x2,
#if defined EIGEN_VECTORIZE_SSE
- const int EiArch = EiArch_SSE;
+ Target = SSE
#elif defined EIGEN_VECTORIZE_ALTIVEC
- const int EiArch = EiArch_AltiVec;
+ Target = AltiVec
#else
- const int EiArch = EiArch_Generic;
+ Target = Generic
#endif
+ };
+}
+
+enum DenseStorageMatrix {};
+enum DenseStorageArray {};
#endif // EIGEN_CONSTANTS_H
diff --git a/Eigen/src/Core/util/DisableMSVCWarnings.h b/Eigen/src/Core/util/DisableMSVCWarnings.h
index c08d0389f..dcc71143d 100644
--- a/Eigen/src/Core/util/DisableMSVCWarnings.h
+++ b/Eigen/src/Core/util/DisableMSVCWarnings.h
@@ -1,6 +1,9 @@
#ifdef _MSC_VER
- // 4273 - QtAlignedMalloc, inconsistent dll linkage
+ // 4273 - QtAlignedMalloc, inconsistent DLL linkage
+ // 4100 - unreferenced formal parameter (occurred e.g. in aligned_allocator::destroy(pointer p))
+ // 4101 - unreferenced local variable
+ // 4512 - assignment operator could not be generated
#pragma warning( push )
- #pragma warning( disable : 4181 4244 4127 4211 4273 4522 4717 )
+ #pragma warning( disable : 4100 4101 4181 4244 4127 4211 4273 4512 4522 4717 )
#endif
diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h
index b3a1955fb..4ea5013f7 100644
--- a/Eigen/src/Core/util/Macros.h
+++ b/Eigen/src/Core/util/Macros.h
@@ -29,8 +29,8 @@
#undef minor
#define EIGEN_WORLD_VERSION 2
-#define EIGEN_MAJOR_VERSION 90
-#define EIGEN_MINOR_VERSION 1
+#define EIGEN_MAJOR_VERSION 91
+#define EIGEN_MINOR_VERSION 0
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h
index bc5235582..524bec2fc 100644
--- a/Eigen/src/Core/util/Memory.h
+++ b/Eigen/src/Core/util/Memory.h
@@ -209,16 +209,20 @@ template<typename T, bool Align> inline void ei_conditional_aligned_delete(T *pt
ei_conditional_aligned_free<Align>(ptr);
}
-/** \internal \returns the number of elements which have to be skipped such that data are 16 bytes aligned */
-template<typename Scalar>
-inline static int ei_alignmentOffset(const Scalar* ptr, int maxOffset)
+/** \internal \returns the number of elements which have to be skipped to
+ * find the first 16-byte aligned element
+ *
+ * There is also the variant ei_alignmentOffset(const MatrixBase&, Integer) defined in Coeffs.h.
+ */
+template<typename Scalar, typename Integer>
+inline static Integer ei_alignmentOffset(const Scalar* ptr, Integer maxOffset)
{
typedef typename ei_packet_traits<Scalar>::type Packet;
- const int PacketSize = ei_packet_traits<Scalar>::size;
- const int PacketAlignedMask = PacketSize-1;
+ const Integer PacketSize = ei_packet_traits<Scalar>::size;
+ const Integer PacketAlignedMask = PacketSize-1;
const bool Vectorized = PacketSize>1;
return Vectorized
- ? std::min<int>( (PacketSize - (int((size_t(ptr)/sizeof(Scalar))) & PacketAlignedMask))
+ ? std::min<Integer>( (PacketSize - (Integer((size_t(ptr)/sizeof(Scalar))) & PacketAlignedMask))
& PacketAlignedMask, maxOffset)
: 0;
}
diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h
index 6d6540acc..6d4a5c7bc 100644
--- a/Eigen/src/Core/util/XprHelper.h
+++ b/Eigen/src/Core/util/XprHelper.h
@@ -28,10 +28,11 @@
// just a workaround because GCC seems to not really like empty structs
#ifdef __GNUG__
- struct ei_empty_struct{char _ei_dummy_;};
- #define EIGEN_EMPTY_STRUCT : Eigen::ei_empty_struct
+ #define EIGEN_EMPTY_STRUCT_CTOR(X) \
+ EIGEN_STRONG_INLINE X() {} \
+ EIGEN_STRONG_INLINE X(const X&) {}
#else
- #define EIGEN_EMPTY_STRUCT
+ #define EIGEN_EMPTY_STRUCT_CTOR(X)
#endif
//classes inheriting ei_no_assignment_operator don't generate a default operator=.
@@ -45,10 +46,10 @@ class ei_no_assignment_operator
* can be accessed using value() and setValue().
* Otherwise, this class is an empty structure and value() just returns the template parameter Value.
*/
-template<int Value> class ei_int_if_dynamic EIGEN_EMPTY_STRUCT
+template<int Value> class ei_int_if_dynamic
{
public:
- ei_int_if_dynamic() {}
+ EIGEN_EMPTY_STRUCT_CTOR(ei_int_if_dynamic)
explicit ei_int_if_dynamic(int) {}
static int value() { return Value; }
void setValue(int) {}
@@ -214,8 +215,35 @@ template<typename T> struct ei_plain_matrix_type_row_major
> type;
};
+// we should be able to get rid of this one too
template<typename T> struct ei_must_nest_by_value { enum { ret = false }; };
-template<typename T> struct ei_must_nest_by_value<NestByValue<T> > { enum { ret = true }; };
+
+/**
+* The reference selector for template expressions. The idea is that we don't
+* need to use references for expressions since they are light weight proxy
+* objects which should generate no copying overhead.
+**/
+template <typename T>
+struct ei_ref_selector
+{
+ typedef T type;
+};
+
+/**
+* Matrices on the other hand side should only be copied, when it is sure
+* we gain by copying (see arithmetic cost check and eval before nesting flag).
+* Note: This is an optimization measure that comprises potential (though little)
+* to create erroneous code. Any user, utilizing ei_nested outside of
+* Eigen needs to take care that no references to temporaries are
+* stored or that this potential danger is at least communicated
+* to the user.
+**/
+template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
+struct ei_ref_selector< Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
+{
+ typedef Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> MatrixType;
+ typedef MatrixType const& type;
+};
/** \internal Determines how a given expression should be nested into another one.
* For example, when you do a * (b+c), Eigen will determine how the expression b+c should be
@@ -241,15 +269,12 @@ template<typename T, int n=1, typename PlainMatrixType = typename ei_eval<T>::ty
CostEval = (n+1) * int(NumTraits<typename ei_traits<T>::Scalar>::ReadCost),
CostNoEval = (n-1) * int(ei_traits<T>::CoeffReadCost)
};
+
typedef typename ei_meta_if<
- ei_must_nest_by_value<T>::ret,
- T,
- typename ei_meta_if<
- (int(ei_traits<T>::Flags) & EvalBeforeNestingBit)
- || ( int(CostEval) <= int(CostNoEval) ),
+ ( int(ei_traits<T>::Flags) & EvalBeforeNestingBit ) ||
+ ( int(CostEval) <= int(CostNoEval) ),
PlainMatrixType,
- const T&
- >::ret
+ typename ei_ref_selector<T>::type
>::ret type;
};
@@ -302,7 +327,7 @@ template<typename ExpressionType> struct HNormalizedReturnType {
ei_traits<ExpressionType>::ColsAtCompileTime==1 ? SizeMinusOne : 1,
ei_traits<ExpressionType>::ColsAtCompileTime==1 ? 1 : SizeMinusOne> StartMinusOne;
typedef CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<ExpressionType>::Scalar>,
- NestByValue<StartMinusOne> > Type;
+ StartMinusOne > Type;
};
template<typename XprType, typename CastType> struct ei_cast_return_type
diff --git a/Eigen/src/Eigen2Support/Cwise.h b/Eigen/src/Eigen2Support/Cwise.h
index c8d470228..ab7056a1d 100644
--- a/Eigen/src/Eigen2Support/Cwise.h
+++ b/Eigen/src/Eigen2Support/Cwise.h
@@ -40,7 +40,7 @@
* convenient macro to defined the return type of a cwise comparison to a scalar */
#define EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(OP) \
CwiseBinaryOp<OP<typename ei_traits<ExpressionType>::Scalar>, ExpressionType, \
- NestByValue<typename ExpressionType::ConstantReturnType> >
+ typename ExpressionType::ConstantReturnType >
/** \class Cwise
*
@@ -166,9 +166,6 @@ template<typename ExpressionType> class Cwise
protected:
ExpressionTypeNested m_matrix;
-
- private:
- Cwise& operator=(const Cwise&);
};
diff --git a/Eigen/src/Eigenvalues/HessenbergDecomposition.h b/Eigen/src/Eigenvalues/HessenbergDecomposition.h
index cce76b288..9f7df49bc 100644
--- a/Eigen/src/Eigenvalues/HessenbergDecomposition.h
+++ b/Eigen/src/Eigenvalues/HessenbergDecomposition.h
@@ -58,10 +58,10 @@ template<typename _MatrixType> class HessenbergDecomposition
typedef Matrix<RealScalar, Size, 1> DiagonalType;
typedef Matrix<RealScalar, SizeMinusOne, 1> SubDiagonalType;
- typedef typename NestByValue<Diagonal<MatrixType,0> >::RealReturnType DiagonalReturnType;
+ typedef typename Diagonal<MatrixType,0>::RealReturnType DiagonalReturnType;
- typedef typename NestByValue<Diagonal<
- NestByValue<Block<MatrixType,SizeMinusOne,SizeMinusOne> >,0 > >::RealReturnType SubDiagonalReturnType;
+ typedef typename Diagonal<
+ Block<MatrixType,SizeMinusOne,SizeMinusOne>,0 >::RealReturnType SubDiagonalReturnType;
/** This constructor initializes a HessenbergDecomposition object for
* further use with HessenbergDecomposition::compute()
diff --git a/Eigen/src/Eigenvalues/Tridiagonalization.h b/Eigen/src/Eigenvalues/Tridiagonalization.h
index 04b9f72d7..d8dcfb047 100644
--- a/Eigen/src/Eigenvalues/Tridiagonalization.h
+++ b/Eigen/src/Eigenvalues/Tridiagonalization.h
@@ -61,15 +61,15 @@ template<typename _MatrixType> class Tridiagonalization
typedef Matrix<RealScalar, SizeMinusOne, 1> SubDiagonalType;
typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
- typename NestByValue<Diagonal<MatrixType,0> >::RealReturnType,
+ typename Diagonal<MatrixType,0>::RealReturnType,
Diagonal<MatrixType,0>
>::ret DiagonalReturnType;
typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
- typename NestByValue<Diagonal<
- NestByValue<Block<MatrixType,SizeMinusOne,SizeMinusOne> >,0 > >::RealReturnType,
+ typename Diagonal<
+ Block<MatrixType,SizeMinusOne,SizeMinusOne>,0 >::RealReturnType,
Diagonal<
- NestByValue<Block<MatrixType,SizeMinusOne,SizeMinusOne> >,0 >
+ Block<MatrixType,SizeMinusOne,SizeMinusOne>,0 >
>::ret SubDiagonalReturnType;
/** This constructor initializes a Tridiagonalization object for
@@ -144,7 +144,7 @@ template<typename MatrixType>
const typename Tridiagonalization<MatrixType>::DiagonalReturnType
Tridiagonalization<MatrixType>::diagonal(void) const
{
- return m_matrix.diagonal().nestByValue();
+ return m_matrix.diagonal();
}
/** \returns an expression of the sub-diagonal vector */
@@ -153,8 +153,7 @@ const typename Tridiagonalization<MatrixType>::SubDiagonalReturnType
Tridiagonalization<MatrixType>::subDiagonal(void) const
{
int n = m_matrix.rows();
- return Block<MatrixType,SizeMinusOne,SizeMinusOne>(m_matrix, 1, 0, n-1,n-1)
- .nestByValue().diagonal().nestByValue();
+ return Block<MatrixType,SizeMinusOne,SizeMinusOne>(m_matrix, 1, 0, n-1,n-1).diagonal();
}
/** constructs and returns the tridiagonal matrix T.
diff --git a/Eigen/src/Geometry/AlignedBox.h b/Eigen/src/Geometry/AlignedBox.h
index 707cfeb4f..d47adb7ab 100644
--- a/Eigen/src/Geometry/AlignedBox.h
+++ b/Eigen/src/Geometry/AlignedBox.h
@@ -171,7 +171,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
* determined by \a prec.
*
* \sa MatrixBase::isApprox() */
- bool isApprox(const AlignedBox& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
+ bool isApprox(const AlignedBox& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const
{ return m_min.isApprox(other.m_min, prec) && m_max.isApprox(other.m_max, prec); }
protected:
diff --git a/Eigen/src/Geometry/AngleAxis.h b/Eigen/src/Geometry/AngleAxis.h
index d948ea40b..da698bbfe 100644
--- a/Eigen/src/Geometry/AngleAxis.h
+++ b/Eigen/src/Geometry/AngleAxis.h
@@ -146,7 +146,7 @@ public:
* determined by \a prec.
*
* \sa MatrixBase::isApprox() */
- bool isApprox(const AngleAxis& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
+ bool isApprox(const AngleAxis& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const
{ return m_axis.isApprox(other.m_axis, prec) && ei_isApprox(m_angle,other.m_angle, prec); }
};
@@ -165,7 +165,7 @@ template<typename QuatDerived>
AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived>& q)
{
Scalar n2 = q.vec().squaredNorm();
- if (n2 < precision<Scalar>()*precision<Scalar>())
+ if (n2 < dummy_precision<Scalar>()*dummy_precision<Scalar>())
{
m_angle = 0;
m_axis << 1, 0, 0;
diff --git a/Eigen/src/Geometry/EulerAngles.h b/Eigen/src/Geometry/EulerAngles.h
index dbcc7ae89..b6dbf8ae9 100644
--- a/Eigen/src/Geometry/EulerAngles.h
+++ b/Eigen/src/Geometry/EulerAngles.h
@@ -50,7 +50,7 @@ MatrixBase<Derived>::eulerAngles(int a0, int a1, int a2) const
Matrix<Scalar,3,1> res;
typedef Matrix<typename Derived::Scalar,2,1> Vector2;
- const Scalar epsilon = precision<Scalar>();
+ const Scalar epsilon = dummy_precision<Scalar>();
const int odd = ((a0+1)%3 == a1) ? 0 : 1;
const int i = a0;
diff --git a/Eigen/src/Geometry/Homogeneous.h b/Eigen/src/Geometry/Homogeneous.h
index 6cf6a381d..a601e29cf 100644
--- a/Eigen/src/Geometry/Homogeneous.h
+++ b/Eigen/src/Geometry/Homogeneous.h
@@ -176,7 +176,7 @@ MatrixBase<Derived>::hnormalized() const
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
return StartMinusOne(derived(),0,0,
ColsAtCompileTime==1?size()-1:1,
- ColsAtCompileTime==1?1:size()-1).nestByValue() / coeff(size()-1);
+ ColsAtCompileTime==1?1:size()-1) / coeff(size()-1);
}
/** \geometry_module
@@ -193,8 +193,7 @@ VectorwiseOp<ExpressionType,Direction>::hnormalized() const
{
return HNormalized_Block(_expression(),0,0,
Direction==Vertical ? _expression().rows()-1 : _expression().rows(),
- Direction==Horizontal ? _expression().cols()-1 : _expression().cols()).nestByValue()
- .cwiseQuotient(
+ Direction==Horizontal ? _expression().cols()-1 : _expression().cols()).cwiseQuotient(
Replicate<NestByValue<HNormalized_Factors>,
Direction==Vertical ? HNormalized_SizeMinusOne : 1,
Direction==Horizontal ? HNormalized_SizeMinusOne : 1>
@@ -202,9 +201,9 @@ VectorwiseOp<ExpressionType,Direction>::hnormalized() const
Direction==Vertical ? _expression().rows()-1:0,
Direction==Horizontal ? _expression().cols()-1:0,
Direction==Vertical ? 1 : _expression().rows(),
- Direction==Horizontal ? 1 : _expression().cols()).nestByValue(),
+ Direction==Horizontal ? 1 : _expression().cols()),
Direction==Vertical ? _expression().rows()-1 : 1,
- Direction==Horizontal ? _expression().cols()-1 : 1).nestByValue());
+ Direction==Horizontal ? _expression().cols()-1 : 1));
}
template<typename MatrixType,typename Lhs>
@@ -281,7 +280,6 @@ struct ei_homogeneous_right_product_impl<Homogeneous<MatrixType,Horizontal>,Rhs>
const typename MatrixType::Nested m_lhs;
const typename Rhs::Nested m_rhs;
-
};
#endif // EIGEN_HOMOGENEOUS_H
diff --git a/Eigen/src/Geometry/Hyperplane.h b/Eigen/src/Geometry/Hyperplane.h
index ab65ca2ae..aab3d5b35 100644
--- a/Eigen/src/Geometry/Hyperplane.h
+++ b/Eigen/src/Geometry/Hyperplane.h
@@ -52,9 +52,9 @@ public:
typedef _Scalar Scalar;
typedef typename NumTraits<Scalar>::Real RealScalar;
typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType;
- typedef Matrix<Scalar,AmbientDimAtCompileTime==Dynamic
+ typedef Matrix<Scalar,int(AmbientDimAtCompileTime)==Dynamic
? Dynamic
- : AmbientDimAtCompileTime+1,1> Coefficients;
+ : int(AmbientDimAtCompileTime)+1,1> Coefficients;
typedef Block<Coefficients,AmbientDimAtCompileTime,1> NormalReturnType;
/** Default constructor without initialization */
@@ -257,7 +257,7 @@ public:
* determined by \a prec.
*
* \sa MatrixBase::isApprox() */
- bool isApprox(const Hyperplane& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
+ bool isApprox(const Hyperplane& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const
{ return m_coeffs.isApprox(other.m_coeffs, prec); }
protected:
diff --git a/Eigen/src/Geometry/OrthoMethods.h b/Eigen/src/Geometry/OrthoMethods.h
index 631b82bf5..79baeadd5 100644
--- a/Eigen/src/Geometry/OrthoMethods.h
+++ b/Eigen/src/Geometry/OrthoMethods.h
@@ -90,8 +90,9 @@ MatrixBase<Derived>::cross3(const MatrixBase<OtherDerived>& other) const
const DerivedNested lhs(derived());
const OtherDerivedNested rhs(other.derived());
- return ei_cross3_impl<EiArch,typename ei_cleantype<DerivedNested>::type,
- typename ei_cleantype<OtherDerivedNested>::type>::run(lhs,rhs);
+ return ei_cross3_impl<Architecture::Target,
+ typename ei_cleantype<DerivedNested>::type,
+ typename ei_cleantype<OtherDerivedNested>::type>::run(lhs,rhs);
}
/** \returns a matrix expression of the cross product of each column or row
diff --git a/Eigen/src/Geometry/ParametrizedLine.h b/Eigen/src/Geometry/ParametrizedLine.h
index 6a4fcb1c5..21a5595b9 100644
--- a/Eigen/src/Geometry/ParametrizedLine.h
+++ b/Eigen/src/Geometry/ParametrizedLine.h
@@ -123,7 +123,7 @@ public:
* determined by \a prec.
*
* \sa MatrixBase::isApprox() */
- bool isApprox(const ParametrizedLine& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
+ bool isApprox(const ParametrizedLine& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const
{ return m_origin.isApprox(other.m_origin, prec) && m_direction.isApprox(other.m_direction, prec); }
protected:
diff --git a/Eigen/src/Geometry/Quaternion.h b/Eigen/src/Geometry/Quaternion.h
index 660e10d1e..861eff19c 100644
--- a/Eigen/src/Geometry/Quaternion.h
+++ b/Eigen/src/Geometry/Quaternion.h
@@ -152,9 +152,9 @@ public:
/** \returns the conjugated quaternion */
Quaternion<Scalar> conjugate() const;
- /** \returns an interpolation for a constant motion between \a other and \c *this
+ /** \returns an interpolation for a constant motion between \a other and \c *this
* \a t in [0;1]
- * see http://en.wikipedia.org/wiki/Slerp
+ * see http://en.wikipedia.org/wiki/Slerp
*/
template<class OtherDerived> Quaternion<Scalar> slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const;
@@ -163,7 +163,7 @@ public:
*
* \sa MatrixBase::isApprox() */
template<class OtherDerived>
- bool isApprox(const QuaternionBase<OtherDerived>& other, RealScalar prec = precision<Scalar>()) const
+ bool isApprox(const QuaternionBase<OtherDerived>& other, RealScalar prec = dummy_precision<Scalar>()) const
{ return coeffs().isApprox(other.coeffs(), prec); }
/** return the result vector of \a v through the rotation*/
@@ -221,7 +221,7 @@ struct ei_traits<Quaternion<_Scalar> >
template<typename _Scalar>
class Quaternion : public QuaternionBase<Quaternion<_Scalar> >{
typedef QuaternionBase<Quaternion<_Scalar> > Base;
-public:
+public:
typedef _Scalar Scalar;
EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Quaternion<Scalar>)
@@ -304,27 +304,20 @@ template<typename _Scalar, int PacketAccess>
class Map<Quaternion<_Scalar>, PacketAccess >
: public QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> >
{
- public:
- typedef _Scalar Scalar;
- typedef Map<Quaternion<Scalar>, PacketAccess > MapQuat;
-
- private:
- Map<Quaternion<Scalar>, PacketAccess >();
- Map<Quaternion<Scalar>, PacketAccess >(const Map<Quaternion<Scalar>, PacketAccess>&);
-
typedef QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> > Base;
+
public:
- EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(MapQuat)
+ typedef _Scalar Scalar;
+ typedef typename ei_traits<Map>::Coefficients Coefficients;
+ EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Map)
using Base::operator*=;
- typedef typename ei_traits<Map<Quaternion<Scalar>, PacketAccess> >::Coefficients Coefficients;
-
/** Constructs a Mapped Quaternion object from the pointer \a coeffs
*
* The pointer \a coeffs must reference the four coeffecients of Quaternion in the following order:
* \code *coeffs == {x, y, z, w} \endcode
*
- * If the template paramter PacketAccess is set to Aligned, then the pointer coeffs must be aligned. */
+ * If the template parameter PacketAccess is set to Aligned, then the pointer coeffs must be aligned. */
EIGEN_STRONG_INLINE Map(const Scalar* coeffs) : m_coeffs(coeffs) {}
inline Coefficients& coeffs() { return m_coeffs;}
@@ -374,7 +367,7 @@ QuaternionBase<Derived>::operator* (const QuaternionBase<OtherDerived>& other) c
{
EIGEN_STATIC_ASSERT((ei_is_same_type<typename Derived::Scalar, typename OtherDerived::Scalar>::ret),
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
- return ei_quat_product<EiArch, Derived, OtherDerived,
+ return ei_quat_product<Architecture::Target, Derived, OtherDerived,
typename ei_traits<Derived>::Scalar,
ei_traits<Derived>::PacketAccess && ei_traits<OtherDerived>::PacketAccess>::run(*this, other);
}
@@ -514,7 +507,7 @@ inline Derived& QuaternionBase<Derived>::setFromTwoVectors(const MatrixBase<Deri
// under the constraint:
// ||x|| = 1
// which yields a singular value problem
- if (c < Scalar(-1)+precision<Scalar>())
+ if (c < Scalar(-1)+dummy_precision<Scalar>())
{
c = std::max<Scalar>(c,-1);
Matrix<Scalar,2,3> m; m << v0.transpose(), v1.transpose();
@@ -590,20 +583,29 @@ template <class OtherDerived>
Quaternion<typename ei_traits<Derived>::Scalar>
QuaternionBase<Derived>::slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const
{
- static const Scalar one = Scalar(1) - precision<Scalar>();
+ static const Scalar one = Scalar(1) - epsilon<Scalar>();
Scalar d = this->dot(other);
Scalar absD = ei_abs(d);
- if (absD>=one)
- return Quaternion<Scalar>(derived());
- // theta is the angle between the 2 quaternions
- Scalar theta = std::acos(absD);
- Scalar sinTheta = ei_sin(theta);
+ Scalar scale0;
+ Scalar scale1;
- Scalar scale0 = ei_sin( ( Scalar(1) - t ) * theta) / sinTheta;
- Scalar scale1 = ei_sin( ( t * theta) ) / sinTheta;
- if (d<0)
- scale1 = -scale1;
+ if (absD>=one)
+ {
+ scale0 = Scalar(1) - t;
+ scale1 = t;
+ }
+ else
+ {
+ // theta is the angle between the 2 quaternions
+ Scalar theta = std::acos(absD);
+ Scalar sinTheta = ei_sin(theta);
+
+ scale0 = ei_sin( ( Scalar(1) - t ) * theta) / sinTheta;
+ scale1 = ei_sin( ( t * theta) ) / sinTheta;
+ if (d<0)
+ scale1 = -scale1;
+ }
return Quaternion<Scalar>(scale0 * coeffs() + scale1 * other.coeffs());
}
diff --git a/Eigen/src/Geometry/Rotation2D.h b/Eigen/src/Geometry/Rotation2D.h
index b80fcace0..7f24a3eae 100644
--- a/Eigen/src/Geometry/Rotation2D.h
+++ b/Eigen/src/Geometry/Rotation2D.h
@@ -121,7 +121,7 @@ public:
* determined by \a prec.
*
* \sa MatrixBase::isApprox() */
- bool isApprox(const Rotation2D& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
+ bool isApprox(const Rotation2D& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const
{ return ei_isApprox(m_angle,other.m_angle, prec); }
};
diff --git a/Eigen/src/Geometry/Scaling.h b/Eigen/src/Geometry/Scaling.h
index ce191b5da..4695914fd 100644
--- a/Eigen/src/Geometry/Scaling.h
+++ b/Eigen/src/Geometry/Scaling.h
@@ -107,7 +107,7 @@ public:
* determined by \a prec.
*
* \sa MatrixBase::isApprox() */
- bool isApprox(const UniformScaling& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
+ bool isApprox(const UniformScaling& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const
{ return ei_isApprox(m_factor, other.factor(), prec); }
};
diff --git a/Eigen/src/Geometry/Transform.h b/Eigen/src/Geometry/Transform.h
index cf961b98b..89df73505 100644
--- a/Eigen/src/Geometry/Transform.h
+++ b/Eigen/src/Geometry/Transform.h
@@ -187,7 +187,7 @@ public:
/** type of read/write reference to the affine part of the transformation */
typedef typename ei_meta_if<int(Mode)==int(AffineCompact),
MatrixType&,
- NestByValue<Block<MatrixType,Dim,HDim> > >::ret AffinePartNested;
+ Block<MatrixType,Dim,HDim> >::ret AffinePartNested;
/** type of a vector */
typedef Matrix<Scalar,Dim,1> VectorType;
/** type of a read/write reference to the translation part of the rotation */
@@ -424,7 +424,7 @@ public:
* determined by \a prec.
*
* \sa MatrixBase::isApprox() */
- bool isApprox(const Transform& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
+ bool isApprox(const Transform& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const
{ return m_matrix.isApprox(other.m_matrix, prec); }
/** Sets the last row to [0 ... 0 1]
diff --git a/Eigen/src/Geometry/Translation.h b/Eigen/src/Geometry/Translation.h
index 1fff03810..b7477df9f 100644
--- a/Eigen/src/Geometry/Translation.h
+++ b/Eigen/src/Geometry/Translation.h
@@ -154,7 +154,7 @@ public:
* determined by \a prec.
*
* \sa MatrixBase::isApprox() */
- bool isApprox(const Translation& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
+ bool isApprox(const Translation& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const
{ return m_coeffs.isApprox(other.m_coeffs, prec); }
};
diff --git a/Eigen/src/Geometry/arch/Geometry_SSE.h b/Eigen/src/Geometry/arch/Geometry_SSE.h
index a6ed10d82..297932f92 100644
--- a/Eigen/src/Geometry/arch/Geometry_SSE.h
+++ b/Eigen/src/Geometry/arch/Geometry_SSE.h
@@ -26,7 +26,8 @@
#ifndef EIGEN_GEOMETRY_SSE_H
#define EIGEN_GEOMETRY_SSE_H
-template<class Derived, class OtherDerived> struct ei_quat_product<EiArch_SSE, Derived, OtherDerived, float, Aligned>
+template<class Derived, class OtherDerived>
+struct ei_quat_product<Architecture::SSE, Derived, OtherDerived, float, Aligned>
{
inline static Quaternion<float> run(const QuaternionBase<Derived>& _a, const QuaternionBase<OtherDerived>& _b)
{
@@ -48,7 +49,8 @@ template<class Derived, class OtherDerived> struct ei_quat_product<EiArch_SSE, D
};
template<typename VectorLhs,typename VectorRhs>
-struct ei_cross3_impl<EiArch_SSE,VectorLhs,VectorRhs,float,true> {
+struct ei_cross3_impl<Architecture::SSE,VectorLhs,VectorRhs,float,true>
+{
inline static typename ei_plain_matrix_type<VectorLhs>::type
run(const VectorLhs& lhs, const VectorRhs& rhs)
{
diff --git a/Eigen/src/Householder/HouseholderSequence.h b/Eigen/src/Householder/HouseholderSequence.h
index 85aa90362..25e962001 100644
--- a/Eigen/src/Householder/HouseholderSequence.h
+++ b/Eigen/src/Householder/HouseholderSequence.h
@@ -73,27 +73,31 @@ template<typename VectorsType, typename CoeffsType> class HouseholderSequence
CoeffsType>::ret> ConjugateReturnType;
HouseholderSequence(const VectorsType& v, const CoeffsType& h, bool trans = false)
- : m_vectors(v), m_coeffs(h), m_trans(trans)
+ : m_vectors(v), m_coeffs(h), m_trans(trans), m_actualVectors(v.diagonalSize())
+ {}
+
+ HouseholderSequence(const VectorsType& v, const CoeffsType& h, bool trans, int actualVectors)
+ : m_vectors(v), m_coeffs(h), m_trans(trans), m_actualVectors(actualVectors)
{}
int rows() const { return m_vectors.rows(); }
int cols() const { return m_vectors.rows(); }
HouseholderSequence transpose() const
- { return HouseholderSequence(m_vectors, m_coeffs, !m_trans); }
+ { return HouseholderSequence(m_vectors, m_coeffs, !m_trans, m_actualVectors); }
ConjugateReturnType conjugate() const
- { return ConjugateReturnType(m_vectors, m_coeffs.conjugate(), m_trans); }
+ { return ConjugateReturnType(m_vectors, m_coeffs.conjugate(), m_trans, m_actualVectors); }
ConjugateReturnType adjoint() const
- { return ConjugateReturnType(m_vectors, m_coeffs.conjugate(), !m_trans); }
+ { return ConjugateReturnType(m_vectors, m_coeffs.conjugate(), !m_trans, m_actualVectors); }
ConjugateReturnType inverse() const { return adjoint(); }
/** \internal */
template<typename DestType> void evalTo(DestType& dst) const
{
- int vecs = std::min(m_vectors.cols(),m_vectors.rows());
+ int vecs = m_actualVectors;
int length = m_vectors.rows();
dst.setIdentity();
Matrix<Scalar,1,DestType::RowsAtCompileTime> temp(dst.rows());
@@ -111,22 +115,22 @@ template<typename VectorsType, typename CoeffsType> class HouseholderSequence
/** \internal */
template<typename Dest> inline void applyThisOnTheRight(Dest& dst) const
{
- int vecs = std::min(m_vectors.cols(),m_vectors.rows()); // number of householder vectors
- int length = m_vectors.rows(); // size of the largest householder vector
- Matrix<Scalar,1,Dest::ColsAtCompileTime> temp(dst.rows());
+ int vecs = m_actualVectors; // number of householder vectors
+ int length = m_vectors.rows(); // size of the largest householder vector
+ Matrix<Scalar,1,Dest::RowsAtCompileTime> temp(dst.rows());
for(int k = 0; k < vecs; ++k)
{
int actual_k = m_trans ? vecs-k-1 : k;
- dst.corner(BottomRight, dst.rows(), length-k)
- .applyHouseholderOnTheRight(m_vectors.col(k).end(length-k-1), m_coeffs.coeff(k), &temp.coeffRef(0));
+ dst.corner(BottomRight, dst.rows(), length-actual_k)
+ .applyHouseholderOnTheRight(m_vectors.col(actual_k).end(length-actual_k-1), m_coeffs.coeff(actual_k), &temp.coeffRef(0));
}
}
/** \internal */
template<typename Dest> inline void applyThisOnTheLeft(Dest& dst) const
{
- int vecs = std::min(m_vectors.cols(),m_vectors.rows()); // number of householder vectors
- int length = m_vectors.rows(); // size of the largest householder vector
+ int vecs = m_actualVectors; // number of householder vectors
+ int length = m_vectors.rows(); // size of the largest householder vector
Matrix<Scalar,1,Dest::ColsAtCompileTime> temp(dst.cols());
for(int k = 0; k < vecs; ++k)
{
@@ -156,9 +160,7 @@ template<typename VectorsType, typename CoeffsType> class HouseholderSequence
typename VectorsType::Nested m_vectors;
typename CoeffsType::Nested m_coeffs;
bool m_trans;
-
-private:
- HouseholderSequence& operator=(const HouseholderSequence&);
+ int m_actualVectors;
};
template<typename VectorsType, typename CoeffsType>
@@ -167,4 +169,10 @@ HouseholderSequence<VectorsType,CoeffsType> householderSequence(const VectorsTyp
return HouseholderSequence<VectorsType,CoeffsType>(v, h, trans);
}
+template<typename VectorsType, typename CoeffsType>
+HouseholderSequence<VectorsType,CoeffsType> householderSequence(const VectorsType& v, const CoeffsType& h, bool trans, int actualVectors)
+{
+ return HouseholderSequence<VectorsType,CoeffsType>(v, h, trans, actualVectors);
+}
+
#endif // EIGEN_HOUSEHOLDER_SEQUENCE_H
diff --git a/Eigen/src/LU/CMakeLists.txt b/Eigen/src/LU/CMakeLists.txt
index 2788595b0..e0d8d78c1 100644
--- a/Eigen/src/LU/CMakeLists.txt
+++ b/Eigen/src/LU/CMakeLists.txt
@@ -4,3 +4,5 @@ INSTALL(FILES
${Eigen_LU_SRCS}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/LU COMPONENT Devel
)
+
+ADD_SUBDIRECTORY(arch)
diff --git a/Eigen/src/LU/Determinant.h b/Eigen/src/LU/Determinant.h
index 8870d9f20..27ad6abe9 100644
--- a/Eigen/src/LU/Determinant.h
+++ b/Eigen/src/LU/Determinant.h
@@ -118,7 +118,9 @@ template<typename Derived>
inline typename ei_traits<Derived>::Scalar MatrixBase<Derived>::determinant() const
{
assert(rows() == cols());
- return ei_determinant_impl<Derived>::run(derived());
+ typedef typename ei_nested<Derived,RowsAtCompileTime>::type Nested;
+ Nested nested(derived());
+ return ei_determinant_impl<typename ei_cleantype<Nested>::type>::run(nested);
}
#endif // EIGEN_DETERMINANT_H
diff --git a/Eigen/src/LU/FullPivLU.h b/Eigen/src/LU/FullPivLU.h
index 89eec38c7..149af64bc 100644
--- a/Eigen/src/LU/FullPivLU.h
+++ b/Eigen/src/LU/FullPivLU.h
@@ -14,7 +14,7 @@
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
@@ -63,8 +63,8 @@ template<typename _MatrixType> class FullPivLU
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
- typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;
- typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType;
+ typedef PermutationMatrix<MatrixType::ColsAtCompileTime> PermutationQType;
+ typedef PermutationMatrix<MatrixType::RowsAtCompileTime> PermutationPType;
/**
* \brief Default Constructor.
@@ -119,26 +119,22 @@ template<typename _MatrixType> class FullPivLU
* diagonal coefficient of U.
*/
RealScalar maxPivot() const { return m_maxpivot; }
-
- /** \returns a vector of integers, whose size is the number of rows of the matrix being decomposed,
- * representing the P permutation i.e. the permutation of the rows. For its precise meaning,
- * see the examples given in the documentation of class FullPivLU.
+
+ /** \returns the permutation matrix P
*
* \sa permutationQ()
*/
- inline const IntColVectorType& permutationP() const
+ inline const PermutationPType& permutationP() const
{
ei_assert(m_isInitialized && "LU is not initialized.");
return m_p;
}
- /** \returns a vector of integers, whose size is the number of columns of the matrix being
- * decomposed, representing the Q permutation i.e. the permutation of the columns.
- * For its precise meaning, see the examples given in the documentation of class FullPivLU.
+ /** \returns the permutation matrix Q
*
* \sa permutationP()
*/
- inline const IntRowVectorType& permutationQ() const
+ inline const PermutationQType& permutationQ() const
{
ei_assert(m_isInitialized && "LU is not initialized.");
return m_q;
@@ -238,8 +234,9 @@ template<typename _MatrixType> class FullPivLU
* who need to determine when pivots are to be considered nonzero. This is not used for the
* LU decomposition itself.
*
- * When it needs to get the threshold value, Eigen calls threshold(). By default, this calls
- * defaultThreshold(). Once you have called the present method setThreshold(const RealScalar&),
+ * When it needs to get the threshold value, Eigen calls threshold(). By default, this
+ * uses a formula to automatically determine a reasonable threshold.
+ * Once you have called the present method setThreshold(const RealScalar&),
* your value is used instead.
*
* \param threshold The new value to use as the threshold.
@@ -307,7 +304,7 @@ template<typename _MatrixType> class FullPivLU
inline int dimensionOfKernel() const
{
ei_assert(m_isInitialized && "LU is not initialized.");
- return m_lu.cols() - rank();
+ return cols() - rank();
}
/** \returns true if the matrix of which *this is the LU decomposition represents an injective
@@ -320,7 +317,7 @@ template<typename _MatrixType> class FullPivLU
inline bool isInjective() const
{
ei_assert(m_isInitialized && "LU is not initialized.");
- return rank() == m_lu.cols();
+ return rank() == cols();
}
/** \returns true if the matrix of which *this is the LU decomposition represents a surjective
@@ -333,7 +330,7 @@ template<typename _MatrixType> class FullPivLU
inline bool isSurjective() const
{
ei_assert(m_isInitialized && "LU is not initialized.");
- return rank() == m_lu.rows();
+ return rank() == rows();
}
/** \returns true if the matrix of which *this is the LU decomposition is invertible.
@@ -355,12 +352,12 @@ template<typename _MatrixType> class FullPivLU
*
* \sa MatrixBase::inverse()
*/
- inline const ei_solve_retval<FullPivLU,NestByValue<typename MatrixType::IdentityReturnType> > inverse() const
+ inline const ei_solve_retval<FullPivLU,typename MatrixType::IdentityReturnType> inverse() const
{
ei_assert(m_isInitialized && "LU is not initialized.");
ei_assert(m_lu.rows() == m_lu.cols() && "You can't take the inverse of a non-square matrix!");
- return ei_solve_retval<FullPivLU,NestByValue<typename MatrixType::IdentityReturnType> >
- (*this, MatrixType::Identity(m_lu.rows(), m_lu.cols()).nestByValue());
+ return ei_solve_retval<FullPivLU,typename MatrixType::IdentityReturnType>
+ (*this, MatrixType::Identity(m_lu.rows(), m_lu.cols()));
}
inline int rows() const { return m_lu.rows(); }
@@ -368,8 +365,8 @@ template<typename _MatrixType> class FullPivLU
protected:
MatrixType m_lu;
- IntColVectorType m_p;
- IntRowVectorType m_q;
+ PermutationPType m_p;
+ PermutationQType m_q;
int m_det_pq, m_nonzero_pivots;
RealScalar m_maxpivot, m_prescribedThreshold;
bool m_isInitialized, m_usePrescribedThreshold;
@@ -393,8 +390,6 @@ FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix)
{
m_isInitialized = true;
m_lu = matrix;
- m_p.resize(matrix.rows());
- m_q.resize(matrix.cols());
const int size = matrix.diagonalSize();
const int rows = matrix.rows();
@@ -408,6 +403,7 @@ FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix)
m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
m_maxpivot = RealScalar(0);
+
for(int k = 0; k < size; ++k)
{
// First, we need to find the pivot.
@@ -424,10 +420,10 @@ FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix)
// if the pivot (hence the corner) is exactly zero, terminate to avoid generating nan/inf values
if(biggest_in_corner == RealScalar(0))
{
- // before exiting, make sure to initialize the still uninitialized row_transpositions
+ // before exiting, make sure to initialize the still uninitialized transpositions
// in a sane state without destroying what we already have.
m_nonzero_pivots = k;
- for(int i = k; i < size; i++)
+ for(int i = k; i < size; ++i)
{
rows_transpositions.coeffRef(i) = i;
cols_transpositions.coeffRef(i) = i;
@@ -463,13 +459,13 @@ FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix)
// the main loop is over, we still have to accumulate the transpositions to find the
// permutations P and Q
- for(int k = 0; k < matrix.rows(); ++k) m_p.coeffRef(k) = k;
+ m_p.setIdentity(rows);
for(int k = size-1; k >= 0; --k)
- std::swap(m_p.coeffRef(k), m_p.coeffRef(rows_transpositions.coeff(k)));
+ m_p.applyTranspositionOnTheRight(k, rows_transpositions.coeff(k));
- for(int k = 0; k < matrix.cols(); ++k) m_q.coeffRef(k) = k;
+ m_q.setIdentity(cols);
for(int k = 0; k < size; ++k)
- std::swap(m_q.coeffRef(k), m_q.coeffRef(cols_transpositions.coeff(k)));
+ m_q.applyTranspositionOnTheRight(k, cols_transpositions.coeff(k));
m_det_pq = (number_of_transpositions%2) ? -1 : 1;
return *this;
@@ -562,9 +558,9 @@ struct ei_kernel_retval<FullPivLU<_MatrixType> >
m.col(i).swap(m.col(pivots.coeff(i)));
// see the negative sign in the next line, that's what we were talking about above.
- for(int i = 0; i < rank(); ++i) dst.row(dec().permutationQ().coeff(i)) = -m.row(i).end(dimker);
- for(int i = rank(); i < cols; ++i) dst.row(dec().permutationQ().coeff(i)).setZero();
- for(int k = 0; k < dimker; ++k) dst.coeffRef(dec().permutationQ().coeff(rank()+k), k) = Scalar(1);
+ for(int i = 0; i < rank(); ++i) dst.row(dec().permutationQ().indices().coeff(i)) = -m.row(i).end(dimker);
+ for(int i = rank(); i < cols; ++i) dst.row(dec().permutationQ().indices().coeff(i)).setZero();
+ for(int k = 0; k < dimker; ++k) dst.coeffRef(dec().permutationQ().indices().coeff(rank()+k), k) = Scalar(1);
}
};
@@ -601,7 +597,7 @@ struct ei_image_retval<FullPivLU<_MatrixType> >
ei_internal_assert(p == rank());
for(int i = 0; i < rank(); ++i)
- dst.col(i) = originalMatrix().col(dec().permutationQ().coeff(pivots.coeff(i)));
+ dst.col(i) = originalMatrix().col(dec().permutationQ().indices().coeff(pivots.coeff(i)));
}
};
@@ -623,7 +619,7 @@ struct ei_solve_retval<FullPivLU<_MatrixType>, Rhs>
* Step 4: result = Q * c;
*/
- const int rows = dec().matrixLU().rows(), cols = dec().matrixLU().cols(),
+ const int rows = dec().rows(), cols = dec().cols(),
nonzero_pivots = dec().nonzeroPivots();
ei_assert(rhs().rows() == rows);
const int smalldim = std::min(rows, cols);
@@ -637,8 +633,7 @@ struct ei_solve_retval<FullPivLU<_MatrixType>, Rhs>
typename Rhs::PlainMatrixType c(rhs().rows(), rhs().cols());
// Step 1
- for(int i = 0; i < rows; ++i)
- c.row(dec().permutationP().coeff(i)) = rhs().row(i);
+ c = dec().permutationP() * rhs();
// Step 2
dec().matrixLU()
@@ -660,9 +655,9 @@ struct ei_solve_retval<FullPivLU<_MatrixType>, Rhs>
// Step 4
for(int i = 0; i < nonzero_pivots; ++i)
- dst.row(dec().permutationQ().coeff(i)) = c.row(i);
+ dst.row(dec().permutationQ().indices().coeff(i)) = c.row(i);
for(int i = nonzero_pivots; i < dec().matrixLU().cols(); ++i)
- dst.row(dec().permutationQ().coeff(i)).setZero();
+ dst.row(dec().permutationQ().indices().coeff(i)).setZero();
}
};
diff --git a/Eigen/src/LU/Inverse.h b/Eigen/src/LU/Inverse.h
index 13de19ace..ea2330da3 100644
--- a/Eigen/src/LU/Inverse.h
+++ b/Eigen/src/LU/Inverse.h
@@ -182,91 +182,37 @@ struct ei_compute_inverse_and_det_with_check<MatrixType, ResultType, 3>
*** Size 4 implementation ***
****************************/
-template<typename MatrixType, typename ResultType>
-void ei_compute_inverse_size4_helper(const MatrixType& matrix, ResultType& result)
+template<int Arch, typename Scalar, typename MatrixType, typename ResultType>
+struct ei_compute_inverse_size4
{
- /* Let's split M into four 2x2 blocks:
- * (P Q)
- * (R S)
- * If P is invertible, with inverse denoted by P_inverse, and if
- * (S - R*P_inverse*Q) is also invertible, then the inverse of M is
- * (P' Q')
- * (R' S')
- * where
- * S' = (S - R*P_inverse*Q)^(-1)
- * P' = P1 + (P1*Q) * S' *(R*P_inverse)
- * Q' = -(P_inverse*Q) * S'
- * R' = -S' * (R*P_inverse)
- */
- typedef Block<ResultType,2,2> XprBlock22;
- typedef typename MatrixBase<XprBlock22>::PlainMatrixType Block22;
- Block22 P_inverse;
- ei_compute_inverse<XprBlock22, Block22>::run(matrix.template block<2,2>(0,0), P_inverse);
- const Block22 Q = matrix.template block<2,2>(0,2);
- const Block22 P_inverse_times_Q = P_inverse * Q;
- const XprBlock22 R = matrix.template block<2,2>(2,0);
- const Block22 R_times_P_inverse = R * P_inverse;
- const Block22 R_times_P_inverse_times_Q = R_times_P_inverse * Q;
- const XprBlock22 S = matrix.template block<2,2>(2,2);
- const Block22 X = S - R_times_P_inverse_times_Q;
- Block22 Y;
- ei_compute_inverse<Block22, Block22>::run(X, Y);
- result.template block<2,2>(2,2) = Y;
- result.template block<2,2>(2,0) = - Y * R_times_P_inverse;
- const Block22 Z = P_inverse_times_Q * Y;
- result.template block<2,2>(0,2) = - Z;
- result.template block<2,2>(0,0) = P_inverse + Z * R_times_P_inverse;
-}
+ static void run(const MatrixType& matrix, ResultType& result)
+ {
+ result.coeffRef(0,0) = matrix.minor(0,0).determinant();
+ result.coeffRef(1,0) = -matrix.minor(0,1).determinant();
+ result.coeffRef(2,0) = matrix.minor(0,2).determinant();
+ result.coeffRef(3,0) = -matrix.minor(0,3).determinant();
+ result.coeffRef(0,2) = matrix.minor(2,0).determinant();
+ result.coeffRef(1,2) = -matrix.minor(2,1).determinant();
+ result.coeffRef(2,2) = matrix.minor(2,2).determinant();
+ result.coeffRef(3,2) = -matrix.minor(2,3).determinant();
+ result.coeffRef(0,1) = -matrix.minor(1,0).determinant();
+ result.coeffRef(1,1) = matrix.minor(1,1).determinant();
+ result.coeffRef(2,1) = -matrix.minor(1,2).determinant();
+ result.coeffRef(3,1) = matrix.minor(1,3).determinant();
+ result.coeffRef(0,3) = -matrix.minor(3,0).determinant();
+ result.coeffRef(1,3) = matrix.minor(3,1).determinant();
+ result.coeffRef(2,3) = -matrix.minor(3,2).determinant();
+ result.coeffRef(3,3) = matrix.minor(3,3).determinant();
+ result /= (matrix.col(0).cwise()*result.row(0).transpose()).sum();
+ }
+};
template<typename MatrixType, typename ResultType>
struct ei_compute_inverse<MatrixType, ResultType, 4>
+ : ei_compute_inverse_size4<Architecture::Target, typename MatrixType::Scalar,
+ MatrixType, ResultType>
{
- static inline void run(const MatrixType& _matrix, ResultType& result)
- {
- typedef typename ResultType::Scalar Scalar;
- typedef typename MatrixType::RealScalar RealScalar;
-
- // we will do row permutations on the matrix. This copy should have negligible cost.
- // if not, consider working in-place on the matrix (const-cast it, but then undo the permutations
- // to nevertheless honor constness)
- typename MatrixType::PlainMatrixType matrix(_matrix);
-
- // let's extract from the 2 first colums a 2x2 block whose determinant is as big as possible.
- int good_row0, good_row1, good_i;
- Matrix<RealScalar,6,1> absdet;
-
- // any 2x2 block with determinant above this threshold will be considered good enough
- RealScalar d = (matrix.col(0).squaredNorm()+matrix.col(1).squaredNorm()) * RealScalar(1e-2);
- #define ei_inv_size4_helper_macro(i,row0,row1) \
- absdet[i] = ei_abs(matrix.coeff(row0,0)*matrix.coeff(row1,1) \
- - matrix.coeff(row0,1)*matrix.coeff(row1,0)); \
- if(absdet[i] > d) { good_row0=row0; good_row1=row1; goto good; }
- ei_inv_size4_helper_macro(0,0,1)
- ei_inv_size4_helper_macro(1,0,2)
- ei_inv_size4_helper_macro(2,0,3)
- ei_inv_size4_helper_macro(3,1,2)
- ei_inv_size4_helper_macro(4,1,3)
- ei_inv_size4_helper_macro(5,2,3)
-
- // no 2x2 block has determinant bigger than the threshold. So just take the one that
- // has the biggest determinant
- absdet.maxCoeff(&good_i);
- good_row0 = good_i <= 2 ? 0 : good_i <= 4 ? 1 : 2;
- good_row1 = good_i <= 2 ? good_i+1 : good_i <= 4 ? good_i-1 : 3;
-
- // now good_row0 and good_row1 are correctly set
- good:
-
- // do row permutations to move this 2x2 block to the top
- matrix.row(0).swap(matrix.row(good_row0));
- matrix.row(1).swap(matrix.row(good_row1));
- // now applying our helper function is numerically stable
- ei_compute_inverse_size4_helper(matrix, result);
- // Since we did row permutations on the original matrix, we need to do column permutations
- // in the reverse order on the inverse
- result.col(1).swap(result.col(good_row1));
- result.col(0).swap(result.col(good_row0));
- }
+ // FIXME empty?
};
template<typename MatrixType, typename ResultType>
@@ -300,7 +246,8 @@ template<typename MatrixType>
struct ei_inverse_impl : public ReturnByValue<ei_inverse_impl<MatrixType> >
{
// for 2x2, it's worth giving a chance to avoid evaluating.
- // for larger sizes, evaluating has negligible cost and limits code size.
+ // for larger sizes, evaluating has negligible cost, limits code size,
+ // and allows for vectorized paths.
typedef typename ei_meta_if<
MatrixType::RowsAtCompileTime == 2,
typename ei_nested<MatrixType,2>::type,
@@ -326,7 +273,7 @@ struct ei_inverse_impl : public ReturnByValue<ei_inverse_impl<MatrixType> >
*
* \returns the matrix inverse of this matrix.
*
- * For small fixed sizes up to 4x4, this method uses ad-hoc methods (cofactors up to 3x3, Euler's trick for 4x4).
+ * For small fixed sizes up to 4x4, this method uses cofactors.
* In the general case, this method uses class PartialPivLU.
*
* \note This matrix must be invertible, otherwise the result is undefined. If you need an
diff --git a/Eigen/src/LU/PartialPivLU.h b/Eigen/src/LU/PartialPivLU.h
index 37cffd7a1..deb29b5c6 100644
--- a/Eigen/src/LU/PartialPivLU.h
+++ b/Eigen/src/LU/PartialPivLU.h
@@ -64,10 +64,8 @@ template<typename _MatrixType> class PartialPivLU
typedef _MatrixType MatrixType;
typedef typename MatrixType::Scalar Scalar;
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
- typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
- typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
- typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;
- typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType;
+ typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> PermutationVectorType;
+ typedef PermutationMatrix<MatrixType::RowsAtCompileTime> PermutationType;
enum { MaxSmallDimAtCompileTime = EIGEN_ENUM_MIN(
MatrixType::MaxColsAtCompileTime,
@@ -105,11 +103,9 @@ template<typename _MatrixType> class PartialPivLU
return m_lu;
}
- /** \returns a vector of integers, whose size is the number of rows of the matrix being decomposed,
- * representing the P permutation i.e. the permutation of the rows. For its precise meaning,
- * see the examples given in the documentation of class FullPivLU.
+ /** \returns the permutation matrix P.
*/
- inline const IntColVectorType& permutationP() const
+ inline const PermutationType& permutationP() const
{
ei_assert(m_isInitialized && "PartialPivLU is not initialized.");
return m_p;
@@ -147,11 +143,11 @@ template<typename _MatrixType> class PartialPivLU
*
* \sa MatrixBase::inverse(), LU::inverse()
*/
- inline const ei_solve_retval<PartialPivLU,NestByValue<typename MatrixType::IdentityReturnType> > inverse() const
+ inline const ei_solve_retval<PartialPivLU,typename MatrixType::IdentityReturnType> inverse() const
{
ei_assert(m_isInitialized && "PartialPivLU is not initialized.");
- return ei_solve_retval<PartialPivLU,NestByValue<typename MatrixType::IdentityReturnType> >
- (*this, MatrixType::Identity(m_lu.rows(), m_lu.cols()).nestByValue());
+ return ei_solve_retval<PartialPivLU,typename MatrixType::IdentityReturnType>
+ (*this, MatrixType::Identity(m_lu.rows(), m_lu.cols()));
}
/** \returns the determinant of the matrix of which
@@ -174,7 +170,7 @@ template<typename _MatrixType> class PartialPivLU
protected:
MatrixType m_lu;
- IntColVectorType m_p;
+ PermutationType m_p;
int m_det_p;
bool m_isInitialized;
};
@@ -379,20 +375,19 @@ template<typename MatrixType>
PartialPivLU<MatrixType>& PartialPivLU<MatrixType>::compute(const MatrixType& matrix)
{
m_lu = matrix;
- m_p.resize(matrix.rows());
ei_assert(matrix.rows() == matrix.cols() && "PartialPivLU is only for square (and moreover invertible) matrices");
const int size = matrix.rows();
- IntColVectorType rows_transpositions(size);
+ PermutationVectorType rows_transpositions(size);
int nb_transpositions;
ei_partial_lu_inplace(m_lu, rows_transpositions, nb_transpositions);
m_det_p = (nb_transpositions%2) ? -1 : 1;
- for(int k = 0; k < size; ++k) m_p.coeffRef(k) = k;
+ m_p.setIdentity(size);
for(int k = size-1; k >= 0; --k)
- std::swap(m_p.coeffRef(k), m_p.coeffRef(rows_transpositions.coeff(k)));
+ m_p.applyTranspositionOnTheRight(k, rows_transpositions.coeff(k));
m_isInitialized = true;
return *this;
@@ -428,7 +423,7 @@ struct ei_solve_retval<PartialPivLU<_MatrixType>, Rhs>
dst.resize(size, rhs().cols());
// Step 1
- for(int i = 0; i < size; ++i) dst.row(dec().permutationP().coeff(i)) = rhs().row(i);
+ dst = dec().permutationP() * rhs();
// Step 2
dec().matrixLU().template triangularView<UnitLowerTriangular>().solveInPlace(dst);
diff --git a/Eigen/src/LU/arch/CMakeLists.txt b/Eigen/src/LU/arch/CMakeLists.txt
new file mode 100644
index 000000000..f6b7ed9ec
--- /dev/null
+++ b/Eigen/src/LU/arch/CMakeLists.txt
@@ -0,0 +1,6 @@
+FILE(GLOB Eigen_LU_arch_SRCS "*.h")
+
+INSTALL(FILES
+ ${Eigen_LU_arch_SRCS}
+ DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/LU/arch COMPONENT Devel
+ )
diff --git a/Eigen/src/LU/arch/Inverse_SSE.h b/Eigen/src/LU/arch/Inverse_SSE.h
new file mode 100644
index 000000000..cded9195c
--- /dev/null
+++ b/Eigen/src/LU/arch/Inverse_SSE.h
@@ -0,0 +1,151 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 1999 Intel Corporation
+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 3 of the License, or (at your option) any later version.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+// The SSE code for the 4x4 float matrix inverse in this file comes from the file
+// ftp://download.intel.com/design/PentiumIII/sml/24504301.pdf
+// See page ii of that document for legal stuff. Not being lawyers, we just assume
+// here that if Intel makes this document publically available, with source code
+// and detailed explanations, it's because they want their CPUs to be fed with
+// good code, and therefore they presumably don't mind us using it in Eigen.
+
+#ifndef EIGEN_INVERSE_SSE_H
+#define EIGEN_INVERSE_SSE_H
+
+template<typename MatrixType, typename ResultType>
+struct ei_compute_inverse_size4<Architecture::SSE, float, MatrixType, ResultType>
+{
+ static void run(const MatrixType& matrix, ResultType& result)
+ {
+ // Variables (Streaming SIMD Extensions registers) which will contain cofactors and, later, the
+ // lines of the inverted matrix.
+ __m128 minor0, minor1, minor2, minor3;
+
+ // Variables which will contain the lines of the reference matrix and, later (after the transposition),
+ // the columns of the original matrix.
+ __m128 row0, row1, row2, row3;
+
+ // Temporary variables and the variable that will contain the matrix determinant.
+ __m128 det, tmp1;
+
+ // Matrix transposition
+ const float *src = matrix.data();
+ tmp1 = _mm_loadh_pi(_mm_castpd_ps(_mm_load_sd((double*)src)), (__m64*)(src+ 4));
+ row1 = _mm_loadh_pi(_mm_castpd_ps(_mm_load_sd((double*)(src+8))), (__m64*)(src+12));
+ row0 = _mm_shuffle_ps(tmp1, row1, 0x88);
+ row1 = _mm_shuffle_ps(row1, tmp1, 0xDD);
+ tmp1 = _mm_loadh_pi(_mm_castpd_ps(_mm_load_sd((double*)(src+ 2))), (__m64*)(src+ 6));
+ row3 = _mm_loadh_pi(_mm_castpd_ps(_mm_load_sd((double*)(src+10))), (__m64*)(src+14));
+ row2 = _mm_shuffle_ps(tmp1, row3, 0x88);
+ row3 = _mm_shuffle_ps(row3, tmp1, 0xDD);
+
+
+ // Cofactors calculation. Because in the process of cofactor computation some pairs in three-
+ // element products are repeated, it is not reasonable to load these pairs anew every time. The
+ // values in the registers with these pairs are formed using shuffle instruction. Cofactors are
+ // calculated row by row (4 elements are placed in 1 SP FP SIMD floating point register).
+
+ tmp1 = _mm_mul_ps(row2, row3);
+ tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
+ minor0 = _mm_mul_ps(row1, tmp1);
+ minor1 = _mm_mul_ps(row0, tmp1);
+ tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
+ minor0 = _mm_sub_ps(_mm_mul_ps(row1, tmp1), minor0);
+ minor1 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor1);
+ minor1 = _mm_shuffle_ps(minor1, minor1, 0x4E);
+ // -----------------------------------------------
+ tmp1 = _mm_mul_ps(row1, row2);
+ tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
+ minor0 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor0);
+ minor3 = _mm_mul_ps(row0, tmp1);
+ tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
+ minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row3, tmp1));
+ minor3 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor3);
+ minor3 = _mm_shuffle_ps(minor3, minor3, 0x4E);
+ // -----------------------------------------------
+ tmp1 = _mm_mul_ps(_mm_shuffle_ps(row1, row1, 0x4E), row3);
+ tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
+ row2 = _mm_shuffle_ps(row2, row2, 0x4E);
+ minor0 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor0);
+ minor2 = _mm_mul_ps(row0, tmp1);
+ tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
+ minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row2, tmp1));
+ minor2 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor2);
+ minor2 = _mm_shuffle_ps(minor2, minor2, 0x4E);
+ // -----------------------------------------------
+ tmp1 = _mm_mul_ps(row0, row1);
+ tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
+ minor2 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor2);
+ minor3 = _mm_sub_ps(_mm_mul_ps(row2, tmp1), minor3);
+ tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
+ minor2 = _mm_sub_ps(_mm_mul_ps(row3, tmp1), minor2);
+ minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row2, tmp1));
+ // -----------------------------------------------
+ tmp1 = _mm_mul_ps(row0, row3);
+ tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
+ minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row2, tmp1));
+ minor2 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor2);
+ tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
+ minor1 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor1);
+ minor2 = _mm_sub_ps(minor2, _mm_mul_ps(row1, tmp1));
+ // -----------------------------------------------
+ tmp1 = _mm_mul_ps(row0, row2);
+ tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
+ minor1 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor1);
+ minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row1, tmp1));
+ tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
+ minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row3, tmp1));
+ minor3 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor3);
+
+ // Evaluation of determinant and its reciprocal value. In the original Intel document,
+ // 1/det was evaluated using a fast rcpps command with subsequent approximation using
+ // the Newton-Raphson algorithm. Here, we go for a IEEE-compliant division instead,
+ // so as to not compromise precision at all.
+ det = _mm_mul_ps(row0, minor0);
+ det = _mm_add_ps(_mm_shuffle_ps(det, det, 0x4E), det);
+ det = _mm_add_ss(_mm_shuffle_ps(det, det, 0xB1), det);
+// tmp1= _mm_rcp_ss(det);
+// det= _mm_sub_ss(_mm_add_ss(tmp1, tmp1), _mm_mul_ss(det, _mm_mul_ss(tmp1, tmp1)));
+ det = _mm_div_ss(_mm_set_ss(1.0f), det); // <--- yay, one original line not copied from Intel
+ det = _mm_shuffle_ps(det, det, 0x00);
+ // warning, Intel's variable naming is very confusing: now 'det' is 1/det !
+
+ // Multiplication of cofactors by 1/det. Storing the inverse matrix to the address in pointer src.
+ minor0 = _mm_mul_ps(det, minor0);
+ float *dst = result.data();
+ _mm_storel_pi((__m64*)(dst), minor0);
+ _mm_storeh_pi((__m64*)(dst+2), minor0);
+ minor1 = _mm_mul_ps(det, minor1);
+ _mm_storel_pi((__m64*)(dst+4), minor1);
+ _mm_storeh_pi((__m64*)(dst+6), minor1);
+ minor2 = _mm_mul_ps(det, minor2);
+ _mm_storel_pi((__m64*)(dst+ 8), minor2);
+ _mm_storeh_pi((__m64*)(dst+10), minor2);
+ minor3 = _mm_mul_ps(det, minor3);
+ _mm_storel_pi((__m64*)(dst+12), minor3);
+ _mm_storeh_pi((__m64*)(dst+14), minor3);
+ }
+};
+
+#endif // EIGEN_INVERSE_SSE_H
diff --git a/Eigen/src/QR/ColPivHouseholderQR.h b/Eigen/src/QR/ColPivHouseholderQR.h
index 02864caa5..b4c1a5fcc 100644
--- a/Eigen/src/QR/ColPivHouseholderQR.h
+++ b/Eigen/src/QR/ColPivHouseholderQR.h
@@ -57,10 +57,9 @@ template<typename _MatrixType> class ColPivHouseholderQR
typedef typename MatrixType::RealScalar RealScalar;
typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime> MatrixQType;
typedef Matrix<Scalar, DiagSizeAtCompileTime, 1> HCoeffsType;
+ typedef PermutationMatrix<ColsAtCompileTime> PermutationType;
typedef Matrix<int, 1, ColsAtCompileTime> IntRowVectorType;
- typedef Matrix<int, RowsAtCompileTime, 1> IntColVectorType;
typedef Matrix<Scalar, 1, ColsAtCompileTime> RowVectorType;
- typedef Matrix<Scalar, RowsAtCompileTime, 1> ColVectorType;
typedef Matrix<RealScalar, 1, ColsAtCompileTime> RealRowVectorType;
typedef typename HouseholderSequence<MatrixType,HCoeffsType>::ConjugateReturnType HouseholderSequenceType;
@@ -75,7 +74,8 @@ template<typename _MatrixType> class ColPivHouseholderQR
ColPivHouseholderQR(const MatrixType& matrix)
: m_qr(matrix.rows(), matrix.cols()),
m_hCoeffs(std::min(matrix.rows(),matrix.cols())),
- m_isInitialized(false)
+ m_isInitialized(false),
+ m_usePrescribedThreshold(false)
{
compute(matrix);
}
@@ -105,7 +105,7 @@ template<typename _MatrixType> class ColPivHouseholderQR
return ei_solve_retval<ColPivHouseholderQR, Rhs>(*this, b.derived());
}
- HouseholderSequenceType matrixQ(void) const;
+ HouseholderSequenceType householderQ(void) const;
/** \returns a reference to the matrix where the Householder QR decomposition is stored
*/
@@ -117,7 +117,7 @@ template<typename _MatrixType> class ColPivHouseholderQR
ColPivHouseholderQR& compute(const MatrixType& matrix);
- const IntRowVectorType& colsPermutation() const
+ const PermutationType& colsPermutation() const
{
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
return m_cols_permutation;
@@ -154,54 +154,63 @@ template<typename _MatrixType> class ColPivHouseholderQR
/** \returns the rank of the matrix of which *this is the QR decomposition.
*
- * \note This is computed at the time of the construction of the QR decomposition. This
- * method does not perform any further computation.
+ * \note This method has to determine which pivots should be considered nonzero.
+ * For that, it uses the threshold value that you can control by calling
+ * setThreshold(const RealScalar&).
*/
inline int rank() const
{
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
- return m_rank;
+ RealScalar premultiplied_threshold = ei_abs(m_maxpivot) * threshold();
+ int result = 0;
+ for(int i = 0; i < m_nonzero_pivots; ++i)
+ result += (ei_abs(m_qr.coeff(i,i)) > premultiplied_threshold);
+ return result;
}
/** \returns the dimension of the kernel of the matrix of which *this is the QR decomposition.
*
- * \note Since the rank is computed at the time of the construction of the QR decomposition, this
- * method almost does not perform any further computation.
+ * \note This method has to determine which pivots should be considered nonzero.
+ * For that, it uses the threshold value that you can control by calling
+ * setThreshold(const RealScalar&).
*/
inline int dimensionOfKernel() const
{
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
- return m_qr.cols() - m_rank;
+ return cols() - rank();
}
/** \returns true if the matrix of which *this is the QR decomposition represents an injective
* linear map, i.e. has trivial kernel; false otherwise.
*
- * \note Since the rank is computed at the time of the construction of the QR decomposition, this
- * method almost does not perform any further computation.
+ * \note This method has to determine which pivots should be considered nonzero.
+ * For that, it uses the threshold value that you can control by calling
+ * setThreshold(const RealScalar&).
*/
inline bool isInjective() const
{
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
- return m_rank == m_qr.cols();
+ return rank() == cols();
}
/** \returns true if the matrix of which *this is the QR decomposition represents a surjective
* linear map; false otherwise.
*
- * \note Since the rank is computed at the time of the construction of the QR decomposition, this
- * method almost does not perform any further computation.
+ * \note This method has to determine which pivots should be considered nonzero.
+ * For that, it uses the threshold value that you can control by calling
+ * setThreshold(const RealScalar&).
*/
inline bool isSurjective() const
{
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
- return m_rank == m_qr.rows();
+ return rank() == rows();
}
/** \returns true if the matrix of which *this is the QR decomposition is invertible.
*
- * \note Since the rank is computed at the time of the construction of the QR decomposition, this
- * method almost does not perform any further computation.
+ * \note This method has to determine which pivots should be considered nonzero.
+ * For that, it uses the threshold value that you can control by calling
+ * setThreshold(const RealScalar&).
*/
inline bool isInvertible() const
{
@@ -215,25 +224,92 @@ template<typename _MatrixType> class ColPivHouseholderQR
* Use isInvertible() to first determine whether this matrix is invertible.
*/
inline const
- ei_solve_retval<ColPivHouseholderQR, NestByValue<typename MatrixType::IdentityReturnType> >
+ ei_solve_retval<ColPivHouseholderQR, typename MatrixType::IdentityReturnType>
inverse() const
{
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
- return ei_solve_retval<ColPivHouseholderQR,NestByValue<typename MatrixType::IdentityReturnType> >
- (*this, MatrixType::Identity(m_qr.rows(), m_qr.cols()).nestByValue());
+ return ei_solve_retval<ColPivHouseholderQR,typename MatrixType::IdentityReturnType>
+ (*this, MatrixType::Identity(m_qr.rows(), m_qr.cols()));
}
inline int rows() const { return m_qr.rows(); }
inline int cols() const { return m_qr.cols(); }
const HCoeffsType& hCoeffs() const { return m_hCoeffs; }
+ /** Allows to prescribe a threshold to be used by certain methods, such as rank(),
+ * who need to determine when pivots are to be considered nonzero. This is not used for the
+ * QR decomposition itself.
+ *
+ * When it needs to get the threshold value, Eigen calls threshold(). By default, this
+ * uses a formula to automatically determine a reasonable threshold.
+ * Once you have called the present method setThreshold(const RealScalar&),
+ * your value is used instead.
+ *
+ * \param threshold The new value to use as the threshold.
+ *
+ * A pivot will be considered nonzero if its absolute value is strictly greater than
+ * \f$ \vert pivot \vert \leqslant threshold \times \vert maxpivot \vert \f$
+ * where maxpivot is the biggest pivot.
+ *
+ * If you want to come back to the default behavior, call setThreshold(Default_t)
+ */
+ ColPivHouseholderQR& setThreshold(const RealScalar& threshold)
+ {
+ m_usePrescribedThreshold = true;
+ m_prescribedThreshold = threshold;
+ }
+
+ /** Allows to come back to the default behavior, letting Eigen use its default formula for
+ * determining the threshold.
+ *
+ * You should pass the special object Eigen::Default as parameter here.
+ * \code qr.setThreshold(Eigen::Default); \endcode
+ *
+ * See the documentation of setThreshold(const RealScalar&).
+ */
+ ColPivHouseholderQR& setThreshold(Default_t)
+ {
+ m_usePrescribedThreshold = false;
+ }
+
+ /** Returns the threshold that will be used by certain methods such as rank().
+ *
+ * See the documentation of setThreshold(const RealScalar&).
+ */
+ RealScalar threshold() const
+ {
+ ei_assert(m_isInitialized || m_usePrescribedThreshold);
+ return m_usePrescribedThreshold ? m_prescribedThreshold
+ // this formula comes from experimenting (see "LU precision tuning" thread on the list)
+ // and turns out to be identical to Higham's formula used already in LDLt.
+ : epsilon<Scalar>() * m_qr.diagonalSize();
+ }
+
+ /** \returns the number of nonzero pivots in the QR decomposition.
+ * Here nonzero is meant in the exact sense, not in a fuzzy sense.
+ * So that notion isn't really intrinsically interesting, but it is
+ * still useful when implementing algorithms.
+ *
+ * \sa rank()
+ */
+ inline int nonzeroPivots() const
+ {
+ ei_assert(m_isInitialized && "LU is not initialized.");
+ return m_nonzero_pivots;
+ }
+
+ /** \returns the absolute value of the biggest pivot, i.e. the biggest
+ * diagonal coefficient of U.
+ */
+ RealScalar maxPivot() const { return m_maxpivot; }
+
protected:
MatrixType m_qr;
HCoeffsType m_hCoeffs;
- IntRowVectorType m_cols_permutation;
- bool m_isInitialized;
- RealScalar m_precision;
- int m_rank;
+ PermutationType m_cols_permutation;
+ bool m_isInitialized, m_usePrescribedThreshold;
+ RealScalar m_prescribedThreshold, m_maxpivot;
+ int m_nonzero_pivots;
int m_det_pq;
};
@@ -260,63 +336,85 @@ ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const
{
int rows = matrix.rows();
int cols = matrix.cols();
- int size = std::min(rows,cols);
- m_rank = size;
+ int size = matrix.diagonalSize();
m_qr = matrix;
m_hCoeffs.resize(size);
RowVectorType temp(cols);
- m_precision = epsilon<Scalar>() * size;
-
IntRowVectorType cols_transpositions(matrix.cols());
- m_cols_permutation.resize(matrix.cols());
int number_of_transpositions = 0;
RealRowVectorType colSqNorms(cols);
for(int k = 0; k < cols; ++k)
colSqNorms.coeffRef(k) = m_qr.col(k).squaredNorm();
- RealScalar biggestColSqNorm = colSqNorms.maxCoeff();
- for (int k = 0; k < size; ++k)
- {
- int biggest_col_in_corner;
- RealScalar biggestColSqNormInCorner = colSqNorms.end(cols-k).maxCoeff(&biggest_col_in_corner);
- biggest_col_in_corner += k;
+ RealScalar threshold_helper = colSqNorms.maxCoeff() * ei_abs2(epsilon<Scalar>()) / rows;
- // if the corner is negligible, then we have less than full rank, and we can finish early
- if(ei_isMuchSmallerThan(biggestColSqNormInCorner, biggestColSqNorm, m_precision))
+ m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
+ m_maxpivot = RealScalar(0);
+
+ for(int k = 0; k < size; ++k)
+ {
+ // first, we look up in our table colSqNorms which column has the biggest squared norm
+ int biggest_col_index;
+ RealScalar biggest_col_sq_norm = colSqNorms.end(cols-k).maxCoeff(&biggest_col_index);
+ biggest_col_index += k;
+
+ // since our table colSqNorms accumulates imprecision at every step, we must now recompute
+ // the actual squared norm of the selected column.
+ // Note that not doing so does result in solve() sometimes returning inf/nan values
+ // when running the unit test with 1000 repetitions.
+ biggest_col_sq_norm = m_qr.col(biggest_col_index).end(rows-k).squaredNorm();
+
+ // we store that back into our table: it can't hurt to correct our table.
+ colSqNorms.coeffRef(biggest_col_index) = biggest_col_sq_norm;
+
+ // if the current biggest column is smaller than epsilon times the initial biggest column,
+ // terminate to avoid generating nan/inf values.
+ // Note that here, if we test instead for "biggest == 0", we get a failure every 1000 (or so)
+ // repetitions of the unit test, with the result of solve() filled with large values of the order
+ // of 1/(size*epsilon).
+ if(biggest_col_sq_norm < threshold_helper * (rows-k))
{
- m_rank = k;
- for(int i = k; i < size; i++)
- {
- cols_transpositions.coeffRef(i) = i;
- m_hCoeffs.coeffRef(i) = Scalar(0);
- }
+ m_nonzero_pivots = k;
+ m_hCoeffs.end(size-k).setZero();
+ m_qr.corner(BottomRight,rows-k,cols-k)
+ .template triangularView<StrictlyLowerTriangular>()
+ .setZero();
break;
}
- cols_transpositions.coeffRef(k) = biggest_col_in_corner;
- if(k != biggest_col_in_corner) {
- m_qr.col(k).swap(m_qr.col(biggest_col_in_corner));
- std::swap(colSqNorms.coeffRef(k), colSqNorms.coeffRef(biggest_col_in_corner));
+ // apply the transposition to the columns
+ cols_transpositions.coeffRef(k) = biggest_col_index;
+ if(k != biggest_col_index) {
+ m_qr.col(k).swap(m_qr.col(biggest_col_index));
+ std::swap(colSqNorms.coeffRef(k), colSqNorms.coeffRef(biggest_col_index));
++number_of_transpositions;
}
+ // generate the householder vector, store it below the diagonal
RealScalar beta;
m_qr.col(k).end(rows-k).makeHouseholderInPlace(m_hCoeffs.coeffRef(k), beta);
+
+ // apply the householder transformation to the diagonal coefficient
m_qr.coeffRef(k,k) = beta;
+ // remember the maximum absolute value of diagonal coefficients
+ if(ei_abs(beta) > m_maxpivot) m_maxpivot = ei_abs(beta);
+
+ // apply the householder transformation
m_qr.corner(BottomRight, rows-k, cols-k-1)
.applyHouseholderOnTheLeft(m_qr.col(k).end(rows-k-1), m_hCoeffs.coeffRef(k), &temp.coeffRef(k+1));
+ // update our table of squared norms of the columns
colSqNorms.end(cols-k-1) -= m_qr.row(k).end(cols-k-1).cwiseAbs2();
}
- for(int k = 0; k < matrix.cols(); ++k) m_cols_permutation.coeffRef(k) = k;
- for(int k = 0; k < size; ++k)
- std::swap(m_cols_permutation.coeffRef(k), m_cols_permutation.coeffRef(cols_transpositions.coeff(k)));
+ m_cols_permutation.setIdentity(cols);
+ for(int k = 0; k < m_nonzero_pivots; ++k)
+ m_cols_permutation.applyTranspositionOnTheRight(k, cols_transpositions.coeff(k));
m_det_pq = (number_of_transpositions%2) ? -1 : 1;
m_isInitialized = true;
@@ -332,13 +430,12 @@ struct ei_solve_retval<ColPivHouseholderQR<_MatrixType>, Rhs>
template<typename Dest> void evalTo(Dest& dst) const
{
- const int rows = dec().rows(), cols = dec().cols();
+ const int rows = dec().rows(), cols = dec().cols(),
+ nonzero_pivots = dec().nonzeroPivots();
dst.resize(cols, rhs().cols());
ei_assert(rhs().rows() == rows);
- // FIXME introduce nonzeroPivots() and use it here. and more generally,
- // make the same improvements in this dec as in FullPivLU.
- if(dec().rank()==0)
+ if(nonzero_pivots == 0)
{
dst.setZero();
return;
@@ -348,37 +445,37 @@ struct ei_solve_retval<ColPivHouseholderQR<_MatrixType>, Rhs>
// Note that the matrix Q = H_0^* H_1^*... so its inverse is Q^* = (H_0 H_1 ...)^T
c.applyOnTheLeft(householderSequence(
- dec().matrixQR().corner(TopLeft,rows,dec().rank()),
- dec().hCoeffs().start(dec().rank())).transpose()
- );
-
- if(!dec().isSurjective())
- {
- // is c is in the image of R ?
- RealScalar biggest_in_upper_part_of_c = c.corner(TopLeft, dec().rank(), c.cols()).cwiseAbs().maxCoeff();
- RealScalar biggest_in_lower_part_of_c = c.corner(BottomLeft, rows-dec().rank(), c.cols()).cwiseAbs().maxCoeff();
- // FIXME brain dead
- const RealScalar m_precision = epsilon<Scalar>() * std::min(rows,cols);
- if(!ei_isMuchSmallerThan(biggest_in_lower_part_of_c, biggest_in_upper_part_of_c, m_precision*4))
- return;
- }
+ dec().matrixQR(),
+ dec().hCoeffs(),
+ true,
+ dec().nonzeroPivots()
+ ));
dec().matrixQR()
- .corner(TopLeft, dec().rank(), dec().rank())
+ .corner(TopLeft, nonzero_pivots, nonzero_pivots)
+ .template triangularView<UpperTriangular>()
+ .solveInPlace(c.corner(TopLeft, nonzero_pivots, c.cols()));
+
+
+ typename Rhs::PlainMatrixType d(c);
+ d.corner(TopLeft, nonzero_pivots, c.cols())
+ = dec().matrixQR()
+ .corner(TopLeft, nonzero_pivots, nonzero_pivots)
.template triangularView<UpperTriangular>()
- .solveInPlace(c.corner(TopLeft, dec().rank(), c.cols()));
+ * c.corner(TopLeft, nonzero_pivots, c.cols());
- for(int i = 0; i < dec().rank(); ++i) dst.row(dec().colsPermutation().coeff(i)) = c.row(i);
- for(int i = dec().rank(); i < cols; ++i) dst.row(dec().colsPermutation().coeff(i)).setZero();
+ for(int i = 0; i < nonzero_pivots; ++i) dst.row(dec().colsPermutation().indices().coeff(i)) = c.row(i);
+ for(int i = nonzero_pivots; i < cols; ++i) dst.row(dec().colsPermutation().indices().coeff(i)).setZero();
}
};
/** \returns the matrix Q as a sequence of householder transformations */
template<typename MatrixType>
-typename ColPivHouseholderQR<MatrixType>::HouseholderSequenceType ColPivHouseholderQR<MatrixType>::matrixQ() const
+typename ColPivHouseholderQR<MatrixType>::HouseholderSequenceType ColPivHouseholderQR<MatrixType>
+ ::householderQ() const
{
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
- return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate());
+ return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate(), false, m_nonzero_pivots);
}
#endif // EIGEN_HIDE_HEAVY_CODE
diff --git a/Eigen/src/QR/FullPivHouseholderQR.h b/Eigen/src/QR/FullPivHouseholderQR.h
index a1eaabf23..51609ca1a 100644
--- a/Eigen/src/QR/FullPivHouseholderQR.h
+++ b/Eigen/src/QR/FullPivHouseholderQR.h
@@ -58,6 +58,7 @@ template<typename _MatrixType> class FullPivHouseholderQR
typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime> MatrixQType;
typedef Matrix<Scalar, DiagSizeAtCompileTime, 1> HCoeffsType;
typedef Matrix<int, 1, ColsAtCompileTime> IntRowVectorType;
+ typedef PermutationMatrix<ColsAtCompileTime> PermutationType;
typedef Matrix<int, RowsAtCompileTime, 1> IntColVectorType;
typedef Matrix<Scalar, 1, ColsAtCompileTime> RowVectorType;
typedef Matrix<Scalar, RowsAtCompileTime, 1> ColVectorType;
@@ -112,7 +113,7 @@ template<typename _MatrixType> class FullPivHouseholderQR
FullPivHouseholderQR& compute(const MatrixType& matrix);
- const IntRowVectorType& colsPermutation() const
+ const PermutationType& colsPermutation() const
{
ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
return m_cols_permutation;
@@ -215,12 +216,12 @@ template<typename _MatrixType> class FullPivHouseholderQR
* \note If this matrix is not invertible, the returned matrix has undefined coefficients.
* Use isInvertible() to first determine whether this matrix is invertible.
*/ inline const
- ei_solve_retval<FullPivHouseholderQR, NestByValue<typename MatrixType::IdentityReturnType> >
+ ei_solve_retval<FullPivHouseholderQR, typename MatrixType::IdentityReturnType>
inverse() const
{
ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
- return ei_solve_retval<FullPivHouseholderQR,NestByValue<typename MatrixType::IdentityReturnType> >
- (*this, MatrixType::Identity(m_qr.rows(), m_qr.cols()).nestByValue());
+ return ei_solve_retval<FullPivHouseholderQR,typename MatrixType::IdentityReturnType>
+ (*this, MatrixType::Identity(m_qr.rows(), m_qr.cols()));
}
inline int rows() const { return m_qr.rows(); }
@@ -231,7 +232,7 @@ template<typename _MatrixType> class FullPivHouseholderQR
MatrixType m_qr;
HCoeffsType m_hCoeffs;
IntColVectorType m_rows_transpositions;
- IntRowVectorType m_cols_permutation;
+ PermutationType m_cols_permutation;
bool m_isInitialized;
RealScalar m_precision;
int m_rank;
@@ -273,7 +274,6 @@ FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(cons
m_rows_transpositions.resize(matrix.rows());
IntRowVectorType cols_transpositions(matrix.cols());
- m_cols_permutation.resize(matrix.cols());
int number_of_transpositions = 0;
RealScalar biggest(0);
@@ -322,9 +322,9 @@ FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(cons
.applyHouseholderOnTheLeft(m_qr.col(k).end(rows-k-1), m_hCoeffs.coeffRef(k), &temp.coeffRef(k+1));
}
- for(int k = 0; k < matrix.cols(); ++k) m_cols_permutation.coeffRef(k) = k;
+ m_cols_permutation.setIdentity(cols);
for(int k = 0; k < size; ++k)
- std::swap(m_cols_permutation.coeffRef(k), m_cols_permutation.coeffRef(cols_transpositions.coeff(k)));
+ m_cols_permutation.applyTranspositionOnTheRight(k, cols_transpositions.coeff(k));
m_det_pq = (number_of_transpositions%2) ? -1 : 1;
m_isInitialized = true;
@@ -379,8 +379,8 @@ struct ei_solve_retval<FullPivHouseholderQR<_MatrixType>, Rhs>
.template triangularView<UpperTriangular>()
.solveInPlace(c.corner(TopLeft, dec().rank(), c.cols()));
- for(int i = 0; i < dec().rank(); ++i) dst.row(dec().colsPermutation().coeff(i)) = c.row(i);
- for(int i = dec().rank(); i < cols; ++i) dst.row(dec().colsPermutation().coeff(i)).setZero();
+ for(int i = 0; i < dec().rank(); ++i) dst.row(dec().colsPermutation().indices().coeff(i)) = c.row(i);
+ for(int i = dec().rank(); i < cols; ++i) dst.row(dec().colsPermutation().indices().coeff(i)).setZero();
}
};
diff --git a/Eigen/src/QR/HouseholderQR.h b/Eigen/src/QR/HouseholderQR.h
index 9d8a33610..895ae046a 100644
--- a/Eigen/src/QR/HouseholderQR.h
+++ b/Eigen/src/QR/HouseholderQR.h
@@ -104,11 +104,10 @@ template<typename _MatrixType> class HouseholderQR
ei_assert(m_isInitialized && "HouseholderQR is not initialized.");
return ei_solve_retval<HouseholderQR, Rhs>(*this, b.derived());
}
-
- MatrixQType matrixQ() const;
- HouseholderSequenceType matrixQAsHouseholderSequence() const
+ HouseholderSequenceType householderQ() const
{
+ ei_assert(m_isInitialized && "HouseholderQR is not initialized.");
return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate());
}
@@ -240,14 +239,6 @@ struct ei_solve_retval<HouseholderQR<_MatrixType>, Rhs>
}
};
-/** \returns the matrix Q */
-template<typename MatrixType>
-typename HouseholderQR<MatrixType>::MatrixQType HouseholderQR<MatrixType>::matrixQ() const
-{
- ei_assert(m_isInitialized && "HouseholderQR is not initialized.");
- return matrixQAsHouseholderSequence();
-}
-
#endif // EIGEN_HIDE_HEAVY_CODE
/** \return the Householder QR decomposition of \c *this.
diff --git a/Eigen/src/SVD/JacobiSVD.h b/Eigen/src/SVD/JacobiSVD.h
index 927ef6591..5792c5767 100644
--- a/Eigen/src/SVD/JacobiSVD.h
+++ b/Eigen/src/SVD/JacobiSVD.h
@@ -236,9 +236,8 @@ struct ei_svd_precondition_if_more_rows_than_cols<MatrixType, Options, true>
FullPivHouseholderQR<MatrixType> qr(matrix);
work_matrix = qr.matrixQR().block(0,0,diagSize,diagSize).template triangularView<UpperTriangular>();
if(ComputeU) svd.m_matrixU = qr.matrixQ();
- if(ComputeV)
- for(int i = 0; i < cols; i++)
- svd.m_matrixV.coeffRef(qr.colsPermutation().coeff(i),i) = Scalar(1);
+ if(ComputeV) svd.m_matrixV = qr.colsPermutation();
+
return true;
}
else return false;
@@ -281,9 +280,7 @@ struct ei_svd_precondition_if_more_cols_than_rows<MatrixType, Options, true>
FullPivHouseholderQR<TransposeTypeWithSameStorageOrder> qr(matrix.adjoint());
work_matrix = qr.matrixQR().block(0,0,diagSize,diagSize).template triangularView<UpperTriangular>().adjoint();
if(ComputeV) svd.m_matrixV = qr.matrixQ();
- if(ComputeU)
- for(int i = 0; i < rows; i++)
- svd.m_matrixU.coeffRef(qr.colsPermutation().coeff(i),i) = Scalar(1);
+ if(ComputeU) svd.m_matrixU = qr.colsPermutation();
return true;
}
else return false;
@@ -297,8 +294,6 @@ JacobiSVD<MatrixType, Options>& JacobiSVD<MatrixType, Options>::compute(const Ma
int rows = matrix.rows();
int cols = matrix.cols();
int diagSize = std::min(rows, cols);
- if(ComputeU) m_matrixU = MatrixUType::Zero(rows,rows);
- if(ComputeV) m_matrixV = MatrixVType::Zero(cols,cols);
m_singularValues.resize(diagSize);
const RealScalar precision = 2 * epsilon<Scalar>();
@@ -306,8 +301,8 @@ JacobiSVD<MatrixType, Options>& JacobiSVD<MatrixType, Options>::compute(const Ma
&& !ei_svd_precondition_if_more_cols_than_rows<MatrixType, Options>::run(matrix, work_matrix, *this))
{
work_matrix = matrix.block(0,0,diagSize,diagSize);
- if(ComputeU) m_matrixU.diagonal().setOnes();
- if(ComputeV) m_matrixV.diagonal().setOnes();
+ if(ComputeU) m_matrixU.setIdentity(rows,rows);
+ if(ComputeV) m_matrixV.setIdentity(cols,cols);
}
bool finished = false;
diff --git a/Eigen/src/SVD/SVD.h b/Eigen/src/SVD/SVD.h
index 6ed9db20a..7a8e4f312 100644
--- a/Eigen/src/SVD/SVD.h
+++ b/Eigen/src/SVD/SVD.h
@@ -190,11 +190,10 @@ SVD<MatrixType>& SVD<MatrixType>::compute(const MatrixType& matrix)
SingularValuesType& W = m_sigma;
bool flag;
- int i,its,j,k,nm;
- int l=0;
+ int i=0,its=0,j=0,k=0,l=0,nm=0;
Scalar anorm, c, f, g, h, s, scale, x, y, z;
bool convergence = true;
- Scalar eps = precision<Scalar>();
+ Scalar eps = dummy_precision<Scalar>();
Matrix<Scalar,Dynamic,1> rv1(n);
g = scale = anorm = 0;
diff --git a/Eigen/src/Sparse/AmbiVector.h b/Eigen/src/Sparse/AmbiVector.h
index 474626848..2988999d6 100644
--- a/Eigen/src/Sparse/AmbiVector.h
+++ b/Eigen/src/Sparse/AmbiVector.h
@@ -126,10 +126,6 @@ template<typename _Scalar> class AmbiVector
int m_llStart;
int m_llCurrent;
int m_llSize;
-
- private:
- AmbiVector(const AmbiVector&);
-
};
/** \returns the number of non zeros in the current sub vector */
@@ -300,7 +296,7 @@ class AmbiVector<_Scalar>::Iterator
* In practice, all coefficients having a magnitude smaller than \a epsilon
* are skipped.
*/
- Iterator(const AmbiVector& vec, RealScalar epsilon = RealScalar(0.1)*precision<RealScalar>())
+ Iterator(const AmbiVector& vec, RealScalar epsilon = RealScalar(0.1)*dummy_precision<RealScalar>())
: m_vector(vec)
{
m_epsilon = epsilon;
diff --git a/Eigen/src/Sparse/CompressedStorage.h b/Eigen/src/Sparse/CompressedStorage.h
index abf42914f..b25b05e91 100644
--- a/Eigen/src/Sparse/CompressedStorage.h
+++ b/Eigen/src/Sparse/CompressedStorage.h
@@ -93,7 +93,7 @@ class CompressedStorage
void append(const Scalar& v, int i)
{
- int id = m_size;
+ int id = static_cast<int>(m_size);
resize(m_size+1, 1);
m_values[id] = v;
m_indices[id] = i;
@@ -135,7 +135,7 @@ class CompressedStorage
else
end = mid;
}
- return start;
+ return static_cast<int>(start);
}
/** \returns the stored value at index \a key
@@ -185,7 +185,7 @@ class CompressedStorage
return m_values[id];
}
- void prune(Scalar reference, RealScalar epsilon = precision<RealScalar>())
+ void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar>())
{
size_t k = 0;
size_t n = size();
diff --git a/Eigen/src/Sparse/DynamicSparseMatrix.h b/Eigen/src/Sparse/DynamicSparseMatrix.h
index 9644dbcd5..4373e1cda 100644
--- a/Eigen/src/Sparse/DynamicSparseMatrix.h
+++ b/Eigen/src/Sparse/DynamicSparseMatrix.h
@@ -58,6 +58,13 @@ struct ei_traits<DynamicSparseMatrix<_Scalar, _Flags> >
};
};
+template<typename _Scalar, int _Options>
+struct ei_ref_selector< DynamicSparseMatrix<_Scalar, _Options> >
+{
+ typedef DynamicSparseMatrix<_Scalar, _Options> MatrixType;
+ typedef MatrixType const& type;
+};
+
template<typename _Scalar, int _Flags>
class DynamicSparseMatrix
: public SparseMatrixBase<DynamicSparseMatrix<_Scalar, _Flags> >
@@ -82,7 +89,7 @@ class DynamicSparseMatrix
inline int rows() const { return IsRowMajor ? outerSize() : m_innerSize; }
inline int cols() const { return IsRowMajor ? m_innerSize : outerSize(); }
inline int innerSize() const { return m_innerSize; }
- inline int outerSize() const { return m_data.size(); }
+ inline int outerSize() const { return static_cast<int>(m_data.size()); }
inline int innerNonZeros(int j) const { return m_data[j].size(); }
std::vector<CompressedStorage<Scalar> >& _data() { return m_data; }
@@ -122,7 +129,7 @@ class DynamicSparseMatrix
{
int res = 0;
for (int j=0; j<outerSize(); ++j)
- res += m_data[j].size();
+ res += static_cast<int>(m_data[j].size());
return res;
}
@@ -189,7 +196,7 @@ class DynamicSparseMatrix
const int inner = IsRowMajor ? col : row;
int startId = 0;
- int id = m_data[outer].size() - 1;
+ int id = static_cast<int>(m_data[outer].size()) - 1;
m_data[outer].resize(id+2,1);
while ( (id >= startId) && (m_data[outer].index(id) > inner) )
@@ -209,7 +216,7 @@ class DynamicSparseMatrix
inline void finalize() {}
- void prune(Scalar reference, RealScalar epsilon = precision<RealScalar>())
+ void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar>())
{
for (int j=0; j<outerSize(); ++j)
m_data[j].prune(reference,epsilon);
@@ -314,7 +321,6 @@ class DynamicSparseMatrix<Scalar,_Flags>::InnerIterator : public SparseVector<Sc
inline int row() const { return IsRowMajor ? m_outer : Base::index(); }
inline int col() const { return IsRowMajor ? Base::index() : m_outer; }
-
protected:
const int m_outer;
};
diff --git a/Eigen/src/Sparse/RandomSetter.h b/Eigen/src/Sparse/RandomSetter.h
index 50824eba1..b34ca19a8 100644
--- a/Eigen/src/Sparse/RandomSetter.h
+++ b/Eigen/src/Sparse/RandomSetter.h
@@ -322,7 +322,7 @@ class RandomSetter
{
int nz = 0;
for (int k=0; k<m_outerPackets; ++k)
- nz += m_hashmaps[k].size();
+ nz += static_cast<int>(m_hashmaps[k].size());
return nz;
}
diff --git a/Eigen/src/Sparse/SparseDiagonalProduct.h b/Eigen/src/Sparse/SparseDiagonalProduct.h
index 642db5789..ceb4d6576 100644
--- a/Eigen/src/Sparse/SparseDiagonalProduct.h
+++ b/Eigen/src/Sparse/SparseDiagonalProduct.h
@@ -86,8 +86,7 @@ class SparseDiagonalProduct
typedef ei_sparse_diagonal_product_inner_iterator_selector
<_LhsNested,_RhsNested,SparseDiagonalProduct,LhsMode,RhsMode> InnerIterator;
- template<typename _Lhs, typename _Rhs>
- EIGEN_STRONG_INLINE SparseDiagonalProduct(const _Lhs& lhs, const _Rhs& rhs)
+ EIGEN_STRONG_INLINE SparseDiagonalProduct(const Lhs& lhs, const Rhs& rhs)
: m_lhs(lhs), m_rhs(rhs)
{
ei_assert(lhs.cols() == rhs.rows() && "invalid sparse matrix * diagonal matrix product");
@@ -156,16 +155,16 @@ class ei_sparse_diagonal_product_inner_iterator_selector
: public CwiseBinaryOp<
ei_scalar_product_op<typename Rhs::Scalar>,
SparseInnerVectorSet<Lhs,1>,
- NestByValue<Transpose<typename Rhs::DiagonalVectorType> > >::InnerIterator
+ Transpose<typename Rhs::DiagonalVectorType> >::InnerIterator
{
typedef typename CwiseBinaryOp<
ei_scalar_product_op<typename Rhs::Scalar>,
SparseInnerVectorSet<Lhs,1>,
- NestByValue<Transpose<typename Rhs::DiagonalVectorType> > >::InnerIterator Base;
+ Transpose<typename Rhs::DiagonalVectorType> >::InnerIterator Base;
public:
inline ei_sparse_diagonal_product_inner_iterator_selector(
const SparseDiagonalProductType& expr, int outer)
- : Base(expr.lhs().innerVector(outer) .cwiseProduct(expr.rhs().diagonal().transpose().nestByValue()), 0)
+ : Base(expr.lhs().innerVector(outer) .cwiseProduct(expr.rhs().diagonal().transpose()), 0)
{}
};
diff --git a/Eigen/src/Sparse/SparseExpressionMaker.h b/Eigen/src/Sparse/SparseExpressionMaker.h
new file mode 100644
index 000000000..8e31d55ef
--- /dev/null
+++ b/Eigen/src/Sparse/SparseExpressionMaker.h
@@ -0,0 +1,42 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 3 of the License, or (at your option) any later version.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_SPARSE_EXPRESSIONMAKER_H
+#define EIGEN_SPARSE_EXPRESSIONMAKER_H
+
+template<typename Func, typename XprType>
+struct MakeCwiseUnaryOp<Func,XprType,IsSparse>
+{
+ typedef SparseCwiseUnaryOp<Func,XprType> Type;
+};
+
+template<typename Func, typename A, typename B>
+struct MakeCwiseBinaryOp<Func,A,B,IsSparse>
+{
+ typedef SparseCwiseBinaryOp<Func,A,B> Type;
+};
+
+// TODO complete the list
+
+#endif // EIGEN_SPARSE_EXPRESSIONMAKER_H
diff --git a/Eigen/src/Sparse/SparseLDLT.h b/Eigen/src/Sparse/SparseLDLT.h
index a30bd5ccd..625357e2b 100644
--- a/Eigen/src/Sparse/SparseLDLT.h
+++ b/Eigen/src/Sparse/SparseLDLT.h
@@ -94,7 +94,7 @@ class SparseLDLT
: m_flags(flags), m_status(0)
{
ei_assert((MatrixType::Flags&RowMajorBit)==0);
- m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
+ m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar>();
}
/** Creates a LDLT object and compute the respective factorization of \a matrix using
@@ -103,7 +103,7 @@ class SparseLDLT
: m_matrix(matrix.rows(), matrix.cols()), m_flags(flags), m_status(0)
{
ei_assert((MatrixType::Flags&RowMajorBit)==0);
- m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
+ m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar>();
compute(matrix);
}
diff --git a/Eigen/src/Sparse/SparseLLT.h b/Eigen/src/Sparse/SparseLLT.h
index 6307b2493..68ae43022 100644
--- a/Eigen/src/Sparse/SparseLLT.h
+++ b/Eigen/src/Sparse/SparseLLT.h
@@ -54,7 +54,7 @@ class SparseLLT
SparseLLT(int flags = 0)
: m_flags(flags), m_status(0)
{
- m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
+ m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar>();
}
/** Creates a LLT object and compute the respective factorization of \a matrix using
@@ -62,7 +62,7 @@ class SparseLLT
SparseLLT(const MatrixType& matrix, int flags = 0)
: m_matrix(matrix.rows(), matrix.cols()), m_flags(flags), m_status(0)
{
- m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
+ m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar>();
compute(matrix);
}
diff --git a/Eigen/src/Sparse/SparseLU.h b/Eigen/src/Sparse/SparseLU.h
index 3f8d0f8db..2ec6d0e74 100644
--- a/Eigen/src/Sparse/SparseLU.h
+++ b/Eigen/src/Sparse/SparseLU.h
@@ -59,7 +59,7 @@ class SparseLU
SparseLU(int flags = 0)
: m_flags(flags), m_status(0)
{
- m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
+ m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar>();
}
/** Creates a LU object and compute the respective factorization of \a matrix using
@@ -67,7 +67,7 @@ class SparseLU
SparseLU(const MatrixType& matrix, int flags = 0)
: /*m_matrix(matrix.rows(), matrix.cols()),*/ m_flags(flags), m_status(0)
{
- m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
+ m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar>();
compute(matrix);
}
diff --git a/Eigen/src/Sparse/SparseMatrix.h b/Eigen/src/Sparse/SparseMatrix.h
index 5e89d3f53..7feb2aff8 100644
--- a/Eigen/src/Sparse/SparseMatrix.h
+++ b/Eigen/src/Sparse/SparseMatrix.h
@@ -58,6 +58,13 @@ struct ei_traits<SparseMatrix<_Scalar, _Options> >
};
template<typename _Scalar, int _Options>
+struct ei_ref_selector<SparseMatrix<_Scalar, _Options> >
+{
+ typedef SparseMatrix<_Scalar, _Options> MatrixType;
+ typedef MatrixType const& type;
+};
+
+template<typename _Scalar, int _Options>
class SparseMatrix
: public SparseMatrixBase<SparseMatrix<_Scalar, _Options> >
{
@@ -132,7 +139,7 @@ class SparseMatrix
}
/** \returns the number of non zero coefficients */
- inline int nonZeros() const { return m_data.size(); }
+ inline int nonZeros() const { return static_cast<int>(m_data.size()); }
/** \deprecated use setZero() and reserve()
* Initializes the filling process of \c *this.
@@ -230,7 +237,7 @@ class SparseMatrix
// we start a new inner vector
while (previousOuter>=0 && m_outerIndex[previousOuter]==0)
{
- m_outerIndex[previousOuter] = m_data.size();
+ m_outerIndex[previousOuter] = static_cast<int>(m_data.size());
--previousOuter;
}
m_outerIndex[outer+1] = m_outerIndex[outer];
@@ -329,7 +336,7 @@ class SparseMatrix
*/
inline void finalize()
{
- int size = m_data.size();
+ int size = static_cast<int>(m_data.size());
int i = m_outerSize;
// find the last filled column
while (i>=0 && m_outerIndex[i]==0)
@@ -342,7 +349,7 @@ class SparseMatrix
}
}
- void prune(Scalar reference, RealScalar epsilon = precision<RealScalar>())
+ void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar>())
{
int k = 0;
for (int j=0; j<m_outerSize; ++j)
diff --git a/Eigen/src/Sparse/SparseMatrixBase.h b/Eigen/src/Sparse/SparseMatrixBase.h
index 4ea1023af..80cb7620c 100644
--- a/Eigen/src/Sparse/SparseMatrixBase.h
+++ b/Eigen/src/Sparse/SparseMatrixBase.h
@@ -105,7 +105,7 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived
// typedef SparseCwiseUnaryOp<ei_scalar_imag_op<Scalar>, Derived> ImagReturnType;
/** \internal the return type of MatrixBase::adjoint() */
typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
- CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, SparseNestByValue<Eigen::Transpose<Derived> > >,
+ CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::Transpose<Derived> >,
Transpose<Derived>
>::ret AdjointReturnType;
@@ -399,7 +399,7 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived
Transpose<Derived> transpose() { return derived(); }
const Transpose<Derived> transpose() const { return derived(); }
// void transposeInPlace();
- const AdjointReturnType adjoint() const { return transpose().nestByValue(); }
+ const AdjointReturnType adjoint() const { return transpose(); }
// sub-vector
SparseInnerVectorSet<Derived,1> row(int i);
@@ -510,32 +510,32 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived
template<typename OtherDerived>
bool isApprox(const SparseMatrixBase<OtherDerived>& other,
- RealScalar prec = precision<Scalar>()) const
+ RealScalar prec = dummy_precision<Scalar>()) const
{ return toDense().isApprox(other.toDense(),prec); }
template<typename OtherDerived>
bool isApprox(const MatrixBase<OtherDerived>& other,
- RealScalar prec = precision<Scalar>()) const
+ RealScalar prec = dummy_precision<Scalar>()) const
{ return toDense().isApprox(other,prec); }
// bool isMuchSmallerThan(const RealScalar& other,
-// RealScalar prec = precision<Scalar>()) const;
+// RealScalar prec = dummy_precision<Scalar>()) const;
// template<typename OtherDerived>
// bool isMuchSmallerThan(const MatrixBase<OtherDerived>& other,
-// RealScalar prec = precision<Scalar>()) const;
+// RealScalar prec = dummy_precision<Scalar>()) const;
-// bool isApproxToConstant(const Scalar& value, RealScalar prec = precision<Scalar>()) const;
-// bool isZero(RealScalar prec = precision<Scalar>()) const;
-// bool isOnes(RealScalar prec = precision<Scalar>()) const;
-// bool isIdentity(RealScalar prec = precision<Scalar>()) const;
-// bool isDiagonal(RealScalar prec = precision<Scalar>()) const;
+// bool isApproxToConstant(const Scalar& value, RealScalar prec = dummy_precision<Scalar>()) const;
+// bool isZero(RealScalar prec = dummy_precision<Scalar>()) const;
+// bool isOnes(RealScalar prec = dummy_precision<Scalar>()) const;
+// bool isIdentity(RealScalar prec = dummy_precision<Scalar>()) const;
+// bool isDiagonal(RealScalar prec = dummy_precision<Scalar>()) const;
-// bool isUpperTriangular(RealScalar prec = precision<Scalar>()) const;
-// bool isLowerTriangular(RealScalar prec = precision<Scalar>()) const;
+// bool isUpperTriangular(RealScalar prec = dummy_precision<Scalar>()) const;
+// bool isLowerTriangular(RealScalar prec = dummy_precision<Scalar>()) const;
// template<typename OtherDerived>
// bool isOrthogonal(const MatrixBase<OtherDerived>& other,
-// RealScalar prec = precision<Scalar>()) const;
-// bool isUnitary(RealScalar prec = precision<Scalar>()) const;
+// RealScalar prec = dummy_precision<Scalar>()) const;
+// bool isUnitary(RealScalar prec = dummy_precision<Scalar>()) const;
// template<typename OtherDerived>
// inline bool operator==(const MatrixBase<OtherDerived>& other) const
@@ -571,9 +571,7 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived
*/
// inline int stride(void) const { return derived().stride(); }
- inline const SparseNestByValue<Derived> nestByValue() const;
-
-
+// FIXME
// ConjugateReturnType conjugate() const;
// const RealReturnType real() const;
// const ImagReturnType imag() const;
@@ -626,11 +624,11 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived
const MatrixBase<ElseDerived>& elseMatrix) const;
template<typename ThenDerived>
- inline const Select<Derived,ThenDerived, NestByValue<typename ThenDerived::ConstantReturnType> >
+ inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
select(const MatrixBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const;
template<typename ElseDerived>
- inline const Select<Derived, NestByValue<typename ElseDerived::ConstantReturnType>, ElseDerived >
+ inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
select(typename ElseDerived::Scalar thenScalar, const MatrixBase<ElseDerived>& elseMatrix) const;
template<int p> RealScalar lpNorm() const;
diff --git a/Eigen/src/Sparse/SparseNestByValue.h b/Eigen/src/Sparse/SparseNestByValue.h
deleted file mode 100644
index b48277232..000000000
--- a/Eigen/src/Sparse/SparseNestByValue.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// Eigen is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 3 of the License, or (at your option) any later version.
-//
-// Alternatively, you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of
-// the License, or (at your option) any later version.
-//
-// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License and a copy of the GNU General Public License along with
-// Eigen. If not, see <http://www.gnu.org/licenses/>.
-
-#ifndef EIGEN_SPARSENESTBYVALUE_H
-#define EIGEN_SPARSENESTBYVALUE_H
-
-/** \class SparseNestByValue
- *
- * \brief Expression which must be nested by value
- *
- * \param ExpressionType the type of the object of which we are requiring nesting-by-value
- *
- * This class is the return type of MatrixBase::nestByValue()
- * and most of the time this is the only way it is used.
- *
- * \sa SparseMatrixBase::nestByValue(), class NestByValue
- */
-template<typename ExpressionType>
-struct ei_traits<SparseNestByValue<ExpressionType> > : public ei_traits<ExpressionType>
-{};
-
-template<typename ExpressionType> class SparseNestByValue
- : public SparseMatrixBase<SparseNestByValue<ExpressionType> >
-{
- public:
-
- typedef typename ExpressionType::InnerIterator InnerIterator;
-
- EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseNestByValue)
-
- inline SparseNestByValue(const ExpressionType& matrix) : m_expression(matrix) {}
-
- EIGEN_STRONG_INLINE int rows() const { return m_expression.rows(); }
- EIGEN_STRONG_INLINE int cols() const { return m_expression.cols(); }
-
- operator const ExpressionType&() const { return m_expression; }
-
- protected:
- const ExpressionType m_expression;
-};
-
-/** \returns an expression of the temporary version of *this.
- */
-template<typename Derived>
-inline const SparseNestByValue<Derived>
-SparseMatrixBase<Derived>::nestByValue() const
-{
- return SparseNestByValue<Derived>(derived());
-}
-
-// template<typename MatrixType>
-// class SparseNestByValue<MatrixType>::InnerIterator : public MatrixType::InnerIterator
-// {
-// typedef typename MatrixType::InnerIterator Base;
-// public:
-//
-// EIGEN_STRONG_INLINE InnerIterator(const SparseNestByValue& expr, int outer)
-// : Base(expr.m_expression, outer)
-// {}
-// };
-
-#endif // EIGEN_SPARSENESTBYVALUE_H
diff --git a/Eigen/src/Sparse/SparseUtil.h b/Eigen/src/Sparse/SparseUtil.h
index 6da1bee25..965565b73 100644
--- a/Eigen/src/Sparse/SparseUtil.h
+++ b/Eigen/src/Sparse/SparseUtil.h
@@ -123,11 +123,10 @@ template<typename _Scalar, int _Flags = 0> class DynamicSparseMatrix;
template<typename _Scalar, int _Flags = 0> class SparseVector;
template<typename _Scalar, int _Flags = 0> class MappedSparseMatrix;
-template<typename MatrixType> class SparseNestByValue;
-template<typename MatrixType, int Size> class SparseInnerVectorSet;
-template<typename MatrixType, int Mode> class SparseTriangularView;
-template<typename MatrixType, unsigned int UpLo> class SparseSelfAdjointView;
-template<typename Lhs, typename Rhs> class SparseDiagonalProduct;
+template<typename MatrixType, int Size> class SparseInnerVectorSet;
+template<typename MatrixType, int Mode> class SparseTriangularView;
+template<typename MatrixType, unsigned int UpLo> class SparseSelfAdjointView;
+template<typename Lhs, typename Rhs> class SparseDiagonalProduct;
template<typename Lhs, typename Rhs> class SparseProduct;
@@ -156,6 +155,4 @@ template<typename T> class ei_eval<T,Sparse>
typedef SparseMatrix<_Scalar, _Flags> type;
};
-template<typename T> struct ei_must_nest_by_value<SparseNestByValue<T> > { enum { ret = true }; };
-
#endif // EIGEN_SPARSEUTIL_H
diff --git a/Eigen/src/Sparse/SparseVector.h b/Eigen/src/Sparse/SparseVector.h
index 68e984fae..5ac3f6be7 100644
--- a/Eigen/src/Sparse/SparseVector.h
+++ b/Eigen/src/Sparse/SparseVector.h
@@ -53,6 +53,13 @@ struct ei_traits<SparseVector<_Scalar, _Options> >
};
template<typename _Scalar, int _Options>
+struct ei_ref_selector< SparseVector<_Scalar, _Options> >
+{
+ typedef SparseVector<_Scalar, _Options> MatrixType;
+ typedef MatrixType const& type;
+};
+
+template<typename _Scalar, int _Options>
class SparseVector
: public SparseMatrixBase<SparseVector<_Scalar, _Options> >
{
@@ -119,7 +126,7 @@ class SparseVector
inline void setZero() { m_data.clear(); }
/** \returns the number of non zero coefficients */
- inline int nonZeros() const { return m_data.size(); }
+ inline int nonZeros() const { return static_cast<int>(m_data.size()); }
inline void startVec(int outer)
{
@@ -202,7 +209,7 @@ class SparseVector
EIGEN_DEPRECATED void endFill() {}
inline void finalize() {}
- void prune(Scalar reference, RealScalar epsilon = precision<RealScalar>())
+ void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar>())
{
m_data.prune(reference,epsilon);
}
@@ -368,13 +375,13 @@ class SparseVector<Scalar,_Options>::InnerIterator
{
public:
InnerIterator(const SparseVector& vec, int outer=0)
- : m_data(vec.m_data), m_id(0), m_end(m_data.size())
+ : m_data(vec.m_data), m_id(0), m_end(static_cast<int>(m_data.size()))
{
ei_assert(outer==0);
}
InnerIterator(const CompressedStorage<Scalar>& data)
- : m_data(data), m_id(0), m_end(m_data.size())
+ : m_data(data), m_id(0), m_end(static_cast<int>(m_data.size()))
{}
template<unsigned int Added, unsigned int Removed>
diff --git a/Eigen/src/misc/Image.h b/Eigen/src/misc/Image.h
index 9ed5d5f70..2f39d6b9d 100644
--- a/Eigen/src/misc/Image.h
+++ b/Eigen/src/misc/Image.h
@@ -67,9 +67,9 @@ template<typename _DecompositionType> struct ei_image_retval_base
}
protected:
- const DecompositionType& m_dec;
- int m_rank, m_cols;
- const MatrixType& m_originalMatrix;
+ const DecompositionType& m_dec;
+ int m_rank, m_cols;
+ const MatrixType& m_originalMatrix;
};
#define EIGEN_MAKE_IMAGE_HELPERS(DecompositionType) \
diff --git a/Eigen/src/misc/Kernel.h b/Eigen/src/misc/Kernel.h
index 717eef450..908c408e9 100644
--- a/Eigen/src/misc/Kernel.h
+++ b/Eigen/src/misc/Kernel.h
@@ -67,8 +67,8 @@ template<typename _DecompositionType> struct ei_kernel_retval_base
}
protected:
- const DecompositionType& m_dec;
- int m_rank, m_cols;
+ const DecompositionType& m_dec;
+ int m_rank, m_cols;
};
#define EIGEN_MAKE_KERNEL_HELPERS(DecompositionType) \
diff --git a/Eigen/src/misc/Solve.h b/Eigen/src/misc/Solve.h
index d93869121..4ab0775fc 100644
--- a/Eigen/src/misc/Solve.h
+++ b/Eigen/src/misc/Solve.h
@@ -61,8 +61,8 @@ template<typename _DecompositionType, typename Rhs> struct ei_solve_retval_base
}
protected:
- const DecompositionType& m_dec;
- const typename Rhs::Nested m_rhs;
+ const DecompositionType& m_dec;
+ const typename Rhs::Nested m_rhs;
};
#define EIGEN_MAKE_SOLVE_HELPERS(DecompositionType,Rhs) \
diff --git a/bench/BenchTimer.h b/bench/BenchTimer.h
index 70173427f..b2d0fc5f6 100644
--- a/bench/BenchTimer.h
+++ b/bench/BenchTimer.h
@@ -26,12 +26,13 @@
#ifndef EIGEN_BENCH_TIMER_H
#define EIGEN_BENCH_TIMER_H
-#ifndef WIN32
-#include <time.h>
-#include <unistd.h>
-#else
+#if defined(_WIN32) || defined(__CYGWIN__)
#define NOMINMAX
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#else
+#include <time.h>
+#include <unistd.h>
#endif
#include <cstdlib>
@@ -53,7 +54,7 @@ public:
BenchTimer()
{
-#ifdef WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
m_frequency = (double)freq.QuadPart;
@@ -77,7 +78,7 @@ public:
return m_best;
}
-#ifdef WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
inline double getTime(void)
#else
static inline double getTime(void)
@@ -95,7 +96,7 @@ public:
}
protected:
-#ifdef WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
double m_frequency;
#endif
double m_best, m_start;
diff --git a/bench/quat_slerp.cpp b/bench/quat_slerp.cpp
new file mode 100644
index 000000000..029443704
--- /dev/null
+++ b/bench/quat_slerp.cpp
@@ -0,0 +1,245 @@
+
+#include <Eigen/Geometry>
+#include <bench/BenchTimer.h>
+using namespace Eigen;
+using namespace std;
+
+
+
+template<typename Q>
+EIGEN_DONT_INLINE Q nlerp(const Q& a, const Q& b, typename Q::Scalar t)
+{
+ return Q((a.coeffs() * (1.0-t) + b.coeffs() * t).normalized());
+}
+
+template<typename Q>
+EIGEN_DONT_INLINE Q slerp_eigen(const Q& a, const Q& b, typename Q::Scalar t)
+{
+ return a.slerp(t,b);
+}
+
+template<typename Q>
+EIGEN_DONT_INLINE Q slerp_legacy(const Q& a, const Q& b, typename Q::Scalar t)
+{
+ typedef typename Q::Scalar Scalar;
+ static const Scalar one = Scalar(1) - dummy_precision<Scalar>();
+ Scalar d = a.dot(b);
+ Scalar absD = ei_abs(d);
+ if (absD>=one)
+ return a;
+
+ // theta is the angle between the 2 quaternions
+ Scalar theta = std::acos(absD);
+ Scalar sinTheta = ei_sin(theta);
+
+ Scalar scale0 = ei_sin( ( Scalar(1) - t ) * theta) / sinTheta;
+ Scalar scale1 = ei_sin( ( t * theta) ) / sinTheta;
+ if (d<0)
+ scale1 = -scale1;
+
+ return Q(scale0 * a.coeffs() + scale1 * b.coeffs());
+}
+
+template<typename Q>
+EIGEN_DONT_INLINE Q slerp_legacy_nlerp(const Q& a, const Q& b, typename Q::Scalar t)
+{
+ typedef typename Q::Scalar Scalar;
+ static const Scalar one = Scalar(1) - epsilon<Scalar>();
+ Scalar d = a.dot(b);
+ Scalar absD = ei_abs(d);
+
+ Scalar scale0;
+ Scalar scale1;
+
+ if (absD>=one)
+ {
+ scale0 = Scalar(1) - t;
+ scale1 = t;
+ }
+ else
+ {
+ // theta is the angle between the 2 quaternions
+ Scalar theta = std::acos(absD);
+ Scalar sinTheta = ei_sin(theta);
+
+ scale0 = ei_sin( ( Scalar(1) - t ) * theta) / sinTheta;
+ scale1 = ei_sin( ( t * theta) ) / sinTheta;
+ if (d<0)
+ scale1 = -scale1;
+ }
+
+ return Q(scale0 * a.coeffs() + scale1 * b.coeffs());
+}
+
+template<typename T>
+inline T sin_over_x(T x)
+{
+ if (T(1) + x*x == T(1))
+ return T(1);
+ else
+ return std::sin(x)/x;
+}
+
+template<typename Q>
+EIGEN_DONT_INLINE Q slerp_rw(const Q& a, const Q& b, typename Q::Scalar t)
+{
+ typedef typename Q::Scalar Scalar;
+
+ Scalar d = a.dot(b);
+ Scalar theta;
+ if (d<0.0)
+ theta = /*M_PI -*/ Scalar(2)*std::asin( (a.coeffs()+b.coeffs()).norm()/2 );
+ else
+ theta = Scalar(2)*std::asin( (a.coeffs()-b.coeffs()).norm()/2 );
+
+ // theta is the angle between the 2 quaternions
+// Scalar theta = std::acos(absD);
+ Scalar sinOverTheta = sin_over_x(theta);
+
+ Scalar scale0 = (Scalar(1)-t)*sin_over_x( ( Scalar(1) - t ) * theta) / sinOverTheta;
+ Scalar scale1 = t * sin_over_x( ( t * theta) ) / sinOverTheta;
+ if (d<0)
+ scale1 = -scale1;
+
+ return Quaternion<Scalar>(scale0 * a.coeffs() + scale1 * b.coeffs());
+}
+
+template<typename Q>
+EIGEN_DONT_INLINE Q slerp_gael(const Q& a, const Q& b, typename Q::Scalar t)
+{
+ typedef typename Q::Scalar Scalar;
+
+ Scalar d = a.dot(b);
+ Scalar theta;
+// theta = Scalar(2) * atan2((a.coeffs()-b.coeffs()).norm(),(a.coeffs()+b.coeffs()).norm());
+// if (d<0.0)
+// theta = M_PI-theta;
+
+ if (d<0.0)
+ theta = /*M_PI -*/ Scalar(2)*std::asin( (-a.coeffs()-b.coeffs()).norm()/2 );
+ else
+ theta = Scalar(2)*std::asin( (a.coeffs()-b.coeffs()).norm()/2 );
+
+
+ Scalar scale0;
+ Scalar scale1;
+ if(theta*theta-Scalar(6)==-Scalar(6))
+ {
+ scale0 = Scalar(1) - t;
+ scale1 = t;
+ }
+ else
+ {
+ Scalar sinTheta = std::sin(theta);
+ scale0 = ei_sin( ( Scalar(1) - t ) * theta) / sinTheta;
+ scale1 = ei_sin( ( t * theta) ) / sinTheta;
+ if (d<0)
+ scale1 = -scale1;
+ }
+
+ return Quaternion<Scalar>(scale0 * a.coeffs() + scale1 * b.coeffs());
+}
+
+int main()
+{
+ typedef double RefScalar;
+ typedef float TestScalar;
+
+ typedef Quaternion<RefScalar> Qd;
+ typedef Quaternion<TestScalar> Qf;
+
+ unsigned int g_seed = (unsigned int) time(NULL);
+ std::cout << g_seed << "\n";
+// g_seed = 1259932496;
+ srand(g_seed);
+
+ Matrix<RefScalar,Dynamic,1> maxerr(7);
+ maxerr.setZero();
+
+ Matrix<RefScalar,Dynamic,1> avgerr(7);
+ avgerr.setZero();
+
+ cout << "double=>float=>double nlerp eigen legacy(snap) legacy(nlerp) rightway gael's criteria\n";
+
+ int rep = 100;
+ int iters = 40;
+ for (int w=0; w<rep; ++w)
+ {
+ Qf a, b;
+ a.coeffs().setRandom();
+ a.normalize();
+ b.coeffs().setRandom();
+ b.normalize();
+
+ Qf c[6];
+
+ Qd ar(a.cast<RefScalar>());
+ Qd br(b.cast<RefScalar>());
+ Qd cr;
+
+
+
+ cout.precision(8);
+ cout << std::scientific;
+ for (int i=0; i<iters; ++i)
+ {
+ RefScalar t = 0.65;
+ cr = slerp_rw(ar,br,t);
+
+ Qf refc = cr.cast<TestScalar>();
+ c[0] = nlerp(a,b,t);
+ c[1] = slerp_eigen(a,b,t);
+ c[2] = slerp_legacy(a,b,t);
+ c[3] = slerp_legacy_nlerp(a,b,t);
+ c[4] = slerp_rw(a,b,t);
+ c[5] = slerp_gael(a,b,t);
+
+ VectorXd err(7);
+ err[0] = (cr.coeffs()-refc.cast<RefScalar>().coeffs()).norm();
+// std::cout << err[0] << " ";
+ for (int k=0; k<6; ++k)
+ {
+ err[k+1] = (c[k].coeffs()-refc.coeffs()).norm();
+// std::cout << err[k+1] << " ";
+ }
+ maxerr = maxerr.cwise().max(err);
+ avgerr += err;
+// std::cout << "\n";
+ b = cr.cast<TestScalar>();
+ br = cr;
+ }
+// std::cout << "\n";
+ }
+ avgerr /= RefScalar(rep*iters);
+ cout << "\n\nAccuracy:\n"
+ << " max: " << maxerr.transpose() << "\n";
+ cout << " avg: " << avgerr.transpose() << "\n";
+
+ // perf bench
+ Quaternionf a,b;
+ a.coeffs().setRandom();
+ a.normalize();
+ b.coeffs().setRandom();
+ b.normalize();
+ //b = a;
+ float s = 0.65;
+
+ #define BENCH(FUNC) {\
+ BenchTimer t; \
+ for(int k=0; k<2; ++k) {\
+ t.start(); \
+ for(int i=0; i<1000000; ++i) \
+ FUNC(a,b,s); \
+ t.stop(); \
+ } \
+ cout << " " << #FUNC << " => \t " << t.value() << "s\n"; \
+ }
+
+ cout << "\nSpeed:\n" << std::fixed;
+ BENCH(nlerp);
+ BENCH(slerp_eigen);
+ BENCH(slerp_legacy);
+ BENCH(slerp_legacy_nlerp);
+ BENCH(slerp_rw);
+ BENCH(slerp_gael);
+} \ No newline at end of file
diff --git a/blas/README.txt b/blas/README.txt
index 466a6751c..07a8bd92a 100644
--- a/blas/README.txt
+++ b/blas/README.txt
@@ -4,4 +4,6 @@ This directory contains a BLAS library built on top of Eigen.
This is currently a work in progress which is far to be ready for use,
but feel free to contribute to it if you wish.
-If you want to compile it, set the cmake variable EIGEN_BUILD_BLAS to "on".
+This module is not built by default. In order to compile it, you need to
+type 'make blas' from within your build dir.
+
diff --git a/blas/common.h b/blas/common.h
index 74c3c9f11..e7bfda570 100644
--- a/blas/common.h
+++ b/blas/common.h
@@ -76,17 +76,17 @@ extern "C"
using namespace Eigen;
template<typename T>
-Block<NestByValue<Map<Matrix<T,Dynamic,Dynamic> > >, Dynamic, Dynamic>
+Block<Map<Matrix<T,Dynamic,Dynamic> >, Dynamic, Dynamic>
matrix(T* data, int rows, int cols, int stride)
{
- return Map<Matrix<T,Dynamic,Dynamic> >(data, stride, cols).nestByValue().block(0,0,rows,cols);
+ return Map<Matrix<T,Dynamic,Dynamic> >(data, stride, cols).block(0,0,rows,cols);
}
template<typename T>
-Block<NestByValue<Map<Matrix<T,Dynamic,Dynamic,RowMajor> > >, Dynamic, 1>
+Block<Map<Matrix<T,Dynamic,Dynamic,RowMajor> >, Dynamic, 1>
vector(T* data, int size, int incr)
{
- return Map<Matrix<T,Dynamic,Dynamic,RowMajor> >(data, size, incr).nestByValue().col(0);
+ return Map<Matrix<T,Dynamic,Dynamic,RowMajor> >(data, size, incr).col(0);
}
template<typename T>
@@ -106,8 +106,8 @@ enum
Conj = IsComplex
};
-typedef Block<NestByValue<Map<Matrix<Scalar,Dynamic,Dynamic> > >, Dynamic, Dynamic> MatrixType;
-typedef Block<NestByValue<Map<Matrix<Scalar,Dynamic,Dynamic, RowMajor> > >, Dynamic, 1> StridedVectorType;
+typedef Block<Map<Matrix<Scalar,Dynamic,Dynamic> >, Dynamic, Dynamic> MatrixType;
+typedef Block<Map<Matrix<Scalar,Dynamic,Dynamic, RowMajor> >, Dynamic, 1> StridedVectorType;
typedef Map<Matrix<Scalar,Dynamic,1> > CompactVectorType;
#define EIGEN_BLAS_FUNC(X) EIGEN_CAT(SCALAR_SUFFIX,X##_)
diff --git a/cmake/EigenTesting.cmake b/cmake/EigenTesting.cmake
index 42f7454f4..b8cd63ac1 100644
--- a/cmake/EigenTesting.cmake
+++ b/cmake/EigenTesting.cmake
@@ -19,7 +19,7 @@ endmacro(ei_add_property)
#internal. See documentation of ei_add_test for details.
macro(ei_add_test_internal testname testname_with_suffix)
- set(targetname test_${testname_with_suffix})
+ set(targetname ${testname_with_suffix})
set(filename ${testname}.cpp)
add_executable(${targetname} ${filename})
@@ -79,8 +79,8 @@ endmacro(ei_add_test_internal)
#
# A. Default behavior
#
-# this macro add an executable test_<testname> as well as a ctest test
-# named <testname>.
+# this macro adds an executable <testname> as well as a ctest test
+# named <testname> too.
#
# On platforms with bash simply run:
# "ctest -V" or "ctest -V -R <testname>"
@@ -102,12 +102,15 @@ endmacro(ei_add_test_internal)
# executables is built passing -DEIGEN_TEST_PART_N. This allows to split large tests
# into smaller executables.
#
-# Moreover, targets test_<testname> are still generated, they
+# Moreover, targets <testname> are still generated, they
# have the effect of building all the parts of the test.
#
# Again, ctest -R allows to run all matching tests.
macro(ei_add_test testname)
- set(cmake_tests_list "${cmake_tests_list}${testname}\n")
+ get_property(EIGEN_TESTS_LIST GLOBAL PROPERTY EIGEN_TESTS_LIST)
+ set(EIGEN_TESTS_LIST "${EIGEN_TESTS_LIST}${testname}\n")
+ set_property(GLOBAL PROPERTY EIGEN_TESTS_LIST "${EIGEN_TESTS_LIST}")
+
file(READ "${testname}.cpp" test_source)
set(parts 0)
string(REGEX MATCHALL "CALL_SUBTEST_[0-9]+|EIGEN_TEST_PART_[0-9]+"
@@ -115,11 +118,11 @@ macro(ei_add_test testname)
string(REGEX REPLACE "CALL_SUBTEST_|EIGEN_TEST_PART_" "" suffixes "${occurences}")
list(REMOVE_DUPLICATES suffixes)
if(EIGEN_SPLIT_LARGE_TESTS AND suffixes)
- add_custom_target(test_${testname})
+ add_custom_target(${testname})
foreach(suffix ${suffixes})
ei_add_test_internal(${testname} ${testname}_${suffix}
"${ARGV1} -DEIGEN_TEST_PART_${suffix}=1" "${ARGV2}")
- add_dependencies(test_${testname} test_${testname}_${suffix})
+ add_dependencies(${testname} ${testname}_${suffix})
endforeach(suffix)
else(EIGEN_SPLIT_LARGE_TESTS AND suffixes)
set(symbols_to_enable_all_parts "")
@@ -147,33 +150,45 @@ macro(ei_testing_print_summary)
if(EIGEN_TEST_SSE2)
message("SSE2: ON")
- else(EIGEN_TEST_SSE2)
+ else()
message("SSE2: Using architecture defaults")
- endif(EIGEN_TEST_SSE2)
+ endif()
if(EIGEN_TEST_SSE3)
message("SSE3: ON")
- else(EIGEN_TEST_SSE3)
+ else()
message("SSE3: Using architecture defaults")
- endif(EIGEN_TEST_SSE3)
+ endif()
if(EIGEN_TEST_SSSE3)
message("SSSE3: ON")
- else(EIGEN_TEST_SSSE3)
+ else()
message("SSSE3: Using architecture defaults")
- endif(EIGEN_TEST_SSSE3)
+ endif()
+
+ if(EIGEN_TEST_SSE4_1)
+ message("SSE4.1: ON")
+ else()
+ message("SSE4.1: Using architecture defaults")
+ endif()
+
+ if(EIGEN_TEST_SSE4_2)
+ message("SSE4.2: ON")
+ else()
+ message("SSE4.2: Using architecture defaults")
+ endif()
if(EIGEN_TEST_ALTIVEC)
message("Altivec: Using architecture defaults")
- else(EIGEN_TEST_ALTIVEC)
+ else()
message("Altivec: Using architecture defaults")
- endif(EIGEN_TEST_ALTIVEC)
+ endif()
if(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)
message("Explicit vec: OFF")
- else(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)
+ else()
message("Explicit vec: Using architecture defaults")
- endif(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)
+ endif()
message("\n${EIGEN_TESTING_SUMMARY}")
# message("CXX: ${CMAKE_CXX_COMPILER}")
@@ -192,10 +207,12 @@ macro(ei_init_testing)
define_property(GLOBAL PROPERTY EIGEN_TESTED_BACKENDS BRIEF_DOCS " " FULL_DOCS " ")
define_property(GLOBAL PROPERTY EIGEN_MISSING_BACKENDS BRIEF_DOCS " " FULL_DOCS " ")
define_property(GLOBAL PROPERTY EIGEN_TESTING_SUMMARY BRIEF_DOCS " " FULL_DOCS " ")
+ define_property(GLOBAL PROPERTY EIGEN_TESTS_LIST BRIEF_DOCS " " FULL_DOCS " ")
set_property(GLOBAL PROPERTY EIGEN_TESTED_BACKENDS "")
set_property(GLOBAL PROPERTY EIGEN_MISSING_BACKENDS "")
set_property(GLOBAL PROPERTY EIGEN_TESTING_SUMMARY "")
+ set_property(GLOBAL PROPERTY EIGEN_TESTS_LIST "")
endmacro(ei_init_testing)
if(CMAKE_COMPILER_IS_GNUCXX)
@@ -205,9 +222,12 @@ if(CMAKE_COMPILER_IS_GNUCXX)
else(EIGEN_COVERAGE_TESTING)
set(COVERAGE_FLAGS "")
endif(EIGEN_COVERAGE_TESTING)
- if(EIGEN_TEST_RVALUE_REF_SUPPORT OR EIGEN_TEST_C++0x)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
- endif(EIGEN_TEST_RVALUE_REF_SUPPORT OR EIGEN_TEST_C++0x)
+ if(EIGEN_TEST_C++0x)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")
+ endif(EIGEN_TEST_C++0x)
+ if(EIGEN_TEST_MAX_WARNING_LEVEL)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion")
+ endif(EIGEN_TEST_MAX_WARNING_LEVEL)
if(CMAKE_SYSTEM_NAME MATCHES Linux)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_FLAGS} -g2")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COVERAGE_FLAGS} -O2 -g2")
@@ -215,5 +235,10 @@ if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COVERAGE_FLAGS} -O0 -g3")
endif(CMAKE_SYSTEM_NAME MATCHES Linux)
elseif(MSVC)
- set(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /MDd /Zi /Ob0 /Od" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS")
+ if(EIGEN_TEST_MAX_WARNING_LEVEL)
+ # C4127 - conditional expression is constant
+ # C4505 - unreferenced local function has been removed
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /wd4127 /wd4505")
+ endif(EIGEN_TEST_MAX_WARNING_LEVEL)
endif(CMAKE_COMPILER_IS_GNUCXX)
diff --git a/cmake/FindEigen2.cmake b/cmake/FindEigen2.cmake
index ee054b0da..da95bb0f5 100644
--- a/cmake/FindEigen2.cmake
+++ b/cmake/FindEigen2.cmake
@@ -29,13 +29,13 @@ if(NOT Eigen2_FIND_VERSION)
endif(NOT Eigen2_FIND_VERSION)
macro(_eigen2_check_version)
- file(READ "${EIGEN2_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen2_version_header LIMIT 5000 OFFSET 1000)
+ file(READ "${EIGEN2_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen2_version_header)
- string(REGEX MATCH "define *EIGEN_WORLD_VERSION ([0-9]*)" _eigen2_world_version_match "${_eigen2_version_header}")
+ string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen2_world_version_match "${_eigen2_version_header}")
set(EIGEN2_WORLD_VERSION "${CMAKE_MATCH_1}")
- string(REGEX MATCH "define *EIGEN_MAJOR_VERSION ([0-9]*)" _eigen2_major_version_match "${_eigen2_version_header}")
+ string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen2_major_version_match "${_eigen2_version_header}")
set(EIGEN2_MAJOR_VERSION "${CMAKE_MATCH_1}")
- string(REGEX MATCH "define *EIGEN_MINOR_VERSION ([0-9]*)" _eigen2_minor_version_match "${_eigen2_version_header}")
+ string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen2_minor_version_match "${_eigen2_version_header}")
set(EIGEN2_MINOR_VERSION "${CMAKE_MATCH_1}")
set(EIGEN2_VERSION ${EIGEN2_WORLD_VERSION}.${EIGEN2_MAJOR_VERSION}.${EIGEN2_MINOR_VERSION})
diff --git a/cmake/FindEigen3.cmake b/cmake/FindEigen3.cmake
new file mode 100644
index 000000000..b87ebff4b
--- /dev/null
+++ b/cmake/FindEigen3.cmake
@@ -0,0 +1,80 @@
+# - Try to find Eigen3 lib
+#
+# This module supports requiring a minimum version, e.g. you can do
+# find_package(Eigen3 3.1.2)
+# to require version 3.1.2 or newer of Eigen3.
+#
+# Once done this will define
+#
+# EIGEN3_FOUND - system has eigen lib with correct version
+# EIGEN3_INCLUDE_DIR - the eigen include directory
+# EIGEN3_VERSION - eigen version
+
+# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org>
+# Copyright (c) 2008, 2009 Gael Guennebaud, <g.gael@free.fr>
+# Redistribution and use is allowed according to the terms of the BSD license.
+
+if(NOT Eigen3_FIND_VERSION)
+ if(NOT Eigen3_FIND_VERSION_MAJOR)
+ set(Eigen3_FIND_VERSION_MAJOR 2)
+ endif(NOT Eigen3_FIND_VERSION_MAJOR)
+ if(NOT Eigen3_FIND_VERSION_MINOR)
+ set(Eigen3_FIND_VERSION_MINOR 91)
+ endif(NOT Eigen3_FIND_VERSION_MINOR)
+ if(NOT Eigen3_FIND_VERSION_PATCH)
+ set(Eigen3_FIND_VERSION_PATCH 0)
+ endif(NOT Eigen3_FIND_VERSION_PATCH)
+
+ set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}")
+endif(NOT Eigen3_FIND_VERSION)
+
+macro(_eigen3_check_version)
+ file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header)
+
+ string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}")
+ set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}")
+ string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}")
+ set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}")
+ string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}")
+ set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}")
+
+ set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION})
+ if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
+ set(EIGEN3_VERSION_OK FALSE)
+ else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
+ set(EIGEN3_VERSION_OK TRUE)
+ endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
+
+ if(NOT EIGEN3_VERSION_OK)
+
+ message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, "
+ "but at least version ${Eigen3_FIND_VERSION} is required")
+ endif(NOT EIGEN3_VERSION_OK)
+endmacro(_eigen3_check_version)
+
+if (EIGEN3_INCLUDE_DIR)
+
+ # in cache already
+ _eigen3_check_version()
+ set(EIGEN3_FOUND ${EIGEN3_VERSION_OK})
+
+else (EIGEN3_INCLUDE_DIR)
+
+ find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library
+ PATHS
+ ${CMAKE_INSTALL_PREFIX}/include
+ ${KDE4_INCLUDE_DIR}
+ PATH_SUFFIXES eigen3 eigen
+ )
+
+ if(EIGEN3_INCLUDE_DIR)
+ _eigen3_check_version()
+ endif(EIGEN3_INCLUDE_DIR)
+
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK)
+
+ mark_as_advanced(EIGEN3_INCLUDE_DIR)
+
+endif(EIGEN3_INCLUDE_DIR)
+
diff --git a/debug/gdb/__init__.py b/debug/gdb/__init__.py
new file mode 100644
index 000000000..bb7b160de
--- /dev/null
+++ b/debug/gdb/__init__.py
@@ -0,0 +1 @@
+# Intentionally empty
diff --git a/debug/gdb/printers.py b/debug/gdb/printers.py
new file mode 100644
index 000000000..9f6cfa5d5
--- /dev/null
+++ b/debug/gdb/printers.py
@@ -0,0 +1,161 @@
+# -*- coding: utf-8 -*-
+# This file is part of Eigen, a lightweight C++ template library
+# for linear algebra.
+#
+# Copyright (C) 2009 Benjamin Schindler <bschindler@inf.ethz.ch>
+#
+# Eigen is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 3 of the License, or (at your option) any later version.
+#
+# Alternatively, you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License and a copy of the GNU General Public License along with
+# Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+# Pretty printers for Eigen::Matrix
+# This is still pretty basic as the python extension to gdb is still pretty basic.
+# It cannot handle complex eigen types and it doesn't support any of the other eigen types
+# Such as quaternion or some other type.
+# This code supports fixed size as well as dynamic size matrices
+
+# To use it:
+#
+# * create a directory and put the file as well as an empty __init__.py in that directory
+# * Create a ~/.gdbinit file, that contains the following:
+
+
+import gdb
+import re
+import itertools
+
+
+class EigenMatrixPrinter:
+ "Print Eigen Matrix of some kind"
+
+ def __init__(self, val):
+ "Extract all the necessary information"
+ # The gdb extension does not support value template arguments - need to extract them by hand
+ type = val.type
+ if type.code == gdb.TYPE_CODE_REF:
+ type = type.target()
+ self.type = type.unqualified().strip_typedefs()
+ tag = self.type.tag
+ regex = re.compile('\<.*\>')
+ m = regex.findall(tag)[0][1:-1]
+ template_params = m.split(',')
+ template_params = map(lambda x:x.replace(" ", ""), template_params)
+
+ self.rows = int(template_params[1])
+ self.cols = int(template_params[2])
+ self.options = 0 # default value
+ if len(template_params) > 3:
+ self.options = template_params[3];
+
+ self.rowMajor = (int(self.options) & 0x1)
+
+ if self.rows == 10000:
+ self.rows = val['m_storage']['m_rows']
+
+ if self.cols == 10000:
+ self.cols = val['m_storage']['m_cols']
+
+ self.innerType = self.type.template_argument(0)
+
+ self.val = val
+
+ # Fixed size matrices have a struct as their storage, so we need to walk through this
+ self.data = self.val['m_storage']['m_data']
+ if self.data.type.code == gdb.TYPE_CODE_STRUCT:
+ self.data = self.data['array']
+ self.data = self.data.cast(self.innerType.pointer())
+
+ class _iterator:
+ def __init__ (self, rows, cols, dataPtr, rowMajor):
+ self.rows = rows
+ self.cols = cols
+ self.dataPtr = dataPtr
+ self.currentRow = 0
+ self.currentCol = 0
+ self.rowMajor = rowMajor
+
+ def __iter__ (self):
+ return self
+
+ def next(self):
+
+ row = self.currentRow
+ col = self.currentCol
+ if self.rowMajor == 0:
+ if self.currentCol >= self.cols:
+ raise StopIteration
+
+ self.currentRow = self.currentRow + 1
+ if self.currentRow >= self.rows:
+ self.currentRow = 0
+ self.currentCol = self.currentCol + 1
+ else:
+ if self.currentRow >= self.rows:
+ raise StopIteration
+
+ self.currentCol = self.currentCol + 1
+ if self.currentCol >= self.cols:
+ self.currentCol = 0
+ self.currentRow = self.currentRow + 1
+
+
+ item = self.dataPtr.dereference()
+ self.dataPtr = self.dataPtr + 1
+
+ return ('[%d, %d]' % (row, col), item)
+
+ def children(self):
+
+ return self._iterator(self.rows, self.cols, self.data, self.rowMajor)
+
+ def to_string(self):
+ return "Eigen::Matrix<%s,%d,%d,%s> (data ptr: %s)" % (self.innerType, self.rows, self.cols, "RowMajor" if self.rowMajor else "ColMajor", self.data)
+
+def build_eigen_dictionary ():
+ pretty_printers_dict[re.compile('^Eigen::Matrix<.*>$')] = lambda val: EigenMatrixPrinter(val)
+
+def register_eigen_printers(obj):
+ "Register eigen pretty-printers with objfile Obj"
+
+ if obj == None:
+ obj = gdb
+ obj.pretty_printers.append(lookup_function)
+
+def lookup_function(val):
+ "Look-up and return a pretty-printer that can print va."
+
+ type = val.type
+
+ if type.code == gdb.TYPE_CODE_REF:
+ type = type.target()
+
+ type = type.unqualified().strip_typedefs()
+
+ typename = type.tag
+ if typename == None:
+ return None
+
+ for function in pretty_printers_dict:
+ if function.search(typename):
+ return pretty_printers_dict[function](val)
+
+ return None
+
+pretty_printers_dict = {}
+
+build_eigen_dictionary ()
diff --git a/debug/msvc/eigen_autoexp_part.dat b/debug/msvc/eigen_autoexp_part.dat
new file mode 100644
index 000000000..394397e5d
--- /dev/null
+++ b/debug/msvc/eigen_autoexp_part.dat
@@ -0,0 +1,306 @@
+; ***************************************************************
+; * Eigen Visualizer
+; *
+; * Author: Hauke Heibel <hauke.heibel@gmail.com>
+; *
+; * Support the enhanced debugging of the following Eigen
+; * types (*: any, +:fixed dimension) :
+; *
+; * - Eigen::Matrix<*,4,1,*,*,*> and Eigen::Matrix<*,1,4,*,*,*>
+; * - Eigen::Matrix<*,3,1,*,*,*> and Eigen::Matrix<*,1,3,*,*,*>
+; * - Eigen::Matrix<*,2,1,*,*,*> and Eigen::Matrix<*,1,2,*,*,*>
+; * - Eigen::Matrix<*,33331,33331,*,*,*>
+; * - Eigen::Matrix<*,+,33331,*,*,*>
+; * - Eigen::Matrix<*,33331,+,*,*,*>
+; * - Eigen::Matrix<*,+,+,*,*,*>
+; *
+; * Matrices are displayed properly independantly of the memory
+; * alignment (RowMajor vs. ColMajor).
+; *
+; * This file is distributed WITHOUT ANY WARRANTY. Please ensure
+; * that your original autoexp.dat file is copied to a safe
+; * place before proceeding with its modification.
+; ***************************************************************
+
+; Fixed size 4-vectors
+Eigen::Matrix<*,4,1,*,*,*>|Eigen::Matrix<*,1,4,*,*,*>{
+ children
+ (
+ #(
+ [internals]: [$c,!],
+ x : ($c.m_storage.m_data.array)[0],
+ y : ($c.m_storage.m_data.array)[1],
+ z : ($c.m_storage.m_data.array)[2],
+ w : ($c.m_storage.m_data.array)[3]
+ )
+ )
+
+ preview
+ (
+ #(
+ "(",
+
+ #array
+ (
+ expr : [($c.m_storage.m_data.array)[$i],g],
+ size : 4
+ ),
+ ")"
+ )
+ )
+}
+
+; Fixed size 3-vectors
+Eigen::Matrix<*,3,1,*,*,*>|Eigen::Matrix<*,1,3,*,*,*>{
+ children
+ (
+ #(
+ [internals]: [$c,!],
+ x : ($c.m_storage.m_data.array)[0],
+ y : ($c.m_storage.m_data.array)[1],
+ z : ($c.m_storage.m_data.array)[2]
+ )
+ )
+
+ preview
+ (
+ #(
+ "(",
+
+ #array
+ (
+ expr : [($c.m_storage.m_data.array)[$i],g],
+ size : 3
+ ),
+ ")"
+ )
+ )
+}
+
+; Fixed size floating point 2-vectors
+Eigen::Matrix<float,2,1,*,*,*>|Eigen::Matrix<float,1,2,*,*,*>|Eigen::Matrix<double,2,1,*,*,*>|Eigen::Matrix<double,1,2,*,*,*>{
+ children
+ (
+ #(
+ [internals]: [$c,!],
+ x : ($c.m_storage.m_data.array)[0],
+ y : ($c.m_storage.m_data.array)[1]
+ )
+ )
+
+ preview
+ (
+ #(
+ "(",
+
+ #array
+ (
+ expr : [($c.m_storage.m_data.array)[$i],g],
+ size : 2
+ ),
+ ")"
+ )
+ )
+}
+
+; Fixed size integral 2-vectors
+Eigen::Matrix<*,2,1,*,*,*>|Eigen::Matrix<*,1,2,*,*,*>{
+ children
+ (
+ #(
+ [internals]: [$c,!],
+ x : ($c.m_storage.m_data.array)[0],
+ y : ($c.m_storage.m_data.array)[1]
+ )
+ )
+
+ preview
+ (
+ #(
+ "(",
+
+ #array
+ (
+ expr : ($c.m_storage.m_data.array)[$i],
+ size : 2
+ ),
+ ")"
+ )
+ )
+}
+
+; Dynamic matrices (ColMajor and RowMajor support)
+Eigen::Matrix<*,33331,33331,*,*,*>{
+ children
+ (
+ #(
+ [internals]: [$c,!],
+ rows: $c.m_storage.m_rows,
+ cols: $c.m_storage.m_cols,
+ ; Check for RowMajorBit
+ #if ($c.Flags & 0x1) (
+ #array(
+ rank: 2,
+ base: 0,
+ expr: ($c.m_storage.m_data)[($i % $c.m_storage.m_rows)*$c.m_storage.m_cols + (($i- $i % $c.m_storage.m_rows)/$c.m_storage.m_rows)],
+ size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.m_storage.m_cols
+ )
+ ) #else (
+ #array(
+ rank: 2,
+ base: 0,
+ expr: ($c.m_storage.m_data)[$i],
+ size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.m_storage.m_cols
+ )
+ )
+ )
+ )
+
+ preview
+ (
+ #(
+ "[",
+ $c.m_storage.m_rows,
+ ",",
+ $c.m_storage.m_cols,
+ "](",
+ #array(
+ expr : [($c.m_storage.m_data)[$i],g],
+ size : $c.m_storage.m_rows*$c.m_storage.m_cols
+ ),
+ ")"
+ )
+ )
+}
+
+; Fixed rows, dynamic columns matrix (ColMajor and RowMajor support)
+Eigen::Matrix<*,*,33331,*,*,*>{
+ children
+ (
+ #(
+ [internals]: [$c,!],
+ rows: $c.RowsAtCompileTime,
+ cols: $c.m_storage.m_cols,
+ ; Check for RowMajorBit
+ #if ($c.Flags & 0x1) (
+ #array(
+ rank: 2,
+ base: 0,
+ expr: ($c.m_storage.m_data)[($i % $c.RowsAtCompileTime)*$c.m_storage.m_cols + (($i- $i % $c.RowsAtCompileTime)/$c.RowsAtCompileTime)],
+ size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.m_storage.m_cols
+ )
+ ) #else (
+ #array(
+ rank: 2,
+ base: 0,
+ expr: ($c.m_storage.m_data)[$i],
+ size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.m_storage.m_cols
+ )
+ )
+ )
+ )
+
+ preview
+ (
+ #(
+ "[",
+ $c.RowsAtCompileTime,
+ ",",
+ $c.m_storage.m_cols,
+ "](",
+ #array(
+ expr : [($c.m_storage.m_data)[$i],g],
+ size : $c.RowsAtCompileTime*$c.m_storage.m_cols
+ ),
+ ")"
+ )
+ )
+}
+
+; Dynamic rows, fixed columns matrix (ColMajor and RowMajor support)
+Eigen::Matrix<*,33331,*,*,*,*>{
+ children
+ (
+ #(
+ [internals]: [$c,!],
+ rows: $c.m_storage.m_rows,
+ cols: $c.ColsAtCompileTime,
+ ; Check for RowMajorBit
+ #if ($c.Flags & 0x1) (
+ #array(
+ rank: 2,
+ base: 0,
+ expr: ($c.m_storage.m_data)[($i % $c.m_storage.m_rows)*$c.ColsAtCompileTime + (($i- $i % $c.m_storage.m_rows)/$c.m_storage.m_rows)],
+ size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.ColsAtCompileTime
+ )
+ ) #else (
+ #array(
+ rank: 2,
+ base: 0,
+ expr: ($c.m_storage.m_data)[$i],
+ size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.ColsAtCompileTime
+ )
+ )
+ )
+ )
+
+ preview
+ (
+ #(
+ "[",
+ $c.m_storage.m_rows,
+ ",",
+ $c.ColsAtCompileTime,
+ "](",
+ #array(
+ expr : [($c.m_storage.m_data)[$i],g],
+ size : $c.m_storage.m_rows*$c.ColsAtCompileTime
+ ),
+ ")"
+ )
+ )
+}
+
+; Fixed size matrix (ColMajor and RowMajor support)
+Eigen::Matrix<*,*,*,*,*,*>{
+ children
+ (
+ #(
+ [internals]: [$c,!],
+ rows: $c.RowsAtCompileTime,
+ cols: $c.ColsAtCompileTime,
+ ; Check for RowMajorBit
+ #if ($c.Flags & 0x1) (
+ #array(
+ rank: 2,
+ base: 0,
+ expr: ($c.m_storage.m_data.array)[($i % $c.RowsAtCompileTime)*$c.ColsAtCompileTime + (($i- $i % $c.RowsAtCompileTime)/$c.RowsAtCompileTime)],
+ size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.ColsAtCompileTime
+ )
+ ) #else (
+ #array(
+ rank: 2,
+ base: 0,
+ expr: ($c.m_storage.m_data.array)[$i],
+ size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.ColsAtCompileTime
+ )
+ )
+ )
+ )
+
+ preview
+ (
+ #(
+ "[",
+ $c.RowsAtCompileTime,
+ ",",
+ $c.ColsAtCompileTime,
+ "](",
+ #array(
+ expr : [($c.m_storage.m_data.array)[$i],g],
+ size : $c.RowsAtCompileTime*$c.ColsAtCompileTime
+ ),
+ ")"
+ )
+ )
+}
diff --git a/doc/C01_QuickStartGuide.dox b/doc/C01_QuickStartGuide.dox
index 06b2595e7..7c4aa8f76 100644
--- a/doc/C01_QuickStartGuide.dox
+++ b/doc/C01_QuickStartGuide.dox
@@ -36,7 +36,7 @@ In order to use Eigen, you just need to download and extract Eigen's source code
Here are some quick compilation instructions with GCC. To quickly test an example program, just do
-\code g++ -I /path/to/eigen2/ my_program.cpp -o my_program \endcode
+\code g++ -I /path/to/eigen/ my_program.cpp -o my_program \endcode
There is no library to link to. For good performance, add the \c -O2 compile-flag. Note however that this makes it impossible to debug inside Eigen code, as many functions get inlined. In some cases, performance can be further improved by disabling Eigen assertions: use \c -DEIGEN_NO_DEBUG or \c -DNDEBUG to disable them.
@@ -470,7 +470,7 @@ mat = 2 7 8
Also note that maxCoeff and minCoeff can takes optional arguments returning the coordinates of the respective min/max coeff: \link MatrixBase::maxCoeff(int*,int*) const maxCoeff(int* i, int* j) \endlink, \link MatrixBase::minCoeff(int*,int*) const minCoeff(int* i, int* j) \endlink.
-<span class="note">\b Side \b note: The all() and any() functions are especially useful in combination with coeff-wise comparison operators (\ref CwiseAll "example").</span>
+<span class="note">\b Side \b note: The all() and any() functions are especially useful in combination with coeff-wise comparison operators.</span>
diff --git a/doc/C05_TutorialLinearAlgebra.dox b/doc/C05_TutorialLinearAlgebra.dox
index c50e9c6bc..5bae00b7e 100644
--- a/doc/C05_TutorialLinearAlgebra.dox
+++ b/doc/C05_TutorialLinearAlgebra.dox
@@ -69,9 +69,9 @@ As an example, suppose we want to solve the following system of linear equations
The following program solves this system:
<table class="tutorial_code"><tr><td>
-\include Tutorial_PartialPivLU_solve.cpp
+\include Tutorial_PartialLU_solve.cpp
</td><td>
-output: \include Tutorial_PartialPivLU_solve.out
+output: \include Tutorial_PartialLU_solve.out
</td></tr></table>
There are many situations in which we want to solve the same system of equations with different
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 1d20a6075..af756a516 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -63,7 +63,7 @@ add_custom_target(
)
add_dependencies(doc-eigen-prerequisites all_snippets all_examples)
-# add_dependencies(doc-unsupported-prerequisites unsupported_snippets unsupported_examples)
+add_dependencies(doc-unsupported-prerequisites unsupported_snippets unsupported_examples)
add_custom_target(doc ALL
COMMAND doxygen Doxyfile-unsupported
COMMAND doxygen
diff --git a/doc/D11_UnalignedArrayAssert.dox b/doc/D11_UnalignedArrayAssert.dox
index 226b20452..f4da15236 100644
--- a/doc/D11_UnalignedArrayAssert.dox
+++ b/doc/D11_UnalignedArrayAssert.dox
@@ -4,7 +4,7 @@ namespace Eigen {
Hello! You are seeing this webpage because your program terminated on an assertion failure like this one:
<pre>
-my_program: path/to/eigen2/Eigen/src/Core/MatrixStorage.h:44:
+my_program: path/to/eigen/Eigen/src/Core/MatrixStorage.h:44:
Eigen::ei_matrix_array<T, Size, MatrixOptions, Align>::ei_matrix_array()
[with T = double, int Size = 2, int MatrixOptions = 2, bool Align = true]:
Assertion `(reinterpret_cast<size_t>(array) & 0xf) == 0 && "this assertion
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
index da99d3592..64bb7bd01 100644
--- a/doc/Doxyfile.in
+++ b/doc/Doxyfile.in
@@ -1,11 +1,3 @@
-################################################################################
-## ##
-## WARNING ##
-## ##
-## all modifications in this file must be reported in eigen2/Mainpage.dox ##
-## ##
-################################################################################
-
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project
#
@@ -205,20 +197,22 @@ TAB_SIZE = 8
ALIASES = "only_for_vectors=This is only for vectors (either row-vectors or column-vectors), i.e. matrices which are known at compile-time to have either one row or one column." \
"array_module=This is defined in the %Array module. \code #include <Eigen/Array> \endcode" \
- "lu_module=This is defined in the %LU module. \code #include <Eigen/LU> \endcode" \
"cholesky_module=This is defined in the %Cholesky module. \code #include <Eigen/Cholesky> \endcode" \
- "qr_module=This is defined in the %QR module. \code #include <Eigen/QR> \endcode" \
- "jacobi_module=This is defined in the %Jacobi module. \code #include <Eigen/Jacobi> \endcode" \
- "svd_module=This is defined in the %SVD module. \code #include <Eigen/SVD> \endcode" \
+ "eigenvalues_module=This is defined in the %Eigenvalues module. \code #include <Eigen/Eigenvalues> \endcode" \
"geometry_module=This is defined in the %Geometry module. \code #include <Eigen/Geometry> \endcode" \
+ "householder_module=This is defined in the %Householder module. \code #include <Eigen/Householder> \endcode" \
+ "jacobi_module=This is defined in the %Jacobi module. \code #include <Eigen/Jacobi> \endcode" \
"leastsquares_module=This is defined in the %LeastSquares module. \code #include <Eigen/LeastSquares> \endcode" \
- "eigenvalues_module=This is defined in the %Eigenvalues module. \code #include <Eigen/Eigenvalues> \endcode" \
+ "lu_module=This is defined in the %LU module. \code #include <Eigen/LU> \endcode" \
+ "qr_module=This is defined in the %QR module. \code #include <Eigen/QR> \endcode" \
+ "svd_module=This is defined in the %SVD module. \code #include <Eigen/SVD> \endcode" \
"label=\bug" \
"redstar=<a href='#warningarraymodule' style='color:red;text-decoration: none;'>*</a>" \
"nonstableyet=\warning This is not considered to be part of the stable public API yet. Changes may happen in future releases. See \ref Experimental \"Experimental parts of Eigen\"" \
"note_about_arbitrary_choice_of_solution=If there exists more than one solution, this method will arbitrarily choose one." \
"note_about_using_kernel_to_study_multiple_solutions=If you need a complete analysis of the space of solutions, take the one solution obtained by this method and add to it elements of the kernel, as determined by kernel()." \
- "note_about_checking_solutions=This method just tries to find as good a solution as possible. If you want to check whether a solution exists or if it is accurate, just call this function to get a result and then compute the error of this result, or use MatrixBase::isApprox() directly, for instance like this: \code bool a_solution_exists = (A*result).isApprox(b, precision); \endcode This method avoids dividing by zero, so that the non-existence of a solution doesn't by itself mean that you'll get \c inf or \c nan values."
+ "note_about_checking_solutions=This method just tries to find as good a solution as possible. If you want to check whether a solution exists or if it is accurate, just call this function to get a result and then compute the error of this result, or use MatrixBase::isApprox() directly, for instance like this: \code bool a_solution_exists = (A*result).isApprox(b, precision); \endcode This method avoids dividing by zero, so that the non-existence of a solution doesn't by itself mean that you'll get \c inf or \c nan values." \
+ "note_try_to_help_rvo=This function returns the result by value. In order to make that efficient, it is implemented as just a return statement using a special constructor, hopefully allowing the compiler to perform a RVO (return value optimization)."
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
# sources only. Doxygen will then generate output that is more tailored for C.
@@ -614,8 +608,9 @@ EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = CMake* \
*.txt \
*.sh \
+ *.orig \
*.diff \
- diff
+ diff \
*~
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
diff --git a/doc/I00_CustomizingEigen.dox b/doc/I00_CustomizingEigen.dox
index 7c8ba9b75..ede6f23b7 100644
--- a/doc/I00_CustomizingEigen.dox
+++ b/doc/I00_CustomizingEigen.dox
@@ -2,7 +2,7 @@ namespace Eigen {
/** \page CustomizingEigen Advanced - Customizing/Extending Eigen
-Eigen2 can be extended in several ways, for instance, by defining global methods, \ref ExtendingMatrixBase "by adding custom methods to MatrixBase", adding support to \ref CustomScalarType "custom types" etc.
+Eigen can be extended in several ways, for instance, by defining global methods, \ref ExtendingMatrixBase "by adding custom methods to MatrixBase", adding support to \ref CustomScalarType "custom types" etc.
\b Table \b of \b contents
- \ref ExtendingMatrixBase
diff --git a/doc/I01_TopicLazyEvaluation.dox b/doc/I01_TopicLazyEvaluation.dox
index f40afa06d..68fa1e2df 100644
--- a/doc/I01_TopicLazyEvaluation.dox
+++ b/doc/I01_TopicLazyEvaluation.dox
@@ -36,7 +36,7 @@ Here is now a more involved example:
Eigen chooses lazy evaluation at every stage in that example, which is clearly the correct choice. In fact, lazy evaluation is the "default choice" and Eigen will choose it except in a few circumstances.
-<b>The first circumstance</b> in which Eigen chooses immediate evaluation, is when it sees an assignment <tt>a = b;</tt> and the expression \c b has the evaluate-before-assigning \link flags flag\endlink. The most important example of such an expression is the \link Product matrix product expression\endlink. For example, when you do
+<b>The first circumstance</b> in which Eigen chooses immediate evaluation, is when it sees an assignment <tt>a = b;</tt> and the expression \c b has the evaluate-before-assigning \link flags flag\endlink. The most important example of such an expression is the \link GeneralProduct matrix product expression\endlink. For example, when you do
\code matrix = matrix * matrix; \endcode
@@ -48,7 +48,7 @@ What if you know that the result does no alias the operand of the product and wa
Here, since we know that matrix2 is not the same matrix as matrix1, we know that lazy evaluation is not dangerous, so we may force lazy evaluation. Concretely, the effect of noalias() here is to bypass the evaluate-before-assigning \link flags flag\endlink.
-<b>The second circumstance</b> in which Eigen chooses immediate evaluation, is when it sees a nested expression such as <tt>a + b</tt> where \c b is already an expression having the evaluate-before-nesting \link flags flag\endlink. Again, the most important example of such an expression is the \link Product matrix product expression\endlink. For example, when you do
+<b>The second circumstance</b> in which Eigen chooses immediate evaluation, is when it sees a nested expression such as <tt>a + b</tt> where \c b is already an expression having the evaluate-before-nesting \link flags flag\endlink. Again, the most important example of such an expression is the \link GeneralProduct matrix product expression\endlink. For example, when you do
\code matrix1 = matrix2 + matrix3 * matrix4; \endcode
@@ -62,4 +62,4 @@ Here, provided the matrices have at least 2 rows and 2 columns, each coefficienc
*/
-} \ No newline at end of file
+}
diff --git a/doc/Overview.dox b/doc/Overview.dox
index db0d9587a..78bf5f9dd 100644
--- a/doc/Overview.dox
+++ b/doc/Overview.dox
@@ -15,7 +15,7 @@ For a first contact with Eigen, the best place is to have a look at the \ref Tut
Most of the API is available as methods in MatrixBase, so this is a good starting point for browsing. Also have a look at Matrix, as a few methods and the matrix constructors are there. Other notable classes for the Eigen API are Cwise, which contains the methods for doing certain coefficient-wise operations, and Part.
-In fact, except for advanced use, the only class that you'll have to explicitly name in your program, i.e. of which you'll explicitly contruct objects, is Matrix. For instance, vectors are handled as a special case of Matrix with one column. Typedefs are provided, e.g. Vector2f is a typedef for Matrix<float, 2, 1>. Finally, you might also have look at the \ref ExampleList "the list of selected examples".
+In fact, except for advanced use, the only class that you'll have to explicitly name in your program, i.e. of which you'll explicitly contruct objects, is Matrix. For instance, vectors are handled as a special case of Matrix with one column. Typedefs are provided, e.g. Vector2f is a typedef for Matrix<float, 2, 1>.
Most of the other classes are just return types for MatrixBase methods.
diff --git a/doc/examples/class_CwiseBinaryOp.cpp b/doc/examples/class_CwiseBinaryOp.cpp
index fb9b2ff09..7ca5bf6ef 100644
--- a/doc/examples/class_CwiseBinaryOp.cpp
+++ b/doc/examples/class_CwiseBinaryOp.cpp
@@ -4,7 +4,8 @@ USING_PART_OF_NAMESPACE_EIGEN
using namespace std;
// define a custom template binary functor
-template<typename Scalar> struct MakeComplexOp EIGEN_EMPTY_STRUCT {
+template<typename Scalar> struct MakeComplexOp {
+ EIGEN_EMPTY_STRUCT_CTOR(MakeComplexOp)
typedef complex<Scalar> result_type;
complex<Scalar> operator()(const Scalar& a, const Scalar& b) const { return complex<Scalar>(a,b); }
};
diff --git a/doc/snippets/MatrixBase_extract.cpp b/doc/snippets/MatrixBase_extract.cpp
index a5ccd7574..c96220f72 100644
--- a/doc/snippets/MatrixBase_extract.cpp
+++ b/doc/snippets/MatrixBase_extract.cpp
@@ -1,4 +1,6 @@
-#warning deprecated
+#ifndef _MSC_VER
+ #warning deprecated
+#endif
/* deprecated
Matrix3i m = Matrix3i::Random();
cout << "Here is the matrix m:" << endl << m << endl;
diff --git a/doc/snippets/MatrixBase_marked.cpp b/doc/snippets/MatrixBase_marked.cpp
index f536773c9..f60712178 100644
--- a/doc/snippets/MatrixBase_marked.cpp
+++ b/doc/snippets/MatrixBase_marked.cpp
@@ -1,4 +1,6 @@
-#warning deprecated
+#ifndef _MSC_VER
+ #warning deprecated
+#endif
/*
Matrix3d m = Matrix3d::Zero();
m.part<Eigen::UpperTriangular>().setOnes();
diff --git a/doc/snippets/MatrixBase_part.cpp b/doc/snippets/MatrixBase_part.cpp
index 81e66c4cd..d3e7f482e 100644
--- a/doc/snippets/MatrixBase_part.cpp
+++ b/doc/snippets/MatrixBase_part.cpp
@@ -1,4 +1,6 @@
-#warning deprecated
+#ifndef _MSC_VER
+ #warning deprecated
+#endif
/*
Matrix3d m = Matrix3d::Zero();
m.part<Eigen::StrictlyUpperTriangular>().setOnes();
diff --git a/doc/snippets/PartialLU_solve.cpp b/doc/snippets/PartialPivLU_solve.cpp
index fa3570ab8..fa3570ab8 100644
--- a/doc/snippets/PartialLU_solve.cpp
+++ b/doc/snippets/PartialPivLU_solve.cpp
diff --git a/doc/snippets/class_FullPivLU.cpp b/doc/snippets/class_FullPivLU.cpp
index 40d76e8e6..855782d15 100644
--- a/doc/snippets/class_FullPivLU.cpp
+++ b/doc/snippets/class_FullPivLU.cpp
@@ -13,8 +13,4 @@ cout << "Here is the U part:" << endl;
Matrix5x3 u = lu.matrixLU().part<UpperTriangular>();
cout << u << endl;
cout << "Let us now reconstruct the original matrix m:" << endl;
-Matrix5x3 x = l * u;
-Matrix5x3 y;
-for(int i = 0; i < 5; i++) for(int j = 0; j < 3; j++)
- y(i, lu.permutationQ()[j]) = x(lu.permutationP()[i], j);
-cout << y << endl; // should be equal to the original matrix m
+cout << lu.permutationP().inverse() * l * u * lu.permutationQ().inverse() << endl;
diff --git a/eigen2.pc.in b/eigen3.pc.in
index b508a58d3..c5855de33 100644
--- a/eigen2.pc.in
+++ b/eigen3.pc.in
@@ -1,5 +1,4 @@
-
-Name: Eigen2
+Name: Eigen3
Description: A C++ template library for linear algebra: vectors, matrices, and related algorithms
Requires:
Version: ${EIGEN_VERSION_NUMBER}
diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
index b75e99d5e..acf3bb6e9 100644
--- a/scripts/CMakeLists.txt
+++ b/scripts/CMakeLists.txt
@@ -1,3 +1,6 @@
+get_property(EIGEN_TESTS_LIST GLOBAL PROPERTY EIGEN_TESTS_LIST)
+configure_file(buildtests.in ${CMAKE_BINARY_DIR}/buildtests)
+
configure_file(check.in ${CMAKE_BINARY_DIR}/check)
configure_file(debug.in ${CMAKE_BINARY_DIR}/debug)
configure_file(release.in ${CMAKE_BINARY_DIR}/release)
diff --git a/test/buildtests.in b/scripts/buildtests.in
index 52cc66281..3c4282848 100755
--- a/test/buildtests.in
+++ b/scripts/buildtests.in
@@ -3,19 +3,22 @@
if [ $# == 0 -o $# -ge 3 ]
then
echo "usage: ./buildtests regexp [jobs]"
- echo " makes tests matching the regexp, with <jobs> concurrent make jobs"
+ echo " makes tests matching the regexp, with [jobs] concurrent make jobs"
exit 0
fi
-TESTSLIST="${cmake_tests_list}"
-targets_to_make=`echo "$TESTSLIST" | grep "$1" | sed s/^/test_/g | xargs echo`
+TESTSLIST="${EIGEN_TESTS_LIST}"
+
+targets_to_make=`echo "$TESTSLIST" | egrep "$1" | xargs echo`
if [ $# == 1 ]
then
make $targets_to_make
+ exit $?
fi
if [ $# == 2 ]
then
make -j $2 $targets_to_make
+ exit $?
fi
diff --git a/scripts/check.in b/scripts/check.in
index 3aa9501bb..82d805b79 100755
--- a/scripts/check.in
+++ b/scripts/check.in
@@ -1,14 +1,12 @@
#!/bin/bash
-# mctestr : shorthand for make and ctest -R
+# check : shorthand for make and ctest -R
if [ $# == 0 -o $# -ge 3 ]
then
echo "usage: ./check regexp [jobs]"
- echo " makes and runs tests matching the regexp, with <jobs> concurrent make jobs"
+ echo " makes and runs tests matching the regexp, with [jobs] concurrent make jobs"
exit 0
fi
-./buildtests $*
-
# TODO when ctest 2.8 comes out, honor the jobs parameter
-ctest -R $1 \ No newline at end of file
+./buildtests "$1" "${2:-1}" && ctest -R "$1"
diff --git a/scripts/eigen_gen_credits b/scripts/eigen_gen_credits
index c67416784..83ca8da12 100755
--- a/scripts/eigen_gen_credits
+++ b/scripts/eigen_gen_credits
@@ -1,10 +1,10 @@
#!/bin/sh
-# this script must be run from the eigen2/ directory.
+# this script must be run from the eigen/ directory.
# when running hg churn from the scripts/ subdir, i hit a divide-by-zero error.
#
# like this:
-# cd eigen2
+# cd eigen
# USER=yourtuxfamilyuser scripts/eigen_gen_credits
rm -f eigen_gen_credits.log
diff --git a/signature_of_eigen3_matrix_library b/signature_of_eigen3_matrix_library
new file mode 100644
index 000000000..80aaf4621
--- /dev/null
+++ b/signature_of_eigen3_matrix_library
@@ -0,0 +1 @@
+This file is just there as a signature to help identify directories containing Eigen3. When writing a script looking for Eigen3, just look for this file. This is especially useful to help disambiguate with Eigen2...
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index c6e282a0e..c29331db5 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -3,10 +3,6 @@ add_custom_target(buildtests)
add_custom_target(check COMMAND "ctest")
add_dependencies(check buildtests)
-
-include(EigenTesting)
-ei_init_testing()
-
option(EIGEN_SPLIT_LARGE_TESTS "Split large tests into smaller executables" ON)
find_package(GSL)
@@ -162,6 +158,8 @@ ei_add_test(conservative_resize)
ei_add_test(permutationmatrices)
ei_add_test(eigen2support)
+ei_add_test(prec_inverse_4x4)
+
ei_add_property(EIGEN_TESTING_SUMMARY "CXX: ${CMAKE_CXX_COMPILER}\n")
if(CMAKE_COMPILER_IS_GNUCXX)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version COMMAND head -n 1 OUTPUT_VARIABLE EIGEN_CXX_VERSION_STRING OUTPUT_STRIP_TRAILING_WHITESPACE)
@@ -169,5 +167,3 @@ if(CMAKE_COMPILER_IS_GNUCXX)
endif(CMAKE_COMPILER_IS_GNUCXX)
ei_add_property(EIGEN_TESTING_SUMMARY "CXX_FLAGS: ${CMAKE_CXX_FLAGS}\n")
ei_add_property(EIGEN_TESTING_SUMMARY "Sparse lib flags: ${SPARSE_LIBS}\n")
-
-configure_file(buildtests.in ${CMAKE_BINARY_DIR}/buildtests)
diff --git a/test/adjoint.cpp b/test/adjoint.cpp
index 344399257..b34112249 100644
--- a/test/adjoint.cpp
+++ b/test/adjoint.cpp
@@ -128,6 +128,14 @@ void test_adjoint()
VERIFY_RAISES_ASSERT(a = a.adjoint());
VERIFY_RAISES_ASSERT(a = a.adjoint() + b);
VERIFY_RAISES_ASSERT(a = b + a.adjoint());
+
+ // no assertion should be triggered for these cases:
+ a.transpose() = a.transpose();
+ a.transpose() += a.transpose();
+ a.transpose() += a.transpose() + b;
+ a.transpose() = a.adjoint();
+ a.transpose() += a.adjoint();
+ a.transpose() += a.adjoint() + b;
}
#endif
}
diff --git a/test/bandmatrix.cpp b/test/bandmatrix.cpp
index ecb7304db..e243dffe5 100644
--- a/test/bandmatrix.cpp
+++ b/test/bandmatrix.cpp
@@ -53,7 +53,7 @@ template<typename MatrixType> void bandmatrix(const MatrixType& _m)
dm1.diagonal(-i).setConstant(-static_cast<RealScalar>(i));
}
//std::cerr << m.m_data << "\n\n" << m.toDense() << "\n\n" << dm1 << "\n\n\n\n";
- VERIFY_IS_APPROX(dm1,m.toDense());
+ VERIFY_IS_APPROX(dm1,m.toDenseMatrix());
for (int i=0; i<cols; ++i)
{
@@ -68,7 +68,7 @@ template<typename MatrixType> void bandmatrix(const MatrixType& _m)
dm1.block(subs+1,0,rows-subs-1-b,rows-subs-1-b).template triangularView<LowerTriangular>().setZero();
if(b>0) dm1.block(d+subs,0,b,cols).setZero();
//std::cerr << m.m_data << "\n\n" << m.toDense() << "\n\n" << dm1 << "\n\n";
- VERIFY_IS_APPROX(dm1,m.toDense());
+ VERIFY_IS_APPROX(dm1,m.toDenseMatrix());
}
diff --git a/test/cholesky.cpp b/test/cholesky.cpp
index c3ef96752..c658b902c 100644
--- a/test/cholesky.cpp
+++ b/test/cholesky.cpp
@@ -95,7 +95,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
{
LLT<SquareMatrixType,LowerTriangular> chollo(symmLo);
- VERIFY_IS_APPROX(symm, chollo.matrixL().toDense() * chollo.matrixL().adjoint().toDense());
+ VERIFY_IS_APPROX(symm, chollo.matrixL().toDenseMatrix() * chollo.matrixL().adjoint().toDenseMatrix());
vecX = chollo.solve(vecB);
VERIFY_IS_APPROX(symm * vecX, vecB);
matX = chollo.solve(matB);
@@ -103,7 +103,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
// test the upper mode
LLT<SquareMatrixType,UpperTriangular> cholup(symmUp);
- VERIFY_IS_APPROX(symm, cholup.matrixL().toDense() * cholup.matrixL().adjoint().toDense());
+ VERIFY_IS_APPROX(symm, cholup.matrixL().toDenseMatrix() * cholup.matrixL().adjoint().toDenseMatrix());
vecX = cholup.solve(vecB);
VERIFY_IS_APPROX(symm * vecX, vecB);
matX = cholup.solve(matB);
diff --git a/test/eigensolver_complex.cpp b/test/eigensolver_complex.cpp
index 11b7be5f7..fa052a9ae 100644
--- a/test/eigensolver_complex.cpp
+++ b/test/eigensolver_complex.cpp
@@ -60,5 +60,6 @@ void test_eigensolver_complex()
for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST_1( eigensolver(Matrix4cf()) );
CALL_SUBTEST_2( eigensolver(MatrixXcd(14,14)) );
+ CALL_SUBTEST_3( eigensolver(Matrix<std::complex<float>, 1, 1>()) );
}
}
diff --git a/test/geo_hyperplane.cpp b/test/geo_hyperplane.cpp
index 3cf5655c2..1fd1e281a 100644
--- a/test/geo_hyperplane.cpp
+++ b/test/geo_hyperplane.cpp
@@ -64,7 +64,7 @@ template<typename HyperplaneType> void hyperplane(const HyperplaneType& _plane)
// transform
if (!NumTraits<Scalar>::IsComplex)
{
- MatrixType rot = MatrixType::Random(dim,dim).householderQr().matrixQ();
+ MatrixType rot = MatrixType::Random(dim,dim).householderQr().householderQ();
DiagonalMatrix<Scalar,HyperplaneType::AmbientDimAtCompileTime> scaling(VectorType::Random());
Translation<Scalar,HyperplaneType::AmbientDimAtCompileTime> translation(VectorType::Random());
diff --git a/test/geo_quaternion.cpp b/test/geo_quaternion.cpp
index 19eb6e78c..a73ff19ec 100644
--- a/test/geo_quaternion.cpp
+++ b/test/geo_quaternion.cpp
@@ -43,7 +43,7 @@ template<typename Scalar> void quaternion(void)
if (ei_is_same_type<Scalar,float>::ret)
largeEps = 1e-3f;
- Scalar eps = ei_random<Scalar>() * 1e-2;
+ Scalar eps = ei_random<Scalar>() * Scalar(1e-2);
Vector3 v0 = Vector3::Random(),
v1 = Vector3::Random(),
diff --git a/test/inverse.cpp b/test/inverse.cpp
index 3ed61d356..b80e139e0 100644
--- a/test/inverse.cpp
+++ b/test/inverse.cpp
@@ -38,18 +38,11 @@ template<typename MatrixType> void inverse(const MatrixType& m)
typedef typename NumTraits<Scalar>::Real RealScalar;
typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;
- MatrixType m1 = MatrixType::Random(rows, cols),
+ MatrixType m1(rows, cols),
m2(rows, cols),
mzero = MatrixType::Zero(rows, cols),
identity = MatrixType::Identity(rows, rows);
-
- if (ei_is_same_type<RealScalar,float>::ret)
- {
- // let's build a more stable to inverse matrix
- MatrixType a = MatrixType::Random(rows,cols);
- m1 += m1 * m1.adjoint() + a * a.adjoint();
- }
-
+ createRandomMatrixOfRank(rows,rows,rows,m1);
m2 = m1.inverse();
VERIFY_IS_APPROX(m1, m2.inverse() );
@@ -104,12 +97,4 @@ void test_inverse()
s = ei_random<int>(25,100);
CALL_SUBTEST_6( inverse(MatrixXcd(s,s)) );
}
-
-#ifdef EIGEN_TEST_PART_4
- // test some tricky cases for 4x4 matrices
- VERIFY_IS_APPROX((Matrix4f() << 0,0,1,0, 1,0,0,0, 0,1,0,0, 0,0,0,1).finished().inverse(),
- (Matrix4f() << 0,1,0,0, 0,0,1,0, 1,0,0,0, 0,0,0,1).finished());
- VERIFY_IS_APPROX((Matrix4f() << 1,0,0,0, 0,0,1,0, 0,0,0,1, 0,1,0,0).finished().inverse(),
- (Matrix4f() << 1,0,0,0, 0,0,0,1, 0,1,0,0, 0,0,1,0).finished());
-#endif
}
diff --git a/test/jacobisvd.cpp b/test/jacobisvd.cpp
index f3a143e3c..587bc7572 100644
--- a/test/jacobisvd.cpp
+++ b/test/jacobisvd.cpp
@@ -54,6 +54,9 @@ template<typename MatrixType, unsigned int Options> void svd(const MatrixType& m
MatrixUType u = svd.matrixU();
MatrixVType v = svd.matrixV();
+ std::cout << "a\n" << a << std::endl;
+ std::cout << "b\n" << u * sigma * v.adjoint() << std::endl;
+
VERIFY_IS_APPROX(a, u * sigma * v.adjoint());
VERIFY_IS_UNITARY(u);
VERIFY_IS_UNITARY(v);
diff --git a/test/lu.cpp b/test/lu.cpp
index 9dcebbeaa..c2237febf 100644
--- a/test/lu.cpp
+++ b/test/lu.cpp
@@ -24,9 +24,11 @@
#include "main.h"
#include <Eigen/LU>
+using namespace std;
template<typename MatrixType> void lu_non_invertible()
{
+ typedef typename MatrixType::Scalar Scalar;
/* this test covers the following files:
LU.h
*/
@@ -65,7 +67,20 @@ template<typename MatrixType> void lu_non_invertible()
createRandomMatrixOfRank(rank, rows, cols, m1);
FullPivLU<MatrixType> lu(m1);
- std::cout << lu.kernel().rows() << " " << lu.kernel().cols() << std::endl;
+ // FIXME need better way to construct trapezoid matrices. extend triangularView to support rectangular.
+ DynamicMatrixType u(rows,cols);
+ for(int i = 0; i < rows; i++)
+ for(int j = 0; j < cols; j++)
+ u(i,j) = i>j ? Scalar(0) : lu.matrixLU()(i,j);
+ DynamicMatrixType l(rows,rows);
+ for(int i = 0; i < rows; i++)
+ for(int j = 0; j < rows; j++)
+ l(i,j) = (i<j || j>=cols) ? Scalar(0)
+ : i==j ? Scalar(1)
+ : lu.matrixLU()(i,j);
+
+ VERIFY_IS_APPROX(lu.permutationP() * m1 * lu.permutationQ(), l*u);
+
KernelMatrixType m1kernel = lu.kernel();
ImageMatrixType m1image = lu.image(m1);
diff --git a/test/main.h b/test/main.h
index 0b9b0bc4c..06c17a9ae 100644
--- a/test/main.h
+++ b/test/main.h
@@ -24,6 +24,7 @@
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#include <cstdlib>
+#include <cerrno>
#include <ctime>
#include <iostream>
#include <string>
@@ -49,6 +50,8 @@ namespace Eigen
{
static std::vector<std::string> g_test_stack;
static int g_repeat;
+ static unsigned int g_seed;
+ static bool g_has_set_repeat, g_has_set_seed;
}
#define EI_PP_MAKE_STRING2(S) #S
@@ -350,17 +353,30 @@ void createRandomMatrixOfRank(int desired_rank, int rows, int cols, MatrixType&
typedef Matrix<Scalar, Rows, Rows> MatrixAType;
typedef Matrix<Scalar, Cols, Cols> MatrixBType;
+ if(desired_rank == 0)
+ {
+ m.setZero(rows,cols);
+ return;
+ }
+
+ if(desired_rank == 1)
+ {
+ m = VectorType::Random(rows) * VectorType::Random(cols).transpose();
+ return;
+ }
+
MatrixAType a = MatrixAType::Random(rows,rows);
MatrixType d = MatrixType::Identity(rows,cols);
MatrixBType b = MatrixBType::Random(cols,cols);
// set the diagonal such that only desired_rank non-zero entries reamain
const int diag_size = std::min(d.rows(),d.cols());
- d.diagonal().segment(desired_rank, diag_size-desired_rank) = VectorType::Zero(diag_size-desired_rank);
+ if(diag_size != desired_rank)
+ d.diagonal().segment(desired_rank, diag_size-desired_rank) = VectorType::Zero(diag_size-desired_rank);
HouseholderQR<MatrixAType> qra(a);
HouseholderQR<MatrixBType> qrb(b);
- m = qra.matrixQ() * d * qrb.matrixQ();
+ m = qra.householderQ() * d * qrb.householderQ();
}
} // end namespace Eigen
@@ -372,51 +388,68 @@ template<> struct GetDifferentType<double> { typedef float type; };
template<typename T> struct GetDifferentType<std::complex<T> >
{ typedef std::complex<typename GetDifferentType<T>::type> type; };
+template<typename T> std::string type_name() { return "other"; }
+template<> std::string type_name<float>() { return "float"; }
+template<> std::string type_name<double>() { return "double"; }
+template<> std::string type_name<int>() { return "int"; }
+template<> std::string type_name<std::complex<float> >() { return "complex<float>"; }
+template<> std::string type_name<std::complex<double> >() { return "complex<double>"; }
+template<> std::string type_name<std::complex<int> >() { return "complex<int>"; }
+
// forward declaration of the main test function
void EIGEN_CAT(test_,EIGEN_TEST_FUNC)();
using namespace Eigen;
+void set_repeat_from_string(const char *str)
+{
+ errno = 0;
+ g_repeat = int(strtoul(str, 0, 10));
+ if(errno || g_repeat <= 0)
+ {
+ std::cout << "Invalid repeat value " << str << std::endl;
+ exit(EXIT_FAILURE);
+ }
+ g_has_set_repeat = true;
+}
+
+void set_seed_from_string(const char *str)
+{
+ errno = 0;
+ g_seed = strtoul(str, 0, 10);
+ if(errno || g_seed == 0)
+ {
+ std::cout << "Invalid seed value " << str << std::endl;
+ exit(EXIT_FAILURE);
+ }
+ g_has_set_seed = true;
+}
+
int main(int argc, char *argv[])
{
- bool has_set_repeat = false;
- bool has_set_seed = false;
+ g_has_set_repeat = false;
+ g_has_set_seed = false;
bool need_help = false;
- unsigned int seed = 0;
- int repeat = DEFAULT_REPEAT;
for(int i = 1; i < argc; i++)
{
if(argv[i][0] == 'r')
{
- if(has_set_repeat)
+ if(g_has_set_repeat)
{
std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
return 1;
}
- repeat = atoi(argv[i]+1);
- has_set_repeat = true;
- if(repeat <= 0)
- {
- std::cout << "Invalid \'repeat\' value " << argv[i]+1 << std::endl;
- return 1;
- }
+ set_repeat_from_string(argv[i]+1);
}
else if(argv[i][0] == 's')
{
- if(has_set_seed)
+ if(g_has_set_seed)
{
std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
return 1;
}
- seed = int(strtoul(argv[i]+1, 0, 10));
- has_set_seed = true;
- bool ok = seed!=0;
- if(!ok)
- {
- std::cout << "Invalid \'seed\' value " << argv[i]+1 << std::endl;
- return 1;
- }
+ set_seed_from_string(argv[i]+1);
}
else
{
@@ -429,22 +462,29 @@ int main(int argc, char *argv[])
std::cout << "This test application takes the following optional arguments:" << std::endl;
std::cout << " rN Repeat each test N times (default: " << DEFAULT_REPEAT << ")" << std::endl;
std::cout << " sN Use N as seed for random numbers (default: based on current time)" << std::endl;
+ std::cout << std::endl;
+ std::cout << "If defined, the environment variables EIGEN_REPEAT and EIGEN_SEED" << std::endl;
+ std::cout << "will be used as default values for these parameters." << std::endl;
return 1;
}
- if(!has_set_seed) seed = (unsigned int) time(NULL);
- if(!has_set_repeat) repeat = DEFAULT_REPEAT;
+ char *env_EIGEN_REPEAT = getenv("EIGEN_REPEAT");
+ if(!g_has_set_repeat && env_EIGEN_REPEAT)
+ set_repeat_from_string(env_EIGEN_REPEAT);
+ char *env_EIGEN_SEED = getenv("EIGEN_SEED");
+ if(!g_has_set_seed && env_EIGEN_SEED)
+ set_seed_from_string(env_EIGEN_SEED);
- std::cout << "Initializing random number generator with seed " << seed << std::endl;
- srand(seed);
- std::cout << "Repeating each test " << repeat << " times" << std::endl;
+ if(!g_has_set_seed) g_seed = (unsigned int) time(NULL);
+ if(!g_has_set_repeat) g_repeat = DEFAULT_REPEAT;
+
+ std::cout << "Initializing random number generator with seed " << g_seed << std::endl;
+ srand(g_seed);
+ std::cout << "Repeating each test " << g_repeat << " times" << std::endl;
- Eigen::g_repeat = repeat;
Eigen::g_test_stack.push_back(EI_PP_MAKE_STRING(EIGEN_TEST_FUNC));
EIGEN_CAT(test_,EIGEN_TEST_FUNC)();
return 0;
}
-
-
diff --git a/test/permutationmatrices.cpp b/test/permutationmatrices.cpp
index 13b01cd83..0ef0a371a 100644
--- a/test/permutationmatrices.cpp
+++ b/test/permutationmatrices.cpp
@@ -66,12 +66,45 @@ template<typename MatrixType> void permutationmatrices(const MatrixType& m)
for (int i=0; i<rows; i++)
for (int j=0; j<cols; j++)
- VERIFY_IS_APPROX(m_original(lv(i),j), m_permuted(i,rv(j)));
+ VERIFY_IS_APPROX(m_permuted(lv(i),j), m_original(i,rv(j)));
Matrix<Scalar,Rows,Rows> lm(lp);
Matrix<Scalar,Cols,Cols> rm(rp);
VERIFY_IS_APPROX(m_permuted, lm*m_original*rm);
+
+ VERIFY_IS_APPROX(lp.inverse()*m_permuted*rp.inverse(), m_original);
+ VERIFY((lp*lp.inverse()).toDenseMatrix().isIdentity());
+
+ LeftPermutationVectorType lv2;
+ randomPermutationVector(lv2, rows);
+ LeftPermutationType lp2(lv2);
+ Matrix<Scalar,Rows,Rows> lm2(lp2);
+ VERIFY_IS_APPROX((lp*lp2).toDenseMatrix().template cast<Scalar>(), lm*lm2);
+
+ LeftPermutationType identityp;
+ identityp.setIdentity(rows);
+ VERIFY_IS_APPROX(m_original, identityp*m_original);
+
+ if(rows>1 && cols>1)
+ {
+ lp2 = lp;
+ int i = ei_random<int>(0, rows-1);
+ int j;
+ do j = ei_random<int>(0, rows-1); while(j==i);
+ lp2.applyTranspositionOnTheLeft(i, j);
+ lm = lp;
+ lm.row(i).swap(lm.row(j));
+ VERIFY_IS_APPROX(lm, lp2.toDenseMatrix().template cast<Scalar>());
+
+ RightPermutationType rp2 = rp;
+ i = ei_random<int>(0, cols-1);
+ do j = ei_random<int>(0, cols-1); while(j==i);
+ rp2.applyTranspositionOnTheRight(i, j);
+ rm = rp;
+ rm.col(i).swap(rm.col(j));
+ VERIFY_IS_APPROX(rm, rp2.toDenseMatrix().template cast<Scalar>());
+ }
}
void test_permutationmatrices()
diff --git a/test/prec_inverse_4x4.cpp b/test/prec_inverse_4x4.cpp
new file mode 100644
index 000000000..e1b05aa0d
--- /dev/null
+++ b/test/prec_inverse_4x4.cpp
@@ -0,0 +1,80 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Eigen is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 3 of the License, or (at your option) any later version.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#include "main.h"
+#include <Eigen/LU>
+#include <algorithm>
+
+template<typename MatrixType> void inverse_permutation_4x4()
+{
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::RealScalar RealScalar;
+ Vector4i indices(0,1,2,3);
+ for(int i = 0; i < 24; ++i)
+ {
+ MatrixType m = PermutationMatrix<4>(indices);
+ MatrixType inv = m.inverse();
+ double error = double( (m*inv-MatrixType::Identity()).norm() / epsilon<Scalar>() );
+ VERIFY(error == 0.0);
+ std::next_permutation(indices.data(),indices.data()+4);
+ }
+}
+
+template<typename MatrixType> void inverse_general_4x4(int repeat)
+{
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::RealScalar RealScalar;
+ double error_sum = 0., error_max = 0.;
+ for(int i = 0; i < repeat; ++i)
+ {
+ MatrixType m;
+ RealScalar absdet;
+ do {
+ m = MatrixType::Random();
+ absdet = ei_abs(m.determinant());
+ } while(absdet < epsilon<Scalar>());
+ MatrixType inv = m.inverse();
+ double error = double( (m*inv-MatrixType::Identity()).norm() * absdet / epsilon<Scalar>() );
+ error_sum += error;
+ error_max = std::max(error_max, error);
+ }
+ std::cerr << "inverse_general_4x4, Scalar = " << type_name<Scalar>() << std::endl;
+ double error_avg = error_sum / repeat;
+ EIGEN_DEBUG_VAR(error_avg);
+ EIGEN_DEBUG_VAR(error_max);
+ VERIFY(error_avg < (NumTraits<Scalar>::IsComplex ? 8.0 : 1.0));
+ VERIFY(error_max < (NumTraits<Scalar>::IsComplex ? 64.0 : 20.0));
+}
+
+void test_prec_inverse_4x4()
+{
+ CALL_SUBTEST_1((inverse_permutation_4x4<Matrix4f>()));
+ CALL_SUBTEST_1(( inverse_general_4x4<Matrix4f>(200000 * g_repeat) ));
+
+ CALL_SUBTEST_2((inverse_permutation_4x4<Matrix<double,4,4,RowMajor> >()));
+ CALL_SUBTEST_2(( inverse_general_4x4<Matrix<double,4,4,RowMajor> >(200000 * g_repeat) ));
+
+ CALL_SUBTEST_3((inverse_permutation_4x4<Matrix4cf>()));
+ CALL_SUBTEST_3((inverse_general_4x4<Matrix4cf>(50000 * g_repeat)));
+}
diff --git a/test/product.h b/test/product.h
index 1dcc636e3..c389c33ed 100644
--- a/test/product.h
+++ b/test/product.h
@@ -27,7 +27,7 @@
#include <Eigen/QR>
template<typename Derived1, typename Derived2>
-bool areNotApprox(const MatrixBase<Derived1>& m1, const MatrixBase<Derived2>& m2, typename Derived1::RealScalar epsilon = precision<typename Derived1::RealScalar>())
+bool areNotApprox(const MatrixBase<Derived1>& m1, const MatrixBase<Derived2>& m2, typename Derived1::RealScalar epsilon = dummy_precision<typename Derived1::RealScalar>())
{
return !((m1-m2).cwiseAbs2().maxCoeff() < epsilon * epsilon
* std::max(m1.cwiseAbs2().maxCoeff(), m2.cwiseAbs2().maxCoeff()));
diff --git a/test/product_selfadjoint.cpp b/test/product_selfadjoint.cpp
index aa8da37bd..2e9f8be80 100644
--- a/test/product_selfadjoint.cpp
+++ b/test/product_selfadjoint.cpp
@@ -55,15 +55,15 @@ template<typename MatrixType> void product_selfadjoint(const MatrixType& m)
// rank2 update
m2 = m1.template triangularView<LowerTriangular>();
m2.template selfadjointView<LowerTriangular>().rankUpdate(v1,v2);
- VERIFY_IS_APPROX(m2, (m1 + v1 * v2.adjoint()+ v2 * v1.adjoint()).template triangularView<LowerTriangular>().toDense());
+ VERIFY_IS_APPROX(m2, (m1 + v1 * v2.adjoint()+ v2 * v1.adjoint()).template triangularView<LowerTriangular>().toDenseMatrix());
m2 = m1.template triangularView<UpperTriangular>();
m2.template selfadjointView<UpperTriangular>().rankUpdate(-v1,s2*v2,s3);
- VERIFY_IS_APPROX(m2, (m1 + (-s2*s3) * (v1 * v2.adjoint()+ v2 * v1.adjoint())).template triangularView<UpperTriangular>().toDense());
+ VERIFY_IS_APPROX(m2, (m1 + (-s2*s3) * (v1 * v2.adjoint()+ v2 * v1.adjoint())).template triangularView<UpperTriangular>().toDenseMatrix());
m2 = m1.template triangularView<UpperTriangular>();
m2.template selfadjointView<UpperTriangular>().rankUpdate(-r1.adjoint(),r2.adjoint()*s3,s1);
- VERIFY_IS_APPROX(m2, (m1 + (-s3*s1) * (r1.adjoint() * r2 + r2.adjoint() * r1)).template triangularView<UpperTriangular>().toDense());
+ VERIFY_IS_APPROX(m2, (m1 + (-s3*s1) * (r1.adjoint() * r2 + r2.adjoint() * r1)).template triangularView<UpperTriangular>().toDenseMatrix());
if (rows>1)
{
@@ -71,7 +71,7 @@ template<typename MatrixType> void product_selfadjoint(const MatrixType& m)
m2.block(1,1,rows-1,cols-1).template selfadjointView<LowerTriangular>().rankUpdate(v1.end(rows-1),v2.start(cols-1));
m3 = m1;
m3.block(1,1,rows-1,cols-1) += v1.end(rows-1) * v2.start(cols-1).adjoint()+ v2.start(cols-1) * v1.end(rows-1).adjoint();
- VERIFY_IS_APPROX(m2, m3.template triangularView<LowerTriangular>().toDense());
+ VERIFY_IS_APPROX(m2, m3.template triangularView<LowerTriangular>().toDenseMatrix());
}
}
diff --git a/test/product_syrk.cpp b/test/product_syrk.cpp
index 37d54bf16..9f6aec0e2 100644
--- a/test/product_syrk.cpp
+++ b/test/product_syrk.cpp
@@ -46,27 +46,27 @@ template<typename MatrixType> void syrk(const MatrixType& m)
m2.setZero();
VERIFY_IS_APPROX((m2.template selfadjointView<LowerTriangular>().rankUpdate(rhs2,s1)._expression()),
- ((s1 * rhs2 * rhs2.adjoint()).eval().template triangularView<LowerTriangular>().toDense()));
+ ((s1 * rhs2 * rhs2.adjoint()).eval().template triangularView<LowerTriangular>().toDenseMatrix()));
m2.setZero();
VERIFY_IS_APPROX(m2.template selfadjointView<UpperTriangular>().rankUpdate(rhs2,s1)._expression(),
- (s1 * rhs2 * rhs2.adjoint()).eval().template triangularView<UpperTriangular>().toDense());
+ (s1 * rhs2 * rhs2.adjoint()).eval().template triangularView<UpperTriangular>().toDenseMatrix());
m2.setZero();
VERIFY_IS_APPROX(m2.template selfadjointView<LowerTriangular>().rankUpdate(rhs1.adjoint(),s1)._expression(),
- (s1 * rhs1.adjoint() * rhs1).eval().template triangularView<LowerTriangular>().toDense());
+ (s1 * rhs1.adjoint() * rhs1).eval().template triangularView<LowerTriangular>().toDenseMatrix());
m2.setZero();
VERIFY_IS_APPROX(m2.template selfadjointView<UpperTriangular>().rankUpdate(rhs1.adjoint(),s1)._expression(),
- (s1 * rhs1.adjoint() * rhs1).eval().template triangularView<UpperTriangular>().toDense());
+ (s1 * rhs1.adjoint() * rhs1).eval().template triangularView<UpperTriangular>().toDenseMatrix());
m2.setZero();
VERIFY_IS_APPROX(m2.template selfadjointView<LowerTriangular>().rankUpdate(rhs3.adjoint(),s1)._expression(),
- (s1 * rhs3.adjoint() * rhs3).eval().template triangularView<LowerTriangular>().toDense());
+ (s1 * rhs3.adjoint() * rhs3).eval().template triangularView<LowerTriangular>().toDenseMatrix());
m2.setZero();
VERIFY_IS_APPROX(m2.template selfadjointView<UpperTriangular>().rankUpdate(rhs3.adjoint(),s1)._expression(),
- (s1 * rhs3.adjoint() * rhs3).eval().template triangularView<UpperTriangular>().toDense());
+ (s1 * rhs3.adjoint() * rhs3).eval().template triangularView<UpperTriangular>().toDenseMatrix());
}
void test_product_syrk()
diff --git a/test/product_trsm.cpp b/test/product_trsm.cpp
index 6c5ca274a..e884f3180 100644
--- a/test/product_trsm.cpp
+++ b/test/product_trsm.cpp
@@ -27,7 +27,7 @@
#define VERIFY_TRSM(TRI,XB) { \
(XB).setRandom(); ref = (XB); \
(TRI).solveInPlace(XB); \
- VERIFY_IS_APPROX((TRI).toDense() * (XB), ref); \
+ VERIFY_IS_APPROX((TRI).toDenseMatrix() * (XB), ref); \
}
template<typename Scalar> void trsm(int size,int cols)
diff --git a/test/qr.cpp b/test/qr.cpp
index 90b5c4446..3848ce0a5 100644
--- a/test/qr.cpp
+++ b/test/qr.cpp
@@ -38,13 +38,13 @@ template<typename MatrixType> void qr(const MatrixType& m)
HouseholderQR<MatrixType> qrOfA(a);
MatrixType r = qrOfA.matrixQR();
- MatrixQType q = qrOfA.matrixQ();
+ MatrixQType q = qrOfA.householderQ();
VERIFY_IS_UNITARY(q);
// FIXME need better way to construct trapezoid
for(int i = 0; i < rows; i++) for(int j = 0; j < cols; j++) if(i>j) r(i,j) = Scalar(0);
- VERIFY_IS_APPROX(a, qrOfA.matrixQ() * r);
+ VERIFY_IS_APPROX(a, qrOfA.householderQ() * r);
}
template<typename MatrixType, int Cols2> void qr_fixedsize()
@@ -58,7 +58,7 @@ template<typename MatrixType, int Cols2> void qr_fixedsize()
// FIXME need better way to construct trapezoid
for(int i = 0; i < Rows; i++) for(int j = 0; j < Cols; j++) if(i>j) r(i,j) = Scalar(0);
- VERIFY_IS_APPROX(m1, qr.matrixQ() * r);
+ VERIFY_IS_APPROX(m1, qr.householderQ() * r);
Matrix<Scalar,Cols,Cols2> m2 = Matrix<Scalar,Cols,Cols2>::Random(Cols,Cols2);
Matrix<Scalar,Rows,Cols2> m3 = m1*m2;
@@ -93,7 +93,7 @@ template<typename MatrixType> void qr_invertible()
m1.setZero();
for(int i = 0; i < size; i++) m1(i,i) = ei_random<Scalar>();
RealScalar absdet = ei_abs(m1.diagonal().prod());
- m3 = qr.matrixQ(); // get a unitary
+ m3 = qr.householderQ(); // get a unitary
m1 = m3 * m1 * m3;
qr.compute(m1);
VERIFY_IS_APPROX(absdet, qr.absDeterminant());
@@ -107,7 +107,7 @@ template<typename MatrixType> void qr_verify_assert()
HouseholderQR<MatrixType> qr;
VERIFY_RAISES_ASSERT(qr.matrixQR())
VERIFY_RAISES_ASSERT(qr.solve(tmp))
- VERIFY_RAISES_ASSERT(qr.matrixQ())
+ VERIFY_RAISES_ASSERT(qr.householderQ())
VERIFY_RAISES_ASSERT(qr.absDeterminant())
VERIFY_RAISES_ASSERT(qr.logAbsDeterminant())
}
diff --git a/test/qr_colpivoting.cpp b/test/qr_colpivoting.cpp
index 763c12067..8b56cd296 100644
--- a/test/qr_colpivoting.cpp
+++ b/test/qr_colpivoting.cpp
@@ -28,10 +28,11 @@
template<typename MatrixType> void qr()
{
- int rows = ei_random<int>(20,200), cols = ei_random<int>(20,200), cols2 = ei_random<int>(20,200);
+ int rows = ei_random<int>(2,200), cols = ei_random<int>(2,200), cols2 = ei_random<int>(2,200);
int rank = ei_random<int>(1, std::min(rows, cols)-1);
typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::RealScalar RealScalar;
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> MatrixQType;
typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;
MatrixType m1;
@@ -43,19 +44,11 @@ template<typename MatrixType> void qr()
VERIFY(!qr.isInvertible());
VERIFY(!qr.isSurjective());
- MatrixType r = qr.matrixQR();
-
- MatrixQType q = qr.matrixQ();
+ MatrixQType q = qr.householderQ();
VERIFY_IS_UNITARY(q);
-
- // FIXME need better way to construct trapezoid
- for(int i = 0; i < rows; i++) for(int j = 0; j < cols; j++) if(i>j) r(i,j) = Scalar(0);
- MatrixType b = qr.matrixQ() * r;
-
- MatrixType c = MatrixType::Zero(rows,cols);
-
- for(int i = 0; i < cols; ++i) c.col(qr.colsPermutation().coeff(i)) = b.col(i);
+ MatrixType r = qr.matrixQR().template triangularView<UpperTriangular>();
+ MatrixType c = q * r * qr.colsPermutation().inverse();
VERIFY_IS_APPROX(m1, c);
MatrixType m2 = MatrixType::Random(cols,cols2);
@@ -79,15 +72,8 @@ template<typename MatrixType, int Cols2> void qr_fixedsize()
VERIFY(!qr.isInvertible());
VERIFY(!qr.isSurjective());
- Matrix<Scalar,Rows,Cols> r = qr.matrixQR();
- // FIXME need better way to construct trapezoid
- for(int i = 0; i < Rows; i++) for(int j = 0; j < Cols; j++) if(i>j) r(i,j) = Scalar(0);
-
- Matrix<Scalar,Rows,Cols> b = qr.matrixQ() * r;
-
- Matrix<Scalar,Rows,Cols> c = MatrixType::Zero(Rows,Cols);
-
- for(int i = 0; i < Cols; ++i) c.col(qr.colsPermutation().coeff(i)) = b.col(i);
+ Matrix<Scalar,Rows,Cols> r = qr.matrixQR().template triangularView<UpperTriangular>();
+ Matrix<Scalar,Rows,Cols> c = qr.householderQ() * r * qr.colsPermutation().inverse();
VERIFY_IS_APPROX(m1, c);
Matrix<Scalar,Cols,Cols2> m2 = Matrix<Scalar,Cols,Cols2>::Random(Cols,Cols2);
@@ -117,13 +103,13 @@ template<typename MatrixType> void qr_invertible()
ColPivHouseholderQR<MatrixType> qr(m1);
m3 = MatrixType::Random(size,size);
m2 = qr.solve(m3);
- VERIFY_IS_APPROX(m3, m1*m2);
+ //VERIFY_IS_APPROX(m3, m1*m2);
// now construct a matrix with prescribed determinant
m1.setZero();
for(int i = 0; i < size; i++) m1(i,i) = ei_random<Scalar>();
RealScalar absdet = ei_abs(m1.diagonal().prod());
- m3 = qr.matrixQ(); // get a unitary
+ m3 = qr.householderQ(); // get a unitary
m1 = m3 * m1 * m3;
qr.compute(m1);
VERIFY_IS_APPROX(absdet, qr.absDeterminant());
@@ -137,7 +123,7 @@ template<typename MatrixType> void qr_verify_assert()
ColPivHouseholderQR<MatrixType> qr;
VERIFY_RAISES_ASSERT(qr.matrixQR())
VERIFY_RAISES_ASSERT(qr.solve(tmp))
- VERIFY_RAISES_ASSERT(qr.matrixQ())
+ VERIFY_RAISES_ASSERT(qr.householderQ())
VERIFY_RAISES_ASSERT(qr.dimensionOfKernel())
VERIFY_RAISES_ASSERT(qr.isInjective())
VERIFY_RAISES_ASSERT(qr.isSurjective())
@@ -149,7 +135,7 @@ template<typename MatrixType> void qr_verify_assert()
void test_qr_colpivoting()
{
- for(int i = 0; i < 1; i++) {
+ for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST_1( qr<MatrixXf>() );
CALL_SUBTEST_2( qr<MatrixXd>() );
CALL_SUBTEST_3( qr<MatrixXcd>() );
diff --git a/test/qr_fullpivoting.cpp b/test/qr_fullpivoting.cpp
index 65d9a071f..c82ba4c7e 100644
--- a/test/qr_fullpivoting.cpp
+++ b/test/qr_fullpivoting.cpp
@@ -51,11 +51,8 @@ template<typename MatrixType> void qr()
// FIXME need better way to construct trapezoid
for(int i = 0; i < rows; i++) for(int j = 0; j < cols; j++) if(i>j) r(i,j) = Scalar(0);
- MatrixType b = qr.matrixQ() * r;
+ MatrixType c = qr.matrixQ() * r * qr.colsPermutation().inverse();
- MatrixType c = MatrixType::Zero(rows,cols);
-
- for(int i = 0; i < cols; ++i) c.col(qr.colsPermutation().coeff(i)) = b.col(i);
VERIFY_IS_APPROX(m1, c);
MatrixType m2 = MatrixType::Random(cols,cols2);
diff --git a/test/runtest.sh b/test/runtest.sh
index 31d1ca654..2be250819 100755
--- a/test/runtest.sh
+++ b/test/runtest.sh
@@ -9,7 +9,7 @@ magenta='\E[35m'
cyan='\E[36m'
white='\E[37m'
-if ! ./test_$1 > /dev/null 2> .runtest.log ; then
+if ! ./$1 > /dev/null 2> .runtest.log ; then
echo -e $red Test $1 failed: $black
echo -e $blue
cat .runtest.log
diff --git a/test/sparse_basic.cpp b/test/sparse_basic.cpp
index dd3245fb1..9de156d38 100644
--- a/test/sparse_basic.cpp
+++ b/test/sparse_basic.cpp
@@ -34,7 +34,7 @@ bool test_random_setter(SparseMatrix<Scalar,Options>& sm, const DenseType& ref,
std::vector<Vector2i> remaining = nonzeroCoords;
while(!remaining.empty())
{
- int i = ei_random<int>(0,remaining.size()-1);
+ int i = ei_random<int>(0,static_cast<int>(remaining.size())-1);
w(remaining[i].x(),remaining[i].y()) = ref.coeff(remaining[i].x(),remaining[i].y());
remaining[i] = remaining.back();
remaining.pop_back();
@@ -50,7 +50,7 @@ bool test_random_setter(DynamicSparseMatrix<T>& sm, const DenseType& ref, const
std::vector<Vector2i> remaining = nonzeroCoords;
while(!remaining.empty())
{
- int i = ei_random<int>(0,remaining.size()-1);
+ int i = ei_random<int>(0,static_cast<int>(remaining.size())-1);
sm.coeffRef(remaining[i].x(),remaining[i].y()) = ref.coeff(remaining[i].x(),remaining[i].y());
remaining[i] = remaining.back();
remaining.pop_back();
diff --git a/test/stable_norm.cpp b/test/stable_norm.cpp
index 7661fc893..10531dc5d 100644
--- a/test/stable_norm.cpp
+++ b/test/stable_norm.cpp
@@ -79,6 +79,14 @@ template<typename MatrixType> void stable_norm(const MatrixType& m)
VERIFY_IS_APPROX(static_cast<Scalar>(vsmall.stableNorm()), ei_sqrt(size)*small);
VERIFY_IS_APPROX(static_cast<Scalar>(vsmall.blueNorm()), ei_sqrt(size)*small);
VERIFY_IS_APPROX(static_cast<Scalar>(vsmall.hypotNorm()), ei_sqrt(size)*small);
+
+// Test compilation of cwise() version
+ VERIFY_IS_APPROX(vrand.colwise().stableNorm(), vrand.colwise().norm());
+ VERIFY_IS_APPROX(vrand.colwise().blueNorm(), vrand.colwise().norm());
+ VERIFY_IS_APPROX(vrand.colwise().hypotNorm(), vrand.colwise().norm());
+ VERIFY_IS_APPROX(vrand.rowwise().stableNorm(), vrand.rowwise().norm());
+ VERIFY_IS_APPROX(vrand.rowwise().blueNorm(), vrand.rowwise().norm());
+ VERIFY_IS_APPROX(vrand.rowwise().hypotNorm(), vrand.rowwise().norm());
}
void test_stable_norm()
diff --git a/test/testsuite.cmake b/test/testsuite.cmake
index 9c38e48b1..90edf2853 100644
--- a/test/testsuite.cmake
+++ b/test/testsuite.cmake
@@ -4,7 +4,7 @@
# Usage:
# - create a new folder, let's call it cdash
# - in that folder, do:
-# ctest -S path/to/eigen2/test/testsuite.cmake[,option1=value1[,option2=value2]]
+# ctest -S path/to/eigen/test/testsuite.cmake[,option1=value1[,option2=value2]]
#
# Options:
# - EIGEN_CXX: compiler, eg.: g++-4.2
@@ -44,9 +44,9 @@
# ARCH=`uname -m`
# SITE=`hostname`
# VERSION=opensuse-11.1
-# WORK_DIR=/home/gael/Coding/eigen2/cdash
+# WORK_DIR=/home/gael/Coding/eigen/cdash
# # get the last version of the script
-# wget http://bitbucket.org/eigen/eigen2/raw/tip/test/testsuite.cmake -o $WORK_DIR/testsuite.cmake
+# wget http://bitbucket.org/eigen/eigen/raw/tip/test/testsuite.cmake -o $WORK_DIR/testsuite.cmake
# COMMON="ctest -S $WORK_DIR/testsuite.cmake,EIGEN_WORK_DIR=$WORK_DIR,EIGEN_SITE=$SITE,EIGEN_MODE=$1,EIGEN_BUILD_STRING=$OS_VERSION-$ARCH"
# $COMMON-gcc-3.4.6,EIGEN_CXX=g++-3.4
# $COMMON-gcc-4.0.1,EIGEN_CXX=g++-4.0.1
@@ -141,7 +141,7 @@ endif(NOT EIGEN_MODE)
if(NOT EIGEN_NO_UPDATE)
SET (CTEST_CVS_COMMAND "hg")
- SET (CTEST_CVS_CHECKOUT "${CTEST_CVS_COMMAND} clone http://bitbucket.org/eigen/eigen2 \"${CTEST_SOURCE_DIRECTORY}\"")
+ SET (CTEST_CVS_CHECKOUT "${CTEST_CVS_COMMAND} clone http://bitbucket.org/eigen/eigen \"${CTEST_SOURCE_DIRECTORY}\"")
SET(CTEST_BACKUP_AND_RESTORE TRUE) # the backup is CVS related ...
endif(NOT EIGEN_NO_UPDATE)
diff --git a/test/triangular.cpp b/test/triangular.cpp
index 2a583710d..111774b75 100644
--- a/test/triangular.cpp
+++ b/test/triangular.cpp
@@ -24,7 +24,9 @@
#include "main.h"
-template<typename MatrixType> void triangular(const MatrixType& m)
+
+
+template<typename MatrixType> void triangular_square(const MatrixType& m)
{
typedef typename MatrixType::Scalar Scalar;
typedef typename NumTraits<Scalar>::Real RealScalar;
@@ -51,8 +53,8 @@ template<typename MatrixType> void triangular(const MatrixType& m)
v2 = VectorType::Random(rows),
vzero = VectorType::Zero(rows);
- MatrixType m1up = m1.template triangularView<Eigen::UpperTriangular>();
- MatrixType m2up = m2.template triangularView<Eigen::UpperTriangular>();
+ MatrixType m1up = m1.template triangularView<UpperTriangular>();
+ MatrixType m2up = m2.template triangularView<UpperTriangular>();
if (rows*cols>1)
{
@@ -66,83 +68,197 @@ template<typename MatrixType> void triangular(const MatrixType& m)
// test overloaded operator+=
r1.setZero();
r2.setZero();
- r1.template triangularView<Eigen::UpperTriangular>() += m1;
+ r1.template triangularView<UpperTriangular>() += m1;
r2 += m1up;
VERIFY_IS_APPROX(r1,r2);
// test overloaded operator=
m1.setZero();
- m1.template triangularView<Eigen::UpperTriangular>() = m2.transpose() + m2;
+ m1.template triangularView<UpperTriangular>() = m2.transpose() + m2;
m3 = m2.transpose() + m2;
- VERIFY_IS_APPROX(m3.template triangularView<Eigen::LowerTriangular>().transpose().toDense(), m1);
+ VERIFY_IS_APPROX(m3.template triangularView<LowerTriangular>().transpose().toDenseMatrix(), m1);
// test overloaded operator=
m1.setZero();
- m1.template triangularView<Eigen::LowerTriangular>() = m2.transpose() + m2;
- VERIFY_IS_APPROX(m3.template triangularView<Eigen::LowerTriangular>().toDense(), m1);
+ m1.template triangularView<LowerTriangular>() = m2.transpose() + m2;
+ VERIFY_IS_APPROX(m3.template triangularView<LowerTriangular>().toDenseMatrix(), m1);
m1 = MatrixType::Random(rows, cols);
for (int i=0; i<rows; ++i)
- while (ei_abs2(m1(i,i))<1e-3) m1(i,i) = ei_random<Scalar>();
+ while (ei_abs2(m1(i,i))<1e-1) m1(i,i) = ei_random<Scalar>();
Transpose<MatrixType> trm4(m4);
// test back and forward subsitution with a vector as the rhs
- m3 = m1.template triangularView<Eigen::UpperTriangular>();
- VERIFY(v2.isApprox(m3.adjoint() * (m1.adjoint().template triangularView<Eigen::LowerTriangular>().solve(v2)), largerEps));
- m3 = m1.template triangularView<Eigen::LowerTriangular>();
- VERIFY(v2.isApprox(m3.transpose() * (m1.transpose().template triangularView<Eigen::UpperTriangular>().solve(v2)), largerEps));
- m3 = m1.template triangularView<Eigen::UpperTriangular>();
- VERIFY(v2.isApprox(m3 * (m1.template triangularView<Eigen::UpperTriangular>().solve(v2)), largerEps));
- m3 = m1.template triangularView<Eigen::LowerTriangular>();
- VERIFY(v2.isApprox(m3.conjugate() * (m1.conjugate().template triangularView<Eigen::LowerTriangular>().solve(v2)), largerEps));
+ m3 = m1.template triangularView<UpperTriangular>();
+ VERIFY(v2.isApprox(m3.adjoint() * (m1.adjoint().template triangularView<LowerTriangular>().solve(v2)), largerEps));
+ m3 = m1.template triangularView<LowerTriangular>();
+ VERIFY(v2.isApprox(m3.transpose() * (m1.transpose().template triangularView<UpperTriangular>().solve(v2)), largerEps));
+ m3 = m1.template triangularView<UpperTriangular>();
+ VERIFY(v2.isApprox(m3 * (m1.template triangularView<UpperTriangular>().solve(v2)), largerEps));
+ m3 = m1.template triangularView<LowerTriangular>();
+ VERIFY(v2.isApprox(m3.conjugate() * (m1.conjugate().template triangularView<LowerTriangular>().solve(v2)), largerEps));
// test back and forward subsitution with a matrix as the rhs
- m3 = m1.template triangularView<Eigen::UpperTriangular>();
- VERIFY(m2.isApprox(m3.adjoint() * (m1.adjoint().template triangularView<Eigen::LowerTriangular>().solve(m2)), largerEps));
- m3 = m1.template triangularView<Eigen::LowerTriangular>();
- VERIFY(m2.isApprox(m3.transpose() * (m1.transpose().template triangularView<Eigen::UpperTriangular>().solve(m2)), largerEps));
- m3 = m1.template triangularView<Eigen::UpperTriangular>();
- VERIFY(m2.isApprox(m3 * (m1.template triangularView<Eigen::UpperTriangular>().solve(m2)), largerEps));
- m3 = m1.template triangularView<Eigen::LowerTriangular>();
- VERIFY(m2.isApprox(m3.conjugate() * (m1.conjugate().template triangularView<Eigen::LowerTriangular>().solve(m2)), largerEps));
+ m3 = m1.template triangularView<UpperTriangular>();
+ VERIFY(m2.isApprox(m3.adjoint() * (m1.adjoint().template triangularView<LowerTriangular>().solve(m2)), largerEps));
+ m3 = m1.template triangularView<LowerTriangular>();
+ VERIFY(m2.isApprox(m3.transpose() * (m1.transpose().template triangularView<UpperTriangular>().solve(m2)), largerEps));
+ m3 = m1.template triangularView<UpperTriangular>();
+ VERIFY(m2.isApprox(m3 * (m1.template triangularView<UpperTriangular>().solve(m2)), largerEps));
+ m3 = m1.template triangularView<LowerTriangular>();
+ VERIFY(m2.isApprox(m3.conjugate() * (m1.conjugate().template triangularView<LowerTriangular>().solve(m2)), largerEps));
// check M * inv(L) using in place API
m4 = m3;
+<<<<<<< local
m3.transpose().template triangularView<Eigen::UpperTriangular>().solveInPlace(trm4);
VERIFY(m4.cwiseAbs().isIdentity(test_precision<RealScalar>()));
+=======
+ m3.transpose().template triangularView<UpperTriangular>().solveInPlace(trm4);
+ VERIFY(m4.cwise().abs().isIdentity(test_precision<RealScalar>()));
+>>>>>>> other
// check M * inv(U) using in place API
- m3 = m1.template triangularView<Eigen::UpperTriangular>();
+ m3 = m1.template triangularView<UpperTriangular>();
m4 = m3;
+<<<<<<< local
m3.transpose().template triangularView<Eigen::LowerTriangular>().solveInPlace(trm4);
VERIFY(m4.cwiseAbs().isIdentity(test_precision<RealScalar>()));
+=======
+ m3.transpose().template triangularView<LowerTriangular>().solveInPlace(trm4);
+ VERIFY(m4.cwise().abs().isIdentity(test_precision<RealScalar>()));
+>>>>>>> other
// check solve with unit diagonal
- m3 = m1.template triangularView<Eigen::UnitUpperTriangular>();
- VERIFY(m2.isApprox(m3 * (m1.template triangularView<Eigen::UnitUpperTriangular>().solve(m2)), largerEps));
+ m3 = m1.template triangularView<UnitUpperTriangular>();
+ VERIFY(m2.isApprox(m3 * (m1.template triangularView<UnitUpperTriangular>().solve(m2)), largerEps));
-// VERIFY(( m1.template triangularView<Eigen::UpperTriangular>()
-// * m2.template triangularView<Eigen::UpperTriangular>()).isUpperTriangular());
+// VERIFY(( m1.template triangularView<UpperTriangular>()
+// * m2.template triangularView<UpperTriangular>()).isUpperTriangular());
// test swap
m1.setOnes();
m2.setZero();
- m2.template triangularView<Eigen::UpperTriangular>().swap(m1);
+ m2.template triangularView<UpperTriangular>().swap(m1);
m3.setZero();
- m3.template triangularView<Eigen::UpperTriangular>().setOnes();
+ m3.template triangularView<UpperTriangular>().setOnes();
VERIFY_IS_APPROX(m2,m3);
}
+
+template<typename MatrixType> void triangular_rect(const MatrixType& m)
+{
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+ enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
+ typedef Matrix<Scalar, Rows, 1> VectorType;
+ typedef Matrix<Scalar, Rows, Rows> RMatrixType;
+
+
+ int rows = m.rows();
+ int cols = m.cols();
+
+ MatrixType m1 = MatrixType::Random(rows, cols),
+ m2 = MatrixType::Random(rows, cols),
+ m3(rows, cols),
+ m4(rows, cols),
+ r1(rows, cols),
+ r2(rows, cols),
+ mzero = MatrixType::Zero(rows, cols),
+ mones = MatrixType::Ones(rows, cols);
+ RMatrixType identity = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>
+ ::Identity(rows, rows),
+ square = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>
+ ::Random(rows, rows);
+ VectorType v1 = VectorType::Random(rows),
+ v2 = VectorType::Random(rows),
+ vzero = VectorType::Zero(rows);
+
+ MatrixType m1up = m1.template triangularView<UpperTriangular>();
+ MatrixType m2up = m2.template triangularView<UpperTriangular>();
+
+ if (rows*cols>1)
+ {
+ VERIFY(m1up.isUpperTriangular());
+ VERIFY(m2up.transpose().isLowerTriangular());
+ VERIFY(!m2.isLowerTriangular());
+ }
+
+ // test overloaded operator+=
+ r1.setZero();
+ r2.setZero();
+ r1.template triangularView<UpperTriangular>() += m1;
+ r2 += m1up;
+ VERIFY_IS_APPROX(r1,r2);
+
+ // test overloaded operator=
+ m1.setZero();
+ m1.template triangularView<UpperTriangular>() = 3 * m2;
+ m3 = 3 * m2;
+ VERIFY_IS_APPROX(m3.template triangularView<UpperTriangular>().toDenseMatrix(), m1);
+
+
+ m1.setZero();
+ m1.template triangularView<LowerTriangular>() = 3 * m2;
+ VERIFY_IS_APPROX(m3.template triangularView<LowerTriangular>().toDenseMatrix(), m1);
+
+ m1.setZero();
+ m1.template triangularView<StrictlyUpperTriangular>() = 3 * m2;
+ VERIFY_IS_APPROX(m3.template triangularView<StrictlyUpperTriangular>().toDenseMatrix(), m1);
+
+
+ m1.setZero();
+ m1.template triangularView<StrictlyLowerTriangular>() = 3 * m2;
+ VERIFY_IS_APPROX(m3.template triangularView<StrictlyLowerTriangular>().toDenseMatrix(), m1);
+ m1.setRandom();
+ m2 = m1.template triangularView<UpperTriangular>();
+ VERIFY(m2.isUpperTriangular());
+ VERIFY(!m2.isLowerTriangular());
+ m2 = m1.template triangularView<StrictlyUpperTriangular>();
+ VERIFY(m2.isUpperTriangular());
+ VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));
+ m2 = m1.template triangularView<UnitUpperTriangular>();
+ VERIFY(m2.isUpperTriangular());
+ m2.diagonal().cwise() -= Scalar(1);
+ VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));
+ m2 = m1.template triangularView<LowerTriangular>();
+ VERIFY(m2.isLowerTriangular());
+ VERIFY(!m2.isUpperTriangular());
+ m2 = m1.template triangularView<StrictlyLowerTriangular>();
+ VERIFY(m2.isLowerTriangular());
+ VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));
+ m2 = m1.template triangularView<UnitLowerTriangular>();
+ VERIFY(m2.isLowerTriangular());
+ m2.diagonal().cwise() -= Scalar(1);
+ VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));
+ // test swap
+ m1.setOnes();
+ m2.setZero();
+ m2.template triangularView<UpperTriangular>().swap(m1);
+ m3.setZero();
+ m3.template triangularView<UpperTriangular>().setOnes();
+ VERIFY_IS_APPROX(m2,m3);
+}
+
void test_triangular()
{
- for(int i = 0; i < g_repeat ; i++) {
- CALL_SUBTEST_1( triangular(Matrix<float, 1, 1>()) );
- CALL_SUBTEST_2( triangular(Matrix<float, 2, 2>()) );
- CALL_SUBTEST_3( triangular(Matrix3d()) );
- CALL_SUBTEST_4( triangular(MatrixXcf(4, 4)) );
- CALL_SUBTEST_5( triangular(Matrix<std::complex<float>,8, 8>()) );
- CALL_SUBTEST_6( triangular(MatrixXcd(17,17)) );
- CALL_SUBTEST_7( triangular(Matrix<float,Dynamic,Dynamic,RowMajor>(5, 5)) );
+ for(int i = 0; i < g_repeat ; i++)
+ {
+ EIGEN_UNUSED int r = ei_random<int>(2,20);
+ EIGEN_UNUSED int c = ei_random<int>(2,20);
+
+ CALL_SUBTEST_1( triangular_square(Matrix<float, 1, 1>()) );
+ CALL_SUBTEST_2( triangular_square(Matrix<float, 2, 2>()) );
+ CALL_SUBTEST_3( triangular_square(Matrix3d()) );
+ CALL_SUBTEST_4( triangular_square(Matrix<std::complex<float>,8, 8>()) );
+ CALL_SUBTEST_5( triangular_square(MatrixXcd(r,r)) );
+ CALL_SUBTEST_6( triangular_square(Matrix<float,Dynamic,Dynamic,RowMajor>(r, r)) );
+
+ CALL_SUBTEST_7( triangular_rect(Matrix<float, 4, 5>()) );
+ CALL_SUBTEST_8( triangular_rect(Matrix<double, 6, 2>()) );
+ CALL_SUBTEST_9( triangular_rect(MatrixXcf(r, c)) );
+ CALL_SUBTEST_5( triangular_rect(MatrixXcd(r, c)) );
+ CALL_SUBTEST_6( triangular_rect(Matrix<float,Dynamic,Dynamic,RowMajor>(r, c)) );
}
}
diff --git a/test/unalignedassert.cpp b/test/unalignedassert.cpp
index 2b819417e..85a83b7b5 100644
--- a/test/unalignedassert.cpp
+++ b/test/unalignedassert.cpp
@@ -87,6 +87,7 @@ void construct_at_boundary(int boundary)
_buf += (16 - (_buf % 16)); // make 16-byte aligned
_buf += boundary; // make exact boundary-aligned
T *x = ::new(reinterpret_cast<void*>(_buf)) T;
+ x[0].setZero(); // just in order to silence warnings
x->~T();
}
#endif
diff --git a/test/vectorization_logic.cpp b/test/vectorization_logic.cpp
index 71214485c..5d86df7b3 100644
--- a/test/vectorization_logic.cpp
+++ b/test/vectorization_logic.cpp
@@ -26,17 +26,18 @@
#include <typeinfo>
template<typename Dst, typename Src>
-bool test_assign(const Dst&, const Src&, int vectorization, int unrolling)
+bool test_assign(const Dst&, const Src&, int traversal, int unrolling)
{
- return ei_assign_traits<Dst,Src>::Vectorization==vectorization
+ ei_assign_traits<Dst,Src>::debug();
+ return ei_assign_traits<Dst,Src>::Traversal==traversal
&& ei_assign_traits<Dst,Src>::Unrolling==unrolling;
}
template<typename Xpr>
-bool test_redux(const Xpr&, int vectorization, int unrolling)
+bool test_redux(const Xpr&, int traversal, int unrolling)
{
typedef ei_redux_traits<ei_scalar_sum_op<typename Xpr::Scalar>,Xpr> traits;
- return traits::Vectorization==vectorization && traits::Unrolling==unrolling;
+ return traits::Traversal==traversal && traits::Unrolling==unrolling;
}
void test_vectorization_logic()
@@ -45,61 +46,67 @@ void test_vectorization_logic()
#ifdef EIGEN_VECTORIZE
VERIFY(test_assign(Vector4f(),Vector4f(),
- InnerVectorization,CompleteUnrolling));
+ InnerVectorizedTraversal,CompleteUnrolling));
VERIFY(test_assign(Vector4f(),Vector4f()+Vector4f(),
- InnerVectorization,CompleteUnrolling));
+ InnerVectorizedTraversal,CompleteUnrolling));
VERIFY(test_assign(Vector4f(),Vector4f().cwiseProduct(Vector4f()),
- InnerVectorization,CompleteUnrolling));
+ InnerVectorizedTraversal,CompleteUnrolling));
VERIFY(test_assign(Vector4f(),Vector4f().cast<float>(),
- InnerVectorization,CompleteUnrolling));
+ InnerVectorizedTraversal,CompleteUnrolling));
VERIFY(test_assign(Matrix4f(),Matrix4f(),
- InnerVectorization,CompleteUnrolling));
+ InnerVectorizedTraversal,CompleteUnrolling));
VERIFY(test_assign(Matrix4f(),Matrix4f()+Matrix4f(),
- InnerVectorization,CompleteUnrolling));
+ InnerVectorizedTraversal,CompleteUnrolling));
VERIFY(test_assign(Matrix4f(),Matrix4f().cwiseProduct(Matrix4f()),
- InnerVectorization,CompleteUnrolling));
+ InnerVectorizedTraversal,CompleteUnrolling));
VERIFY(test_assign(Matrix<float,16,16>(),Matrix<float,16,16>()+Matrix<float,16,16>(),
- InnerVectorization,InnerUnrolling));
+ InnerVectorizedTraversal,InnerUnrolling));
VERIFY(test_assign(Matrix<float,16,16,DontAlign>(),Matrix<float,16,16>()+Matrix<float,16,16>(),
- NoVectorization,InnerUnrolling));
+ LinearTraversal,NoUnrolling));
+
+ VERIFY(test_assign(Matrix<float,2,2,DontAlign>(),Matrix<float,2,2>()+Matrix<float,2,2>(),
+ LinearTraversal,CompleteUnrolling));
VERIFY(test_assign(Matrix<float,6,2>(),Matrix<float,6,2>().cwiseQuotient(Matrix<float,6,2>()),
- LinearVectorization,CompleteUnrolling));
+ LinearVectorizedTraversal,CompleteUnrolling));
VERIFY(test_assign(Matrix<float,17,17>(),Matrix<float,17,17>()+Matrix<float,17,17>(),
- NoVectorization,InnerUnrolling));
+ LinearTraversal,NoUnrolling));
+
+ VERIFY(test_assign(Matrix<float,3,3>(),Matrix<float,3,3>()+Matrix<float,3,3>(),
+ LinearTraversal,CompleteUnrolling));
VERIFY(test_assign(Matrix<float,4,4>(),Matrix<float,17,17>().block<4,4>(2,3)+Matrix<float,17,17>().block<4,4>(10,4),
- NoVectorization,CompleteUnrolling));
+ DefaultTraversal,CompleteUnrolling));
VERIFY(test_assign(MatrixXf(10,10),MatrixXf(20,20).block(10,10,2,3),
- SliceVectorization,NoUnrolling));
+ SliceVectorizedTraversal,NoUnrolling));
VERIFY(test_redux(VectorXf(10),
- LinearVectorization,NoUnrolling));
+ LinearVectorizedTraversal,NoUnrolling));
VERIFY(test_redux(Matrix<float,5,2>(),
- NoVectorization,CompleteUnrolling));
+ DefaultTraversal,CompleteUnrolling));
VERIFY(test_redux(Matrix<float,6,2>(),
- LinearVectorization,CompleteUnrolling));
+ LinearVectorizedTraversal,CompleteUnrolling));
VERIFY(test_redux(Matrix<float,16,16>(),
- LinearVectorization,NoUnrolling));
+ LinearVectorizedTraversal,NoUnrolling));
VERIFY(test_redux(Matrix<float,16,16>().block<4,4>(1,2),
- NoVectorization,CompleteUnrolling));
+ DefaultTraversal,CompleteUnrolling));
VERIFY(test_redux(Matrix<float,16,16>().block<8,1>(1,2),
- LinearVectorization,CompleteUnrolling));
+ LinearVectorizedTraversal,CompleteUnrolling));
VERIFY(test_redux(Matrix<double,7,3>(),
- NoVectorization,CompleteUnrolling));
+ DefaultTraversal,CompleteUnrolling));
#endif // EIGEN_VECTORIZE
diff --git a/unsupported/Eigen/AlignedVector3 b/unsupported/Eigen/AlignedVector3
index f20fad6d1..a1510f19d 100644
--- a/unsupported/Eigen/AlignedVector3
+++ b/unsupported/Eigen/AlignedVector3
@@ -188,7 +188,7 @@ template<typename _Scalar> class AlignedVector3
}
template<typename Derived>
- inline bool isApprox(const MatrixBase<Derived>& other, RealScalar eps=precision<Scalar>()) const
+ inline bool isApprox(const MatrixBase<Derived>& other, RealScalar eps=dummy_precision<Scalar>()) const
{
return m_coeffs.template start<3>().isApprox(other,eps);
}
diff --git a/unsupported/Eigen/AutoDiff b/unsupported/Eigen/AutoDiff
index 229c15e69..a8b3ea90a 100644
--- a/unsupported/Eigen/AutoDiff
+++ b/unsupported/Eigen/AutoDiff
@@ -25,7 +25,7 @@
#ifndef EIGEN_AUTODIFF_MODULE
#define EIGEN_AUTODIFF_MODULE
-#include <Eigen/Core>
+#include <Eigen/Array>
namespace Eigen {
diff --git a/unsupported/Eigen/FFT b/unsupported/Eigen/FFT
index c8521bbf0..a43cd8d97 100644
--- a/unsupported/Eigen/FFT
+++ b/unsupported/Eigen/FFT
@@ -44,11 +44,42 @@
* The build-in implementation is based on kissfft. It is a small, free, and
* reasonably efficient default.
*
- * Frontends are
+ * There are currently two frontends:
*
* - fftw (http://www.fftw.org) : faster, GPL -- incompatible with Eigen in LGPL form, bigger code size.
- * - MLK (http://en.wikipedia.org/wiki/Math_Kernel_Library) : fastest, commercial -- may be incompatible with Eigen in GPL form
+ * - MLK (http://en.wikipedia.org/wiki/Math_Kernel_Library) : fastest, commercial -- may be incompatible with Eigen in GPL form.
*
+ * \section FFTDesign Design
+ *
+ * The following design decisions were made concerning scaling and
+ * half-spectrum for real FFT.
+ *
+ * The intent is to facilitate generic programming and ease migrating code
+ * from Matlab/octave.
+ * We think the default behavior of Eigen/FFT should favor correctness and
+ * generality over speed. Of course, the caller should be able to "opt-out" from this
+ * behavior and get the speed increase if they want it.
+ *
+ * 1) %Scaling:
+ * Other libraries (FFTW,IMKL,KISSFFT) do not perform scaling, so there
+ * is a constant gain incurred after the forward&inverse transforms , so
+ * IFFT(FFT(x)) = Kx; this is done to avoid a vector-by-value multiply.
+ * The downside is that algorithms that worked correctly in Matlab/octave
+ * don't behave the same way once implemented in C++.
+ *
+ * How Eigen/FFT differs: invertible scaling is performed so IFFT( FFT(x) ) = x.
+ *
+ * 2) Real FFT half-spectrum
+ * Other libraries use only half the frequency spectrum (plus one extra
+ * sample for the Nyquist bin) for a real FFT, the other half is the
+ * conjugate-symmetric of the first half. This saves them a copy and some
+ * memory. The downside is the caller needs to have special logic for the
+ * number of bins in complex vs real.
+ *
+ * How Eigen/FFT differs: The full spectrum is returned from the forward
+ * transform. This facilitates generic template programming by obviating
+ * separate specializations for real vs complex. On the inverse
+ * transform, only half the spectrum is actually used if the output type is real.
*/
@@ -129,7 +160,7 @@ class FFT
dst.resize( (src.size()>>1)+1);
else
dst.resize(src.size());
- fwd(&dst[0],&src[0],src.size());
+ fwd(&dst[0],&src[0],static_cast<int>(src.size()));
}
template<typename InputDerived, typename ComplexDerived>
@@ -193,7 +224,7 @@ class FFT
dst.resize( 2*(src.size()-1) );
else
dst.resize( src.size() );
- inv( &dst[0],&src[0],dst.size() );
+ inv( &dst[0],&src[0],static_cast<int>(dst.size()) );
}
// TODO: multi-dimensional FFTs
diff --git a/unsupported/Eigen/MatrixFunctions b/unsupported/Eigen/MatrixFunctions
index 0d785c344..bf2223a6e 100644
--- a/unsupported/Eigen/MatrixFunctions
+++ b/unsupported/Eigen/MatrixFunctions
@@ -25,27 +25,29 @@
#ifndef EIGEN_MATRIX_FUNCTIONS
#define EIGEN_MATRIX_FUNCTIONS
+#include <list>
+#include <functional>
+#include <iterator>
+
#include <Eigen/Core>
#include <Eigen/Array>
#include <Eigen/LU>
+#include <Eigen/Eigenvalues>
namespace Eigen {
/** \ingroup Unsupported_modules
* \defgroup MatrixFunctions_Module Matrix functions module
* \brief This module aims to provide various methods for the computation of
- * matrix functions. Currently, there is only support for the matrix
- * exponential.
+ * matrix functions.
*
* \code
* #include <unsupported/Eigen/MatrixFunctions>
* \endcode
*/
-//@{
#include "src/MatrixFunctions/MatrixExponential.h"
-
-//@}
+#include "src/MatrixFunctions/MatrixFunction.h"
}
diff --git a/unsupported/Eigen/NonLinearOptimization b/unsupported/Eigen/NonLinearOptimization
index 601b1abc7..c413af436 100644
--- a/unsupported/Eigen/NonLinearOptimization
+++ b/unsupported/Eigen/NonLinearOptimization
@@ -26,6 +26,7 @@
#define EIGEN_NONLINEAROPTIMIZATION_MODULE
#include <Eigen/Core>
+#include <Eigen/Jacobi>
#include <unsupported/Eigen/NumericalDiff>
namespace Eigen {
@@ -43,7 +44,7 @@ namespace Eigen {
* actually linear. But if this is so, you should probably better use other
* methods more fitted to this special case.
*
- * One algorithm allows to find the extremum of such a system (Levenberg
+ * One algorithm allows to find an extremum of such a system (Levenberg
* Marquardt algorithm) and the second one is used to find
* a zero for the system (Powell hybrid "dogleg" method).
*
@@ -121,8 +122,6 @@ namespace Eigen {
*
*/
-//@{
-
#ifndef EIGEN_PARSED_BY_DOXYGEN
#include "src/NonLinearOptimization/qrsolv.h"
@@ -142,7 +141,6 @@ namespace Eigen {
#include "src/NonLinearOptimization/HybridNonLinearSolver.h"
#include "src/NonLinearOptimization/LevenbergMarquardt.h"
-//@}
}
diff --git a/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h b/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
index c4607c2b8..795dd6b4d 100644
--- a/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
+++ b/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
@@ -212,33 +212,33 @@ class AutoDiffScalar
template<typename OtherDerType>
inline const AutoDiffScalar<typename MakeCwiseUnaryOp<ei_scalar_multiple_op<Scalar>,
- typename MakeNestByValue<typename MakeCwiseBinaryOp<ei_scalar_difference_op<Scalar>,
- typename MakeNestByValue<typename MakeCwiseUnaryOp<ei_scalar_multiple_op<Scalar>, DerType>::Type>::Type,
- typename MakeNestByValue<typename MakeCwiseUnaryOp<ei_scalar_multiple_op<Scalar>, typename ei_cleantype<OtherDerType>::type>::Type>::Type >::Type >::Type >::Type >
+ typename MakeCwiseBinaryOp<ei_scalar_difference_op<Scalar>,
+ typename MakeCwiseUnaryOp<ei_scalar_multiple_op<Scalar>, DerType>::Type,
+ typename MakeCwiseUnaryOp<ei_scalar_multiple_op<Scalar>, typename ei_cleantype<OtherDerType>::type>::Type>::Type >::Type >
operator/(const AutoDiffScalar<OtherDerType>& other) const
{
ei_make_coherent(m_derivatives, other.derivatives());
return AutoDiffScalar<typename MakeCwiseUnaryOp<ei_scalar_multiple_op<Scalar>,
- typename MakeNestByValue<typename MakeCwiseBinaryOp<ei_scalar_difference_op<Scalar>,
- typename MakeNestByValue<typename MakeCwiseUnaryOp<ei_scalar_multiple_op<Scalar>, DerType>::Type>::Type,
- typename MakeNestByValue<typename MakeCwiseUnaryOp<ei_scalar_multiple_op<Scalar>, typename ei_cleantype<OtherDerType>::type>::Type>::Type >::Type >::Type >::Type >(
+ typename MakeCwiseBinaryOp<ei_scalar_difference_op<Scalar>,
+ typename MakeCwiseUnaryOp<ei_scalar_multiple_op<Scalar>, DerType>::Type,
+ typename MakeCwiseUnaryOp<ei_scalar_multiple_op<Scalar>, typename ei_cleantype<OtherDerType>::type>::Type>::Type >::Type >(
m_value / other.value(),
- ((m_derivatives * other.value()).nestByValue() - (m_value * other.derivatives()).nestByValue()).nestByValue()
+ ((m_derivatives * other.value()) - (m_value * other.derivatives()))
* (Scalar(1)/(other.value()*other.value())));
}
template<typename OtherDerType>
inline const AutoDiffScalar<typename MakeCwiseBinaryOp<ei_scalar_sum_op<Scalar>,
- typename MakeNestByValue<typename MakeCwiseUnaryOp<ei_scalar_multiple_op<Scalar>, DerType>::Type>::Type,
- typename MakeNestByValue<typename MakeCwiseUnaryOp<ei_scalar_multiple_op<Scalar>, typename ei_cleantype<OtherDerType>::type>::Type>::Type >::Type >
+ typename MakeCwiseUnaryOp<ei_scalar_multiple_op<Scalar>, DerType>::Type,
+ typename MakeCwiseUnaryOp<ei_scalar_multiple_op<Scalar>, typename ei_cleantype<OtherDerType>::type>::Type>::Type >
operator*(const AutoDiffScalar<OtherDerType>& other) const
{
ei_make_coherent(m_derivatives, other.derivatives());
return AutoDiffScalar<typename MakeCwiseBinaryOp<ei_scalar_sum_op<Scalar>,
- typename MakeNestByValue<typename MakeCwiseUnaryOp<ei_scalar_multiple_op<Scalar>, DerType>::Type>::Type,
- typename MakeNestByValue<typename MakeCwiseUnaryOp<ei_scalar_multiple_op<Scalar>, typename ei_cleantype<OtherDerType>::type>::Type>::Type >::Type >(
+ typename MakeCwiseUnaryOp<ei_scalar_multiple_op<Scalar>, DerType>::Type,
+ typename MakeCwiseUnaryOp<ei_scalar_multiple_op<Scalar>, typename ei_cleantype<OtherDerType>::type>::Type>::Type >(
m_value * other.value(),
- (m_derivatives * other.value()).nestByValue() + (m_value * other.derivatives()).nestByValue());
+ (m_derivatives * other.value()) + (m_value * other.derivatives()));
}
inline AutoDiffScalar& operator*=(const Scalar& other)
diff --git a/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h b/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h
index 03c82b7e8..c0765d494 100644
--- a/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h
+++ b/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h
@@ -196,17 +196,17 @@ class AutoDiffVector
// inline const AutoDiffVector<
// CwiseBinaryOp<ei_scalar_multiple_op<Scalar>, ValueType, OtherValueType>
// CwiseBinaryOp<ei_scalar_sum_op<Scalar>,
-// NestByValue<CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, JacobianType> >,
-// NestByValue<CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, OtherJacobianType> > > >
+// CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, JacobianType>,
+// CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, OtherJacobianType> > >
// operator*(const AutoDiffVector<OtherValueType,OtherJacobianType>& other) const
// {
// return AutoDiffVector<
// CwiseBinaryOp<ei_scalar_multiple_op<Scalar>, ValueType, OtherValueType>
// CwiseBinaryOp<ei_scalar_sum_op<Scalar>,
-// NestByValue<CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, JacobianType> >,
-// NestByValue<CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, OtherJacobianType> > > >(
+// CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, JacobianType>,
+// CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, OtherJacobianType> > >(
// m_values.cwise() * other.values(),
-// (m_jacobian * other.values()).nestByValue() + (m_values * other.jacobian()).nestByValue());
+// (m_jacobian * other.values()) + (m_values * other.jacobian()));
// }
inline AutoDiffVector& operator*=(const Scalar& other)
diff --git a/unsupported/Eigen/src/BVH/BVAlgorithms.h b/unsupported/Eigen/src/BVH/BVAlgorithms.h
index 47c49be7f..63725763a 100644
--- a/unsupported/Eigen/src/BVH/BVAlgorithms.h
+++ b/unsupported/Eigen/src/BVH/BVAlgorithms.h
@@ -74,6 +74,8 @@ struct ei_intersector_helper1
bool intersectObject(const Object1 &obj) { return intersector.intersectObjectObject(obj, stored); }
Object2 stored;
Intersector &intersector;
+private:
+ ei_intersector_helper1& operator=(const ei_intersector_helper1&);
};
template<typename Volume2, typename Object2, typename Object1, typename Intersector>
@@ -216,6 +218,8 @@ struct ei_minimizer_helper2
Scalar minimumOnObject(const Object2 &obj) { return minimizer.minimumOnObjectObject(stored, obj); }
Object1 stored;
Minimizer &minimizer;
+private:
+ ei_minimizer_helper2& operator=(const ei_minimizer_helper2&);
};
/** Given two BVH's, runs the query on their cartesian product encapsulated by \a minimizer.
diff --git a/unsupported/Eigen/src/BVH/KdBVH.h b/unsupported/Eigen/src/BVH/KdBVH.h
index ec47254af..c4719607f 100644
--- a/unsupported/Eigen/src/BVH/KdBVH.h
+++ b/unsupported/Eigen/src/BVH/KdBVH.h
@@ -107,7 +107,7 @@ public:
children.clear();
objects.insert(objects.end(), begin, end);
- int n = objects.size();
+ int n = static_cast<int>(objects.size());
if(n < 2)
return; //if we have at most one object, we don't need any internal nodes
@@ -149,7 +149,7 @@ public:
return;
}
- int numBoxes = boxes.size();
+ int numBoxes = static_cast<int>(boxes.size());
int idx = index * 2;
if(children[idx + 1] < numBoxes) { //second index is always bigger
diff --git a/unsupported/Eigen/src/CMakeLists.txt b/unsupported/Eigen/src/CMakeLists.txt
index 195808c59..a0870d3af 100644
--- a/unsupported/Eigen/src/CMakeLists.txt
+++ b/unsupported/Eigen/src/CMakeLists.txt
@@ -2,6 +2,6 @@ ADD_SUBDIRECTORY(IterativeSolvers)
ADD_SUBDIRECTORY(BVH)
ADD_SUBDIRECTORY(AutoDiff)
ADD_SUBDIRECTORY(MoreVectorization)
-ADD_SUBDIRECTORY(FFT)
-ADD_SUBDIRECTORY(Skyline)
+# ADD_SUBDIRECTORY(FFT)
+# ADD_SUBDIRECTORY(Skyline)
ADD_SUBDIRECTORY(MatrixFunctions)
diff --git a/unsupported/Eigen/src/FFT/ei_kissfft_impl.h b/unsupported/Eigen/src/FFT/ei_kissfft_impl.h
index 5c958d1ec..dbd92132e 100644
--- a/unsupported/Eigen/src/FFT/ei_kissfft_impl.h
+++ b/unsupported/Eigen/src/FFT/ei_kissfft_impl.h
@@ -160,7 +160,7 @@ struct ei_kiss_cpx_fft
scratch[0]=scratch[1]-scratch[2];
tw1 += fstride;
tw2 += fstride*2;
- Fout[m] = Complex( Fout->real() - .5*scratch[3].real() , Fout->imag() - .5*scratch[3].imag() );
+ Fout[m] = Complex( Fout->real() - Scalar(.5)*scratch[3].real() , Fout->imag() - Scalar(.5)*scratch[3].imag() );
scratch[0] *= epi3.imag();
*Fout += scratch[3];
Fout[m2] = Complex( Fout[m].real() + scratch[0].imag() , Fout[m].imag() - scratch[0].real() );
@@ -247,7 +247,7 @@ struct ei_kiss_cpx_fft
int u,k,q1,q;
Complex * twiddles = &m_twiddles[0];
Complex t;
- int Norig = m_twiddles.size();
+ int Norig = static_cast<int>(m_twiddles.size());
Complex * scratchbuf = &m_scratchBuf[0];
for ( u=0; u<m; ++u ) {
@@ -262,7 +262,7 @@ struct ei_kiss_cpx_fft
int twidx=0;
Fout[ k ] = scratchbuf[0];
for (q=1;q<p;++q ) {
- twidx += fstride * k;
+ twidx += static_cast<int>(fstride) * k;
if (twidx>=Norig) twidx-=Norig;
t=scratchbuf[q] * twiddles[twidx];
Fout[ k ] += t;
@@ -377,10 +377,10 @@ struct ei_kissfft_impl
std::vector<Complex> m_tmpBuf2;
inline
- int PlanKey(int nfft,bool isinverse) const { return (nfft<<1) | isinverse; }
+ int PlanKey(int nfft, bool isinverse) const { return (nfft<<1) | int(isinverse); }
inline
- PlanData & get_plan(int nfft,bool inverse)
+ PlanData & get_plan(int nfft, bool inverse)
{
// TODO look for PlanKey(nfft, ! inverse) and conjugate the twiddles
PlanData & pd = m_plans[ PlanKey(nfft,inverse) ];
@@ -400,7 +400,7 @@ struct ei_kissfft_impl
int ncfft= ncfft2<<1;
Scalar pi = acos( Scalar(-1) );
for (int k=1;k<=ncfft2;++k)
- twidref[k-1] = exp( Complex(0,-pi * ((double) (k) / ncfft + .5) ) );
+ twidref[k-1] = exp( Complex(0,-pi * (Scalar(k) / ncfft + Scalar(.5)) ) );
}
return &twidref[0];
}
diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
index 636f37655..b45aeae58 100644
--- a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
+++ b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
@@ -29,7 +29,9 @@
template <typename Scalar> Scalar log2(Scalar v) { return std::log(v)/std::log(Scalar(2)); }
#endif
-/** \brief Compute the matrix exponential.
+/** \ingroup MatrixFunctions_Module
+ *
+ * \brief Compute the matrix exponential.
*
* \param M matrix whose exponential is to be computed.
* \param result pointer to the matrix in which to store the result.
@@ -58,6 +60,22 @@
* <em>SIAM J. %Matrix Anal. Applic.</em>, <b>26</b>:1179&ndash;1193,
* 2005.
*
+ * Example: The following program checks that
+ * \f[ \exp \left[ \begin{array}{ccc}
+ * 0 & \frac14\pi & 0 \\
+ * -\frac14\pi & 0 & 0 \\
+ * 0 & 0 & 0
+ * \end{array} \right] = \left[ \begin{array}{ccc}
+ * \frac12\sqrt2 & -\frac12\sqrt2 & 0 \\
+ * \frac12\sqrt2 & \frac12\sqrt2 & 0 \\
+ * 0 & 0 & 1
+ * \end{array} \right]. \f]
+ * This corresponds to a rotation of \f$ \frac14\pi \f$ radians around
+ * the z-axis.
+ *
+ * \include MatrixExponential.cpp
+ * Output: \verbinclude MatrixExponential.out
+ *
* \note \p M has to be a matrix of \c float, \c double,
* \c complex<float> or \c complex<double> .
*/
@@ -65,7 +83,9 @@ template <typename Derived>
EIGEN_STRONG_INLINE void ei_matrix_exponential(const MatrixBase<Derived> &M,
typename MatrixBase<Derived>::PlainMatrixType* result);
-/** \brief Class for computing the matrix exponential.*/
+/** \ingroup MatrixFunctions_Module
+ * \brief Class for computing the matrix exponential.
+ */
template <typename MatrixType>
class MatrixExponential {
@@ -272,7 +292,7 @@ void MatrixExponential<MatrixType>::computeUV(float)
} else {
const float maxnorm = 3.925724783138660f;
m_squarings = std::max(0, (int)ceil(log2(m_l1norm / maxnorm)));
- MatrixType A = *m_M / std::pow(Scalar(2), m_squarings);
+ MatrixType A = *m_M / std::pow(Scalar(2), Scalar(static_cast<RealScalar>(m_squarings)));
pade7(A);
}
}
@@ -291,7 +311,7 @@ void MatrixExponential<MatrixType>::computeUV(double)
} else {
const double maxnorm = 5.371920351148152;
m_squarings = std::max(0, (int)ceil(log2(m_l1norm / maxnorm)));
- MatrixType A = *m_M / std::pow(Scalar(2), m_squarings);
+ MatrixType A = *m_M / std::pow(Scalar(2), Scalar(m_squarings));
pade13(A);
}
}
diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h b/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h
new file mode 100644
index 000000000..7103ac541
--- /dev/null
+++ b/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h
@@ -0,0 +1,475 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2009 Jitse Niesen <jitse@maths.leeds.ac.uk>
+//
+// Eigen is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 3 of the License, or (at your option) any later version.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_MATRIX_FUNCTION
+#define EIGEN_MATRIX_FUNCTION
+
+template <typename Scalar>
+struct ei_stem_function
+{
+ typedef std::complex<typename NumTraits<Scalar>::Real> ComplexScalar;
+ typedef ComplexScalar type(ComplexScalar, int);
+};
+
+/** \ingroup MatrixFunctions_Module
+ *
+ * \brief Compute a matrix function.
+ *
+ * \param[in] M argument of matrix function, should be a square matrix.
+ * \param[in] f an entire function; \c f(x,n) should compute the n-th derivative of f at x.
+ * \param[out] result pointer to the matrix in which to store the result, \f$ f(M) \f$.
+ *
+ * Suppose that \f$ f \f$ is an entire function (that is, a function
+ * on the complex plane that is everywhere complex differentiable).
+ * Then its Taylor series
+ * \f[ f(0) + f'(0) x + \frac{f''(0)}{2} x^2 + \frac{f'''(0)}{3!} x^3 + \cdots \f]
+ * converges to \f$ f(x) \f$. In this case, we can define the matrix
+ * function by the same series:
+ * \f[ f(M) = f(0) + f'(0) M + \frac{f''(0)}{2} M^2 + \frac{f'''(0)}{3!} M^3 + \cdots \f]
+ *
+ * This routine uses the algorithm described in:
+ * Philip Davies and Nicholas J. Higham,
+ * "A Schur-Parlett algorithm for computing matrix functions",
+ * <em>SIAM J. %Matrix Anal. Applic.</em>, <b>25</b>:464&ndash;485, 2003.
+ *
+ * Example: The following program checks that
+ * \f[ \exp \left[ \begin{array}{ccc}
+ * 0 & \frac14\pi & 0 \\
+ * -\frac14\pi & 0 & 0 \\
+ * 0 & 0 & 0
+ * \end{array} \right] = \left[ \begin{array}{ccc}
+ * \frac12\sqrt2 & -\frac12\sqrt2 & 0 \\
+ * \frac12\sqrt2 & \frac12\sqrt2 & 0 \\
+ * 0 & 0 & 1
+ * \end{array} \right]. \f]
+ * This corresponds to a rotation of \f$ \frac14\pi \f$ radians around
+ * the z-axis. This is the same example as used in the documentation
+ * of ei_matrix_exponential().
+ *
+ * Note that the function \c expfn is defined for complex numbers \c x,
+ * even though the matrix \c A is over the reals.
+ *
+ * \include MatrixFunction.cpp
+ * Output: \verbinclude MatrixFunction.out
+ */
+template <typename Derived>
+EIGEN_STRONG_INLINE void ei_matrix_function(const MatrixBase<Derived>& M,
+ typename ei_stem_function<typename ei_traits<Derived>::Scalar>::type f,
+ typename MatrixBase<Derived>::PlainMatrixType* result);
+
+
+/** \ingroup MatrixFunctions_Module
+ * \class MatrixFunction
+ * \brief Helper class for computing matrix functions.
+ */
+template <typename MatrixType,
+ int IsComplex = NumTraits<typename ei_traits<MatrixType>::Scalar>::IsComplex,
+ int IsDynamic = ( (ei_traits<MatrixType>::RowsAtCompileTime == Dynamic)
+ && (ei_traits<MatrixType>::RowsAtCompileTime == Dynamic) ) >
+class MatrixFunction;
+
+/* Partial specialization of MatrixFunction for real matrices */
+
+template <typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols, int IsDynamic>
+class MatrixFunction<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>, 0, IsDynamic>
+{
+ public:
+
+ typedef std::complex<Scalar> ComplexScalar;
+ typedef Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> MatrixType;
+ typedef Matrix<ComplexScalar, Rows, Cols, Options, MaxRows, MaxCols> ComplexMatrix;
+ typedef typename ei_stem_function<Scalar>::type StemFunction;
+
+ MatrixFunction(const MatrixType& A, StemFunction f, MatrixType* result)
+ {
+ ComplexMatrix CA = A.template cast<ComplexScalar>();
+ ComplexMatrix Cresult;
+ MatrixFunction<ComplexMatrix>(CA, f, &Cresult);
+ result->resize(A.cols(), A.rows());
+ for (int j = 0; j < A.cols(); j++)
+ for (int i = 0; i < A.rows(); i++)
+ (*result)(i,j) = std::real(Cresult(i,j));
+ }
+};
+
+/* Partial specialization of MatrixFunction for complex static-size matrices */
+
+template <typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
+class MatrixFunction<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>, 1, 0>
+{
+ public:
+
+ typedef Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> MatrixType;
+ typedef Matrix<Scalar, Dynamic, Dynamic, Options, MaxRows, MaxCols> DynamicMatrix;
+ typedef typename ei_stem_function<Scalar>::type StemFunction;
+
+ MatrixFunction(const MatrixType& A, StemFunction f, MatrixType* result)
+ {
+ DynamicMatrix DA = A;
+ DynamicMatrix Dresult;
+ MatrixFunction<DynamicMatrix>(DA, f, &Dresult);
+ *result = Dresult;
+ }
+};
+
+/* Partial specialization of MatrixFunction for complex dynamic-size matrices */
+
+template <typename MatrixType>
+class MatrixFunction<MatrixType, 1, 1>
+{
+ public:
+
+ typedef ei_traits<MatrixType> Traits;
+ typedef typename Traits::Scalar Scalar;
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+ typedef typename ei_stem_function<Scalar>::type StemFunction;
+ typedef Matrix<Scalar, Traits::RowsAtCompileTime, 1> VectorType;
+ typedef Matrix<int, Traits::RowsAtCompileTime, 1> IntVectorType;
+ typedef std::list<Scalar> listOfScalars;
+ typedef std::list<listOfScalars> listOfLists;
+
+ /** \brief Compute matrix function.
+ *
+ * \param A argument of matrix function.
+ * \param f function to compute.
+ * \param result pointer to the matrix in which to store the result.
+ */
+ MatrixFunction(const MatrixType& A, StemFunction f, MatrixType* result);
+
+ private:
+
+ // Prevent copying
+ MatrixFunction(const MatrixFunction&);
+ MatrixFunction& operator=(const MatrixFunction&);
+
+ void separateBlocksInSchur(MatrixType& T, MatrixType& U, IntVectorType& blockSize);
+ void permuteSchur(const IntVectorType& permutation, MatrixType& T, MatrixType& U);
+ void swapEntriesInSchur(int index, MatrixType& T, MatrixType& U);
+ void computeTriangular(const MatrixType& T, MatrixType& result, const IntVectorType& blockSize);
+ void computeBlockAtomic(const MatrixType& T, MatrixType& result, const IntVectorType& blockSize);
+ MatrixType solveSylvester(const MatrixType& A, const MatrixType& B, const MatrixType& C);
+ MatrixType computeAtomic(const MatrixType& T);
+ void divideInBlocks(const VectorType& v, listOfLists* result);
+ void constructPermutation(const VectorType& diag, const listOfLists& blocks,
+ IntVectorType& blockSize, IntVectorType& permutation);
+
+ RealScalar computeMu(const MatrixType& M);
+ bool taylorConverged(const MatrixType& T, int s, const MatrixType& F,
+ const MatrixType& Fincr, const MatrixType& P, RealScalar mu);
+
+ static const RealScalar separation() { return static_cast<RealScalar>(0.01); }
+ StemFunction *m_f;
+};
+
+template <typename MatrixType>
+MatrixFunction<MatrixType,1,1>::MatrixFunction(const MatrixType& A, StemFunction f, MatrixType* result) :
+ m_f(f)
+{
+ if (A.rows() == 1) {
+ result->resize(1,1);
+ (*result)(0,0) = f(A(0,0), 0);
+ } else {
+ const ComplexSchur<MatrixType> schurOfA(A);
+ MatrixType T = schurOfA.matrixT();
+ MatrixType U = schurOfA.matrixU();
+ IntVectorType blockSize, permutation;
+ separateBlocksInSchur(T, U, blockSize);
+ MatrixType fT;
+ computeTriangular(T, fT, blockSize);
+ *result = U * fT * U.adjoint();
+ }
+}
+
+template <typename MatrixType>
+void MatrixFunction<MatrixType,1,1>::separateBlocksInSchur(MatrixType& T, MatrixType& U, IntVectorType& blockSize)
+{
+ const VectorType d = T.diagonal();
+ listOfLists blocks;
+ divideInBlocks(d, &blocks);
+
+ IntVectorType permutation;
+ constructPermutation(d, blocks, blockSize, permutation);
+ permuteSchur(permutation, T, U);
+}
+
+template <typename MatrixType>
+void MatrixFunction<MatrixType,1,1>::permuteSchur(const IntVectorType& permutation, MatrixType& T, MatrixType& U)
+{
+ IntVectorType p = permutation;
+ for (int i = 0; i < p.rows() - 1; i++) {
+ int j;
+ for (j = i; j < p.rows(); j++) {
+ if (p(j) == i) break;
+ }
+ ei_assert(p(j) == i);
+ for (int k = j-1; k >= i; k--) {
+ swapEntriesInSchur(k, T, U);
+ std::swap(p.coeffRef(k), p.coeffRef(k+1));
+ }
+ }
+}
+
+// swap T(index, index) and T(index+1, index+1)
+template <typename MatrixType>
+void MatrixFunction<MatrixType,1,1>::swapEntriesInSchur(int index, MatrixType& T, MatrixType& U)
+{
+ PlanarRotation<Scalar> rotation;
+ rotation.makeGivens(T(index, index+1), T(index+1, index+1) - T(index, index));
+ T.applyOnTheLeft(index, index+1, rotation.adjoint());
+ T.applyOnTheRight(index, index+1, rotation);
+ U.applyOnTheRight(index, index+1, rotation);
+}
+
+template <typename MatrixType>
+void MatrixFunction<MatrixType,1,1>::computeTriangular(const MatrixType& T, MatrixType& result,
+ const IntVectorType& blockSize)
+{
+ MatrixType expT;
+ ei_matrix_exponential(T, &expT);
+ computeBlockAtomic(T, result, blockSize);
+ IntVectorType blockStart(blockSize.rows());
+ blockStart(0) = 0;
+ for (int i = 1; i < blockSize.rows(); i++) {
+ blockStart(i) = blockStart(i-1) + blockSize(i-1);
+ }
+ for (int diagIndex = 1; diagIndex < blockSize.rows(); diagIndex++) {
+ for (int blockIndex = 0; blockIndex < blockSize.rows() - diagIndex; blockIndex++) {
+ // compute (blockIndex, blockIndex+diagIndex) block
+ MatrixType A = T.block(blockStart(blockIndex), blockStart(blockIndex), blockSize(blockIndex), blockSize(blockIndex));
+ MatrixType B = -T.block(blockStart(blockIndex+diagIndex), blockStart(blockIndex+diagIndex), blockSize(blockIndex+diagIndex), blockSize(blockIndex+diagIndex));
+ MatrixType C = result.block(blockStart(blockIndex), blockStart(blockIndex), blockSize(blockIndex), blockSize(blockIndex)) * T.block(blockStart(blockIndex), blockStart(blockIndex+diagIndex), blockSize(blockIndex), blockSize(blockIndex+diagIndex));
+ C -= T.block(blockStart(blockIndex), blockStart(blockIndex+diagIndex), blockSize(blockIndex), blockSize(blockIndex+diagIndex)) * result.block(blockStart(blockIndex+diagIndex), blockStart(blockIndex+diagIndex), blockSize(blockIndex+diagIndex), blockSize(blockIndex+diagIndex));
+ for (int k = blockIndex + 1; k < blockIndex + diagIndex; k++) {
+ C += result.block(blockStart(blockIndex), blockStart(k), blockSize(blockIndex), blockSize(k)) * T.block(blockStart(k), blockStart(blockIndex+diagIndex), blockSize(k), blockSize(blockIndex+diagIndex));
+ C -= T.block(blockStart(blockIndex), blockStart(k), blockSize(blockIndex), blockSize(k)) * result.block(blockStart(k), blockStart(blockIndex+diagIndex), blockSize(k), blockSize(blockIndex+diagIndex));
+ }
+ result.block(blockStart(blockIndex), blockStart(blockIndex+diagIndex), blockSize(blockIndex), blockSize(blockIndex+diagIndex)) = solveSylvester(A, B, C);
+ }
+ }
+}
+
+// solve AX + XB = C <=> U* A' U X V V* + U* U X V B' V* = U* U C V V* <=> A' U X V + U X V B' = U C V
+// Schur: A* = U A'* U* (so A = U* A' U), B = V B' V*, define: X' = U X V, C' = U C V, to get: A' X' + X' B' = C'
+// A is m-by-m, B is n-by-n, X is m-by-n, C is m-by-n, U is m-by-m, V is n-by-n
+template <typename MatrixType>
+MatrixType MatrixFunction<MatrixType,1,1>::solveSylvester(const MatrixType& A, const MatrixType& B, const MatrixType& C)
+{
+ MatrixType U = MatrixType::Zero(A.rows(), A.rows());
+ for (int i = 0; i < A.rows(); i++) {
+ U(i, A.rows() - 1 - i) = static_cast<Scalar>(1);
+ }
+ MatrixType Aprime = U * A * U;
+
+ MatrixType Bprime = B;
+ MatrixType V = MatrixType::Identity(B.rows(), B.rows());
+
+ MatrixType Cprime = U * C * V;
+ MatrixType Xprime(A.rows(), B.rows());
+ for (int l = 0; l < B.rows(); l++) {
+ for (int k = 0; k < A.rows(); k++) {
+ Scalar tmp1, tmp2;
+ if (k == 0) {
+ tmp1 = 0;
+ } else {
+ Matrix<Scalar,1,1> tmp1matrix = Aprime.row(k).start(k) * Xprime.col(l).start(k);
+ tmp1 = tmp1matrix(0,0);
+ }
+ if (l == 0) {
+ tmp2 = 0;
+ } else {
+ Matrix<Scalar,1,1> tmp2matrix = Xprime.row(k).start(l) * Bprime.col(l).start(l);
+ tmp2 = tmp2matrix(0,0);
+ }
+ Xprime(k,l) = (Cprime(k,l) - tmp1 - tmp2) / (Aprime(k,k) + Bprime(l,l));
+ }
+ }
+ return U.adjoint() * Xprime * V.adjoint();
+}
+
+
+// does not touch irrelevant parts of T
+template <typename MatrixType>
+void MatrixFunction<MatrixType,1,1>::computeBlockAtomic(const MatrixType& T, MatrixType& result,
+ const IntVectorType& blockSize)
+{
+ int blockStart = 0;
+ result.resize(T.rows(), T.cols());
+ result.setZero();
+ for (int i = 0; i < blockSize.rows(); i++) {
+ result.block(blockStart, blockStart, blockSize(i), blockSize(i))
+ = computeAtomic(T.block(blockStart, blockStart, blockSize(i), blockSize(i)));
+ blockStart += blockSize(i);
+ }
+}
+
+template <typename Scalar>
+typename std::list<std::list<Scalar> >::iterator ei_find_in_list_of_lists(typename std::list<std::list<Scalar> >& ll, Scalar x)
+{
+ typename std::list<Scalar>::iterator j;
+ for (typename std::list<std::list<Scalar> >::iterator i = ll.begin(); i != ll.end(); i++) {
+ j = std::find(i->begin(), i->end(), x);
+ if (j != i->end())
+ return i;
+ }
+ return ll.end();
+}
+
+// Alg 4.1
+template <typename MatrixType>
+void MatrixFunction<MatrixType,1,1>::divideInBlocks(const VectorType& v, listOfLists* result)
+{
+ const int n = v.rows();
+ for (int i=0; i<n; i++) {
+ // Find set containing v(i), adding a new set if necessary
+ typename listOfLists::iterator qi = ei_find_in_list_of_lists(*result, v(i));
+ if (qi == result->end()) {
+ listOfScalars l;
+ l.push_back(v(i));
+ result->push_back(l);
+ qi = result->end();
+ qi--;
+ }
+ // Look for other element to add to the set
+ for (int j=i+1; j<n; j++) {
+ if (ei_abs(v(j) - v(i)) <= separation() && std::find(qi->begin(), qi->end(), v(j)) == qi->end()) {
+ typename listOfLists::iterator qj = ei_find_in_list_of_lists(*result, v(j));
+ if (qj == result->end()) {
+ qi->push_back(v(j));
+ } else {
+ qi->insert(qi->end(), qj->begin(), qj->end());
+ result->erase(qj);
+ }
+ }
+ }
+ }
+}
+
+// Construct permutation P, such that P(D) has eigenvalues clustered together
+template <typename MatrixType>
+void MatrixFunction<MatrixType,1,1>::constructPermutation(const VectorType& diag, const listOfLists& blocks,
+ IntVectorType& blockSize, IntVectorType& permutation)
+{
+ const int n = diag.rows();
+ const int numBlocks = blocks.size();
+
+ // For every block in blocks, mark and count the entries in diag that
+ // appear in that block
+ blockSize.setZero(numBlocks);
+ IntVectorType entryToBlock(n);
+ int blockIndex = 0;
+ for (typename listOfLists::const_iterator block = blocks.begin(); block != blocks.end(); block++) {
+ for (int i = 0; i < diag.rows(); i++) {
+ if (std::find(block->begin(), block->end(), diag(i)) != block->end()) {
+ blockSize[blockIndex]++;
+ entryToBlock[i] = blockIndex;
+ }
+ }
+ blockIndex++;
+ }
+
+ // Compute index of first entry in every block as the sum of sizes
+ // of all the preceding blocks
+ IntVectorType indexNextEntry(numBlocks);
+ indexNextEntry[0] = 0;
+ for (blockIndex = 1; blockIndex < numBlocks; blockIndex++) {
+ indexNextEntry[blockIndex] = indexNextEntry[blockIndex-1] + blockSize[blockIndex-1];
+ }
+
+ // Construct permutation
+ permutation.resize(n);
+ for (int i = 0; i < n; i++) {
+ int block = entryToBlock[i];
+ permutation[i] = indexNextEntry[block];
+ indexNextEntry[block]++;
+ }
+}
+
+template <typename MatrixType>
+MatrixType MatrixFunction<MatrixType,1,1>::computeAtomic(const MatrixType& T)
+{
+ // TODO: Use that T is upper triangular
+ const int n = T.rows();
+ const Scalar sigma = T.trace() / Scalar(n);
+ const MatrixType M = T - sigma * MatrixType::Identity(n, n);
+ const RealScalar mu = computeMu(M);
+ MatrixType F = m_f(sigma, 0) * MatrixType::Identity(n, n);
+ MatrixType P = M;
+ MatrixType Fincr;
+ for (int s = 1; s < 1.1*n + 10; s++) { // upper limit is fairly arbitrary
+ Fincr = m_f(sigma, s) * P;
+ F += Fincr;
+ P = (1/(s + 1.0)) * P * M;
+ if (taylorConverged(T, s, F, Fincr, P, mu)) {
+ return F;
+ }
+ }
+ ei_assert("Taylor series does not converge" && 0);
+ return F;
+}
+
+template <typename MatrixType>
+typename MatrixFunction<MatrixType,1,1>::RealScalar MatrixFunction<MatrixType,1,1>::computeMu(const MatrixType& M)
+{
+ const int n = M.rows();
+ const MatrixType N = MatrixType::Identity(n, n) - M;
+ VectorType e = VectorType::Ones(n);
+ N.template triangularView<UpperTriangular>().solveInPlace(e);
+ return e.cwise().abs().maxCoeff();
+}
+
+template <typename MatrixType>
+bool MatrixFunction<MatrixType,1,1>::taylorConverged(const MatrixType& T, int s, const MatrixType& F,
+ const MatrixType& Fincr, const MatrixType& P, RealScalar mu)
+{
+ const int n = F.rows();
+ const RealScalar F_norm = F.cwise().abs().rowwise().sum().maxCoeff();
+ const RealScalar Fincr_norm = Fincr.cwise().abs().rowwise().sum().maxCoeff();
+ if (Fincr_norm < epsilon<Scalar>() * F_norm) {
+ RealScalar delta = 0;
+ RealScalar rfactorial = 1;
+ for (int r = 0; r < n; r++) {
+ RealScalar mx = 0;
+ for (int i = 0; i < n; i++)
+ mx = std::max(mx, std::abs(m_f(T(i, i), s+r)));
+ if (r != 0)
+ rfactorial *= r;
+ delta = std::max(delta, mx / rfactorial);
+ }
+ const RealScalar P_norm = P.cwise().abs().rowwise().sum().maxCoeff();
+ if (mu * delta * P_norm < epsilon<Scalar>() * F_norm)
+ return true;
+ }
+ return false;
+}
+
+template <typename Derived>
+EIGEN_STRONG_INLINE void ei_matrix_function(const MatrixBase<Derived>& M,
+ typename ei_stem_function<typename ei_traits<Derived>::Scalar>::type f,
+ typename MatrixBase<Derived>::PlainMatrixType* result)
+{
+ ei_assert(M.rows() == M.cols());
+ MatrixFunction<typename MatrixBase<Derived>::PlainMatrixType>(M, f, result);
+}
+
+#endif // EIGEN_MATRIX_FUNCTION
diff --git a/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h b/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h
index e944f0e1b..bcf1016db 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h
@@ -29,6 +29,7 @@
#define EIGEN_HYBRIDNONLINEARSOLVER_H
/**
+ * \ingroup NonLinearOptimization_Module
* \brief Finds a zero of a system of n
* nonlinear functions in n variables by a modification of the Powell
* hybrid method ("dogleg").
@@ -71,50 +72,49 @@ public:
int nb_of_superdiagonals;
Scalar epsfcn;
};
+ typedef Matrix< Scalar, Dynamic, 1 > FVectorType;
+ typedef Matrix< Scalar, Dynamic, Dynamic > JacobianType;
Status hybrj1(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const Scalar tol = ei_sqrt(epsilon<Scalar>())
);
Status solveInit(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode=1
);
Status solveOneStep(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode=1
);
Status solve(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode=1
);
Status hybrd1(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const Scalar tol = ei_sqrt(epsilon<Scalar>())
);
Status solveNumericalDiffInit(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode=1
);
Status solveNumericalDiffOneStep(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode=1
);
Status solveNumericalDiff(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode=1
);
void resetParameters(void) { parameters = Parameters(); }
Parameters parameters;
- Matrix< Scalar, Dynamic, 1 > fvec;
- Matrix< Scalar, Dynamic, Dynamic > fjac;
- Matrix< Scalar, Dynamic, 1 > R;
- Matrix< Scalar, Dynamic, 1 > qtf;
- Matrix< Scalar, Dynamic, 1 > diag;
+ FVectorType fvec, R, qtf, diag;
+ JacobianType fjac;
int nfev;
int njev;
int iter;
@@ -133,7 +133,7 @@ private:
int nslow1, nslow2;
int ncfail;
Scalar actred, prered;
- Matrix< Scalar, Dynamic, 1 > wa1, wa2, wa3, wa4;
+ FVectorType wa1, wa2, wa3, wa4;
};
@@ -141,7 +141,7 @@ private:
template<typename FunctorType, typename Scalar>
typename HybridNonLinearSolver<FunctorType,Scalar>::Status
HybridNonLinearSolver<FunctorType,Scalar>::hybrj1(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const Scalar tol
)
{
@@ -164,7 +164,7 @@ HybridNonLinearSolver<FunctorType,Scalar>::hybrj1(
template<typename FunctorType, typename Scalar>
typename HybridNonLinearSolver<FunctorType,Scalar>::Status
HybridNonLinearSolver<FunctorType,Scalar>::solveInit(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode
)
{
@@ -214,7 +214,7 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveInit(
template<typename FunctorType, typename Scalar>
typename HybridNonLinearSolver<FunctorType,Scalar>::Status
HybridNonLinearSolver<FunctorType,Scalar>::solveOneStep(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode
)
{
@@ -227,15 +227,11 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveOneStep(
return UserAksed;
++njev;
- /* compute the qr factorization of the jacobian. */
-
- ei_qrfac<Scalar>(n, n, fjac.data(), fjac.rows(), false, iwa, wa1.data(), wa2.data());
-
+ wa2 = fjac.colwise().blueNorm();
+ /* on the first iteration and if mode is 1, scale according */
+ /* to the norms of the columns of the initial jacobian. */
if (iter == 1) {
-
- /* on the first iteration and if mode is 1, scale according */
- /* to the norms of the columns of the initial jacobian. */
if (mode != 2)
for (j = 0; j < n; ++j) {
diag[j] = wa2[j];
@@ -252,6 +248,9 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveOneStep(
delta = parameters.factor;
}
+ /* compute the qr factorization of the jacobian. */
+ ei_qrfac<Scalar>(n, n, fjac.data(), fjac.rows(), false, iwa, wa1.data());
+
/* form (q transpose)*fvec and store in qtf. */
qtf = fvec;
@@ -270,18 +269,16 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveOneStep(
sing = false;
for (j = 0; j < n; ++j) {
l = j;
- if (j)
- for (i = 0; i < j; ++i) {
- R[l] = fjac(i,j);
- l = l + n - i -1;
- }
+ for (i = 0; i < j; ++i) {
+ R[l] = fjac(i,j);
+ l = l + n - i -1;
+ }
R[l] = wa1[j];
if (wa1[j] == 0.)
sing = true;
}
/* accumulate the orthogonal factor in fjac. */
-
ei_qform<Scalar>(n, n, fjac.data(), fjac.rows(), wa1.data());
/* rescale if necessary. */
@@ -435,7 +432,7 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveOneStep(
template<typename FunctorType, typename Scalar>
typename HybridNonLinearSolver<FunctorType,Scalar>::Status
HybridNonLinearSolver<FunctorType,Scalar>::solve(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode
)
{
@@ -450,7 +447,7 @@ HybridNonLinearSolver<FunctorType,Scalar>::solve(
template<typename FunctorType, typename Scalar>
typename HybridNonLinearSolver<FunctorType,Scalar>::Status
HybridNonLinearSolver<FunctorType,Scalar>::hybrd1(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const Scalar tol
)
{
@@ -474,7 +471,7 @@ HybridNonLinearSolver<FunctorType,Scalar>::hybrd1(
template<typename FunctorType, typename Scalar>
typename HybridNonLinearSolver<FunctorType,Scalar>::Status
HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffInit(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode
)
{
@@ -529,7 +526,7 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffInit(
template<typename FunctorType, typename Scalar>
typename HybridNonLinearSolver<FunctorType,Scalar>::Status
HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffOneStep(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode
)
{
@@ -544,13 +541,10 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffOneStep(
return UserAksed;
nfev += std::min(parameters.nb_of_subdiagonals+parameters.nb_of_superdiagonals+ 1, n);
- /* compute the qr factorization of the jacobian. */
-
- ei_qrfac<Scalar>(n, n, fjac.data(), fjac.rows(), false, iwa, wa1.data(), wa2.data());
+ wa2 = fjac.colwise().blueNorm();
/* on the first iteration and if mode is 1, scale according */
/* to the norms of the columns of the initial jacobian. */
-
if (iter == 1) {
if (mode != 2)
for (j = 0; j < n; ++j) {
@@ -561,7 +555,6 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffOneStep(
/* on the first iteration, calculate the norm of the scaled x */
/* and initialize the step bound delta. */
-
wa3 = diag.cwise() * x;
xnorm = wa3.stableNorm();
delta = parameters.factor * xnorm;
@@ -569,6 +562,9 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffOneStep(
delta = parameters.factor;
}
+ /* compute the qr factorization of the jacobian. */
+ ei_qrfac<Scalar>(n, n, fjac.data(), fjac.rows(), false, iwa, wa1.data());
+
/* form (q transpose)*fvec and store in qtf. */
qtf = fvec;
@@ -587,18 +583,16 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffOneStep(
sing = false;
for (j = 0; j < n; ++j) {
l = j;
- if (j)
- for (i = 0; i < j; ++i) {
- R[l] = fjac(i,j);
- l = l + n - i -1;
- }
+ for (i = 0; i < j; ++i) {
+ R[l] = fjac(i,j);
+ l = l + n - i -1;
+ }
R[l] = wa1[j];
if (wa1[j] == 0.)
sing = true;
}
/* accumulate the orthogonal factor in fjac. */
-
ei_qform<Scalar>(n, n, fjac.data(), fjac.rows(), wa1.data());
/* rescale if necessary. */
@@ -752,7 +746,7 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffOneStep(
template<typename FunctorType, typename Scalar>
typename HybridNonLinearSolver<FunctorType,Scalar>::Status
HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiff(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode
)
{
diff --git a/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h b/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
index 9e982a078..2cf96eb14 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
@@ -29,6 +29,7 @@
#define EIGEN_LEVENBERGMARQUARDT__H
/**
+ * \ingroup NonLinearOptimization_Module
* \brief Performs non linear optimization over a non-linear function,
* using a variant of the Levenberg Marquardt algorithm.
*
@@ -72,56 +73,58 @@ public:
Scalar epsfcn;
};
+ typedef Matrix< Scalar, Dynamic, 1 > FVectorType;
+ typedef Matrix< Scalar, Dynamic, Dynamic > JacobianType;
+
Status lmder1(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const Scalar tol = ei_sqrt(epsilon<Scalar>())
);
Status minimize(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode=1
);
Status minimizeInit(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode=1
);
Status minimizeOneStep(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode=1
);
static Status lmdif1(
FunctorType &functor,
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
int *nfev,
const Scalar tol = ei_sqrt(epsilon<Scalar>())
);
Status lmstr1(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const Scalar tol = ei_sqrt(epsilon<Scalar>())
);
Status minimizeOptimumStorage(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode=1
);
Status minimizeOptimumStorageInit(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode=1
);
Status minimizeOptimumStorageOneStep(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode=1
);
void resetParameters(void) { parameters = Parameters(); }
+
Parameters parameters;
- Matrix< Scalar, Dynamic, 1 > fvec;
- Matrix< Scalar, Dynamic, Dynamic > fjac;
+ FVectorType fvec, qtf, diag;
+ JacobianType fjac;
VectorXi ipvt;
- Matrix< Scalar, Dynamic, 1 > qtf;
- Matrix< Scalar, Dynamic, 1 > diag;
int nfev;
int njev;
int iter;
@@ -130,7 +133,7 @@ private:
FunctorType &functor;
int n;
int m;
- Matrix< Scalar, Dynamic, 1 > wa1, wa2, wa3, wa4;
+ FVectorType wa1, wa2, wa3, wa4;
Scalar par, sum;
Scalar temp, temp1, temp2;
@@ -142,7 +145,7 @@ private:
template<typename FunctorType, typename Scalar>
typename LevenbergMarquardt<FunctorType,Scalar>::Status
LevenbergMarquardt<FunctorType,Scalar>::lmder1(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const Scalar tol
)
{
@@ -165,7 +168,7 @@ LevenbergMarquardt<FunctorType,Scalar>::lmder1(
template<typename FunctorType, typename Scalar>
typename LevenbergMarquardt<FunctorType,Scalar>::Status
LevenbergMarquardt<FunctorType,Scalar>::minimize(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode
)
{
@@ -178,7 +181,7 @@ LevenbergMarquardt<FunctorType,Scalar>::minimize(
template<typename FunctorType, typename Scalar>
typename LevenbergMarquardt<FunctorType,Scalar>::Status
LevenbergMarquardt<FunctorType,Scalar>::minimizeInit(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode
)
{
@@ -228,7 +231,7 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeInit(
template<typename FunctorType, typename Scalar>
typename LevenbergMarquardt<FunctorType,Scalar>::Status
LevenbergMarquardt<FunctorType,Scalar>::minimizeOneStep(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode
)
{
@@ -246,8 +249,9 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeOneStep(
/* compute the qr factorization of the jacobian. */
- ei_qrfac<Scalar>(m, n, fjac.data(), fjac.rows(), true, ipvt.data(), wa1.data(), wa2.data());
- ipvt.cwise()-=1; // qrfac() creates ipvt with fortran convetion (1->n), convert it to c (0->n-1)
+ wa2 = fjac.colwise().blueNorm();
+ ei_qrfac<Scalar>(m, n, fjac.data(), fjac.rows(), true, ipvt.data(), wa1.data());
+ ipvt.cwise()-=1; // qrfac() creates ipvt with fortran convention (1->n), convert it to c (0->n-1)
/* on the first iteration and if mode is 1, scale according */
/* to the norms of the columns of the initial jacobian. */
@@ -317,7 +321,7 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeOneStep(
/* determine the levenberg-marquardt parameter. */
- ei_lmpar<Scalar>(fjac, ipvt, diag, qtf, delta, par, wa1, wa2);
+ ei_lmpar<Scalar>(fjac, ipvt, diag, qtf, delta, par, wa1);
/* store the direction p and x + p. calculate the norm of p. */
@@ -424,14 +428,12 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeOneStep(
template<typename FunctorType, typename Scalar>
typename LevenbergMarquardt<FunctorType,Scalar>::Status
LevenbergMarquardt<FunctorType,Scalar>::lmstr1(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const Scalar tol
)
{
n = x.size();
m = functor.values();
- Matrix< Scalar, Dynamic, Dynamic > fjac(m, n);
- VectorXi ipvt;
/* check the input parameters for errors. */
if (n <= 0 || m < n || tol < 0.)
@@ -448,7 +450,7 @@ LevenbergMarquardt<FunctorType,Scalar>::lmstr1(
template<typename FunctorType, typename Scalar>
typename LevenbergMarquardt<FunctorType,Scalar>::Status
LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageInit(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode
)
{
@@ -499,7 +501,7 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageInit(
template<typename FunctorType, typename Scalar>
typename LevenbergMarquardt<FunctorType,Scalar>::Status
LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageOneStep(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode
)
{
@@ -535,8 +537,9 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageOneStep(
}
if (sing) {
ipvt.cwise()+=1;
- ei_qrfac<Scalar>(n, n, fjac.data(), fjac.rows(), true, ipvt.data(), wa1.data(), wa2.data());
- ipvt.cwise()-=1; // qrfac() creates ipvt with fortran convetion (1->n), convert it to c (0->n-1)
+ wa2 = fjac.colwise().blueNorm();
+ ei_qrfac<Scalar>(n, n, fjac.data(), fjac.rows(), true, ipvt.data(), wa1.data());
+ ipvt.cwise()-=1; // qrfac() creates ipvt with fortran convention (1->n), convert it to c (0->n-1)
for (j = 0; j < n; ++j) {
if (fjac(j,j) != 0.) {
sum = 0.;
@@ -601,7 +604,7 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageOneStep(
/* determine the levenberg-marquardt parameter. */
- ei_lmpar<Scalar>(fjac, ipvt, diag, qtf, delta, par, wa1, wa2);
+ ei_lmpar<Scalar>(fjac, ipvt, diag, qtf, delta, par, wa1);
/* store the direction p and x + p. calculate the norm of p. */
@@ -708,7 +711,7 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageOneStep(
template<typename FunctorType, typename Scalar>
typename LevenbergMarquardt<FunctorType,Scalar>::Status
LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorage(
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
const int mode
)
{
@@ -722,7 +725,7 @@ template<typename FunctorType, typename Scalar>
typename LevenbergMarquardt<FunctorType,Scalar>::Status
LevenbergMarquardt<FunctorType,Scalar>::lmdif1(
FunctorType &functor,
- Matrix< Scalar, Dynamic, 1 > &x,
+ FVectorType &x,
int *nfev,
const Scalar tol
)
diff --git a/unsupported/Eigen/src/NonLinearOptimization/lmpar.h b/unsupported/Eigen/src/NonLinearOptimization/lmpar.h
index c62881c81..b723a7e0a 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/lmpar.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/lmpar.h
@@ -7,16 +7,14 @@ void ei_lmpar(
const Matrix< Scalar, Dynamic, 1 > &qtb,
Scalar delta,
Scalar &par,
- Matrix< Scalar, Dynamic, 1 > &x,
- Matrix< Scalar, Dynamic, 1 > &sdiag)
+ Matrix< Scalar, Dynamic, 1 > &x)
{
/* Local variables */
- int i, j, k, l;
+ int i, j, l;
Scalar fp;
- Scalar sum, parc, parl;
+ Scalar parc, parl;
int iter;
Scalar temp, paru;
- int nsing;
Scalar gnorm;
Scalar dxnorm;
@@ -28,31 +26,28 @@ void ei_lmpar(
assert(n==qtb.size());
assert(n==x.size());
- Matrix< Scalar, Dynamic, 1 > wa1(n), wa2(n);
+ Matrix< Scalar, Dynamic, 1 > wa1, wa2;
/* compute and store in x the gauss-newton direction. if the */
/* jacobian is rank-deficient, obtain a least squares solution. */
- nsing = n-1;
+ int nsing = n-1;
+ wa1 = qtb;
for (j = 0; j < n; ++j) {
- wa1[j] = qtb[j];
if (r(j,j) == 0. && nsing == n-1)
nsing = j - 1;
if (nsing < n-1)
wa1[j] = 0.;
}
- for (k = 0; k <= nsing; ++k) {
- j = nsing - k;
+ for (j = nsing; j>=0; --j) {
wa1[j] /= r(j,j);
temp = wa1[j];
for (i = 0; i < j ; ++i)
wa1[i] -= r(i,j) * temp;
}
- for (j = 0; j < n; ++j) {
- l = ipvt[j];
- x[l] = wa1[j];
- }
+ for (j = 0; j < n; ++j)
+ x[ipvt[j]] = wa1[j];
/* initialize the iteration counter. */
/* evaluate the function at the origin, and test */
@@ -77,8 +72,10 @@ void ei_lmpar(
l = ipvt[j];
wa1[j] = diag[l] * (wa2[l] / dxnorm);
}
+ // it's actually a triangularView.solveInplace(), though in a weird
+ // way:
for (j = 0; j < n; ++j) {
- sum = 0.;
+ Scalar sum = 0.;
for (i = 0; i < j; ++i)
sum += r(i,j) * wa1[i];
wa1[j] = (wa1[j] - sum) / r(j,j);
@@ -89,13 +86,9 @@ void ei_lmpar(
/* calculate an upper bound, paru, for the zero of the function. */
- for (j = 0; j < n; ++j) {
- sum = 0.;
- for (i = 0; i <= j; ++i)
- sum += r(i,j) * qtb[i];
- l = ipvt[j];
- wa1[j] = sum / diag[l];
- }
+ for (j = 0; j < n; ++j)
+ wa1[j] = r.col(j).start(j+1).dot(qtb.start(j+1)) / diag[ipvt[j]];
+
gnorm = wa1.stableNorm();
paru = gnorm / delta;
if (paru == 0.)
@@ -119,12 +112,10 @@ void ei_lmpar(
if (par == 0.)
par = std::max(dwarf,Scalar(.001) * paru); /* Computing MAX */
- temp = ei_sqrt(par);
- wa1 = temp * diag;
+ wa1 = ei_sqrt(par)* diag;
- ipvt.cwise()+=1; // qrsolv() expects the fortran convention (as qrfac provides)
- ei_qrsolv<Scalar>(n, r.data(), r.rows(), ipvt.data(), wa1.data(), qtb.data(), x.data(), sdiag.data(), wa2.data());
- ipvt.cwise()-=1;
+ Matrix< Scalar, Dynamic, 1 > sdiag(n);
+ ei_qrsolv<Scalar>(r, ipvt, wa1, qtb, x, sdiag);
wa2 = diag.cwise() * x;
dxnorm = wa2.blueNorm();
@@ -143,7 +134,6 @@ void ei_lmpar(
for (j = 0; j < n; ++j) {
l = ipvt[j];
wa1[j] = diag[l] * (wa2[l] / dxnorm);
- /* L180: */
}
for (j = 0; j < n; ++j) {
wa1[j] /= sdiag[j];
diff --git a/unsupported/Eigen/src/NonLinearOptimization/qrfac.h b/unsupported/Eigen/src/NonLinearOptimization/qrfac.h
index 481fe57d8..0c1ecf394 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/qrfac.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/qrfac.h
@@ -1,8 +1,7 @@
template <typename Scalar>
void ei_qrfac(int m, int n, Scalar *a, int
- lda, int pivot, int *ipvt, Scalar *rdiag,
- Scalar *acnorm)
+ lda, int pivot, int *ipvt, Scalar *rdiag)
{
/* System generated locals */
int a_dim1, a_offset;
@@ -18,7 +17,6 @@ void ei_qrfac(int m, int n, Scalar *a, int
Matrix< Scalar, Dynamic, 1 > wa(n+1);
/* Parameter adjustments */
- --acnorm;
--rdiag;
a_dim1 = lda;
a_offset = 1 + a_dim1 * 1;
@@ -31,13 +29,10 @@ void ei_qrfac(int m, int n, Scalar *a, int
/* compute the initial column norms and initialize several arrays. */
for (j = 1; j <= n; ++j) {
- acnorm[j] = Map< Matrix< Scalar, Dynamic, 1 > >(&a[j * a_dim1 + 1],m).blueNorm();
- rdiag[j] = acnorm[j];
+ rdiag[j] = Map< Matrix< Scalar, Dynamic, 1 > >(&a[j * a_dim1 + 1],m).blueNorm();
wa[j] = rdiag[j];
- if (pivot) {
+ if (pivot)
ipvt[j] = j;
- }
- /* L10: */
}
/* reduce a to r with householder transformations. */
diff --git a/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h b/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
index 57884870c..1ee21d5ed 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
@@ -1,166 +1,92 @@
- template <typename Scalar>
-void ei_qrsolv(int n, Scalar *r__, int ldr,
- const int *ipvt, const Scalar *diag, const Scalar *qtb, Scalar *x,
- Scalar *sdiag, Scalar *wa)
-{
- /* System generated locals */
- int r_dim1, r_offset;
+template <typename Scalar>
+void ei_qrsolv(
+ Matrix< Scalar, Dynamic, Dynamic > &r,
+ VectorXi &ipvt, // TODO : const once ipvt mess fixed
+ const Matrix< Scalar, Dynamic, 1 > &diag,
+ const Matrix< Scalar, Dynamic, 1 > &qtb,
+ Matrix< Scalar, Dynamic, 1 > &x,
+ Matrix< Scalar, Dynamic, 1 > &sdiag)
+{
/* Local variables */
- int i, j, k, l, jp1, kp1;
- Scalar tan__, cos__, sin__, sum, temp, cotan;
- int nsing;
- Scalar qtbpj;
-
- /* Parameter adjustments */
- --wa;
- --sdiag;
- --x;
- --qtb;
- --diag;
- --ipvt;
- r_dim1 = ldr;
- r_offset = 1 + r_dim1 * 1;
- r__ -= r_offset;
+ int i, j, k, l;
+ Scalar sum, temp;
+ int n = r.cols();
+ Matrix< Scalar, Dynamic, 1 > wa(n);
/* Function Body */
/* copy r and (q transpose)*b to preserve input and initialize s. */
/* in particular, save the diagonal elements of r in x. */
- for (j = 1; j <= n; ++j) {
- for (i = j; i <= n; ++i) {
- r__[i + j * r_dim1] = r__[j + i * r_dim1];
- /* L10: */
- }
- x[j] = r__[j + j * r_dim1];
- wa[j] = qtb[j];
- /* L20: */
- }
+ x = r.diagonal();
+ wa = qtb;
- /* eliminate the diagonal matrix d using a givens rotation. */
+ for (j = 0; j < n; ++j)
+ for (i = j+1; i < n; ++i)
+ r(i,j) = r(j,i);
- for (j = 1; j <= n; ++j) {
+ /* eliminate the diagonal matrix d using a givens rotation. */
+ for (j = 0; j < n; ++j) {
/* prepare the row of d to be eliminated, locating the */
/* diagonal element using p from the qr factorization. */
l = ipvt[j];
- if (diag[l] == 0.) {
- goto L90;
- }
- for (k = j; k <= n; ++k) {
- sdiag[k] = 0.;
- /* L30: */
- }
+ if (diag[l] == 0.)
+ break;
+ sdiag.segment(j,n-j).setZero();
sdiag[j] = diag[l];
/* the transformations to eliminate the row of d */
/* modify only a single element of (q transpose)*b */
/* beyond the first n, which is initially zero. */
- qtbpj = 0.;
- for (k = j; k <= n; ++k) {
-
+ Scalar qtbpj = 0.;
+ for (k = j; k < n; ++k) {
/* determine a givens rotation which eliminates the */
/* appropriate element in the current row of d. */
-
- if (sdiag[k] == 0.)
- goto L70;
- if ( ei_abs(r__[k + k * r_dim1]) >= ei_abs(sdiag[k]))
- goto L40;
- cotan = r__[k + k * r_dim1] / sdiag[k];
- /* Computing 2nd power */
- sin__ = Scalar(.5) / ei_sqrt(Scalar(0.25) + Scalar(0.25) * ei_abs2(cotan));
- cos__ = sin__ * cotan;
- goto L50;
-L40:
- tan__ = sdiag[k] / r__[k + k * r_dim1];
- /* Computing 2nd power */
- cos__ = Scalar(.5) / ei_sqrt(Scalar(0.25) + Scalar(0.25) * ei_abs2(tan__));
- sin__ = cos__ * tan__;
-L50:
+ PlanarRotation<Scalar> givens;
+ givens.makeGivens(-r(k,k), sdiag[k]);
/* compute the modified diagonal element of r and */
/* the modified element of ((q transpose)*b,0). */
- r__[k + k * r_dim1] = cos__ * r__[k + k * r_dim1] + sin__ * sdiag[
- k];
- temp = cos__ * wa[k] + sin__ * qtbpj;
- qtbpj = -sin__ * wa[k] + cos__ * qtbpj;
+ r(k,k) = givens.c() * r(k,k) + givens.s() * sdiag[k];
+ temp = givens.c() * wa[k] + givens.s() * qtbpj;
+ qtbpj = -givens.s() * wa[k] + givens.c() * qtbpj;
wa[k] = temp;
/* accumulate the tranformation in the row of s. */
-
- kp1 = k + 1;
- if (n < kp1) {
- goto L70;
+ for (i = k+1; i<n; ++i) {
+ temp = givens.c() * r(i,k) + givens.s() * sdiag[i];
+ sdiag[i] = -givens.s() * r(i,k) + givens.c() * sdiag[i];
+ r(i,k) = temp;
}
- for (i = kp1; i <= n; ++i) {
- temp = cos__ * r__[i + k * r_dim1] + sin__ * sdiag[i];
- sdiag[i] = -sin__ * r__[i + k * r_dim1] + cos__ * sdiag[
- i];
- r__[i + k * r_dim1] = temp;
- /* L60: */
- }
-L70:
- /* L80: */
- ;
}
-L90:
-
- /* store the diagonal element of s and restore */
- /* the corresponding diagonal element of r. */
-
- sdiag[j] = r__[j + j * r_dim1];
- r__[j + j * r_dim1] = x[j];
- /* L100: */
}
+ // restore
+ sdiag = r.diagonal();
+ r.diagonal() = x;
+
/* solve the triangular system for z. if the system is */
/* singular, then obtain a least squares solution. */
- nsing = n;
- for (j = 1; j <= n; ++j) {
- if (sdiag[j] == 0. && nsing == n) {
- nsing = j - 1;
- }
- if (nsing < n) {
- wa[j] = 0.;
- }
- /* L110: */
- }
- if (nsing < 1) {
- goto L150;
- }
- for (k = 1; k <= nsing; ++k) {
- j = nsing - k + 1;
+ int nsing;
+ for (nsing=0; nsing<n && sdiag[nsing]!=0; nsing++);
+ wa.segment(nsing,n-nsing).setZero();
+ nsing--; // nsing is the last nonsingular index
+
+ for (j = nsing; j>=0; j--) {
sum = 0.;
- jp1 = j + 1;
- if (nsing < jp1) {
- goto L130;
- }
- for (i = jp1; i <= nsing; ++i) {
- sum += r__[i + j * r_dim1] * wa[i];
- /* L120: */
- }
-L130:
+ for (i = j+1; i <= nsing; ++i)
+ sum += r(i,j) * wa[i];
wa[j] = (wa[j] - sum) / sdiag[j];
- /* L140: */
}
-L150:
/* permute the components of z back to components of x. */
-
- for (j = 1; j <= n; ++j) {
- l = ipvt[j];
- x[l] = wa[j];
- /* L160: */
- }
- return;
-
- /* last card of subroutine qrsolv. */
-
-} /* qrsolv_ */
+ for (j = 0; j < n; ++j) x[ipvt[j]] = wa[j];
+}
diff --git a/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h b/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h
index ef91da2da..70a6d30c3 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h
@@ -8,7 +8,7 @@ void ei_r1mpyq(int m, int n, Scalar *a, int
/* Local variables */
int i, j, nm1, nmj;
- Scalar cos__, sin__, temp;
+ Scalar cos__=0., sin__=0., temp;
/* Parameter adjustments */
--w;
@@ -18,28 +18,18 @@ void ei_r1mpyq(int m, int n, Scalar *a, int
a -= a_offset;
/* Function Body */
-
- /* apply the first set of givens rotations to a. */
-
nm1 = n - 1;
- if (nm1 < 1) {
- /* goto L50; */
+ if (nm1 < 1)
return;
- }
+
+ /* apply the first set of givens rotations to a. */
for (nmj = 1; nmj <= nm1; ++nmj) {
j = n - nmj;
if (ei_abs(v[j]) > 1.) {
cos__ = 1. / v[j];
- }
- if (ei_abs(v[j]) > 1.) {
- /* Computing 2nd power */
sin__ = ei_sqrt(1. - ei_abs2(cos__));
- }
- if (ei_abs(v[j]) <= 1.) {
+ } else {
sin__ = v[j];
- }
- if (ei_abs(v[j]) <= 1.) {
- /* Computing 2nd power */
cos__ = ei_sqrt(1. - ei_abs2(sin__));
}
for (i = 1; i <= m; ++i) {
@@ -47,26 +37,15 @@ void ei_r1mpyq(int m, int n, Scalar *a, int
a[i + n * a_dim1] = sin__ * a[i + j * a_dim1] + cos__ * a[
i + n * a_dim1];
a[i + j * a_dim1] = temp;
- /* L10: */
}
- /* L20: */
}
-
/* apply the second set of givens rotations to a. */
-
for (j = 1; j <= nm1; ++j) {
if (ei_abs(w[j]) > 1.) {
cos__ = 1. / w[j];
- }
- if (ei_abs(w[j]) > 1.) {
- /* Computing 2nd power */
sin__ = ei_sqrt(1. - ei_abs2(cos__));
- }
- if (ei_abs(w[j]) <= 1.) {
+ } else {
sin__ = w[j];
- }
- if (ei_abs(w[j]) <= 1.) {
- /* Computing 2nd power */
cos__ = ei_sqrt(1. - ei_abs2(sin__));
}
for (i = 1; i <= m; ++i) {
@@ -74,14 +53,8 @@ void ei_r1mpyq(int m, int n, Scalar *a, int
a[i + n * a_dim1] = -sin__ * a[i + j * a_dim1] + cos__ * a[
i + n * a_dim1];
a[i + j * a_dim1] = temp;
- /* L30: */
}
- /* L40: */
}
- /* L50: */
return;
-
- /* last card of subroutine r1mpyq. */
-
} /* r1mpyq_ */
diff --git a/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h b/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h
index 98872e0bc..db6f791df 100644
--- a/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h
+++ b/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h
@@ -45,10 +45,11 @@ enum NumericalDiffMode {
*
* Currently only "Forward" and "Central" scheme are implemented.
*/
-template<typename Functor, NumericalDiffMode mode=Forward>
-class NumericalDiff : public Functor
+template<typename _Functor, NumericalDiffMode mode=Forward>
+class NumericalDiff : public _Functor
{
public:
+ typedef _Functor Functor;
typedef typename Functor::Scalar Scalar;
typedef typename Functor::InputType InputType;
typedef typename Functor::ValueType ValueType;
diff --git a/unsupported/Eigen/src/Skyline/SkylineInplaceLU.h b/unsupported/Eigen/src/Skyline/SkylineInplaceLU.h
index feed564c5..c8c5f7575 100644
--- a/unsupported/Eigen/src/Skyline/SkylineInplaceLU.h
+++ b/unsupported/Eigen/src/Skyline/SkylineInplaceLU.h
@@ -46,7 +46,7 @@ public:
* flags \a flags. */
SkylineInplaceLU(MatrixType& matrix, int flags = 0)
: /*m_matrix(matrix.rows(), matrix.cols()),*/ m_flags(flags), m_status(0), m_lu(matrix) {
- m_precision = RealScalar(0.1) * Eigen::precision<RealScalar > ();
+ m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar > ();
m_lu.IsRowMajor ? computeRowMajor() : compute();
}
diff --git a/unsupported/Eigen/src/Skyline/SkylineMatrix.h b/unsupported/Eigen/src/Skyline/SkylineMatrix.h
index 5d47d970f..6dd4f1736 100644
--- a/unsupported/Eigen/src/Skyline/SkylineMatrix.h
+++ b/unsupported/Eigen/src/Skyline/SkylineMatrix.h
@@ -589,7 +589,7 @@ public:
m_data.squeeze();
}
- void prune(Scalar reference, RealScalar epsilon = precision<RealScalar > ()) {
+ void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar > ()) {
//TODO
}
diff --git a/unsupported/Eigen/src/Skyline/SkylineStorage.h b/unsupported/Eigen/src/Skyline/SkylineStorage.h
index f725da0bf..641508f75 100644
--- a/unsupported/Eigen/src/Skyline/SkylineStorage.h
+++ b/unsupported/Eigen/src/Skyline/SkylineStorage.h
@@ -206,7 +206,7 @@ public:
memset(m_lowerProfile, 0, m_diagSize * sizeof (int));
}
- void prune(Scalar reference, RealScalar epsilon = precision<RealScalar>()) {
+ void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar>()) {
//TODO
}
diff --git a/unsupported/README.txt b/unsupported/README.txt
index ed1341426..83479ff0b 100644
--- a/unsupported/README.txt
+++ b/unsupported/README.txt
@@ -4,7 +4,7 @@ most of them are subject to be included in Eigen in the future.
In order to use an unsupported module you have to do either:
- - add the path_to_eigen2/unsupported directory to your include path and do:
+ - add the path_to_eigen/unsupported directory to your include path and do:
#include <Eigen/ModuleHeader>
- or directly do:
diff --git a/unsupported/doc/CMakeLists.txt b/unsupported/doc/CMakeLists.txt
index 2cff2510f..9e9ab9800 100644
--- a/unsupported/doc/CMakeLists.txt
+++ b/unsupported/doc/CMakeLists.txt
@@ -1,6 +1,4 @@
-
set_directory_properties(PROPERTIES EXCLUDE_FROM_ALL TRUE)
-if(NOT MSVC)
- add_subdirectory(examples)
-endif(NOT MSVC)
+add_subdirectory(examples)
+add_subdirectory(snippets)
diff --git a/unsupported/doc/Doxyfile.in b/unsupported/doc/Doxyfile.in
index 269595820..12f2f39eb 100644
--- a/unsupported/doc/Doxyfile.in
+++ b/unsupported/doc/Doxyfile.in
@@ -1,11 +1,3 @@
-################################################################################
-## ##
-## WARNING ##
-## ##
-## all modifications in this file must be reported in eigen2/Mainpage.dox ##
-## ##
-################################################################################
-
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project
#
@@ -609,7 +601,8 @@ EXCLUDE_PATTERNS = CMake* \
*.txt \
*.sh \
*.diff \
- diff
+ *.orig \
+ diff \
*~
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
diff --git a/unsupported/doc/examples/BVH_Example.cpp b/unsupported/doc/examples/BVH_Example.cpp
index 890eb535b..0fbab5fdb 100644
--- a/unsupported/doc/examples/BVH_Example.cpp
+++ b/unsupported/doc/examples/BVH_Example.cpp
@@ -1,3 +1,4 @@
+#include <Eigen/StdVector>
#include <unsupported/Eigen/BVH>
using namespace Eigen;
@@ -20,7 +21,8 @@ struct PointPointMinimizer //how to compute squared distances between points and
int main()
{
- std::vector<Vector2d> redPoints, bluePoints;
+ typedef std::vector<Vector2d, aligned_allocator<Vector2d> > StdVectorOfVector2d;
+ StdVectorOfVector2d redPoints, bluePoints;
for(int i = 0; i < 100; ++i) { //initialize random set of red points and blue points
redPoints.push_back(Vector2d::Random());
bluePoints.push_back(Vector2d::Random());
diff --git a/unsupported/doc/examples/CMakeLists.txt b/unsupported/doc/examples/CMakeLists.txt
index af4de4b0d..cb42b2ab9 100644
--- a/unsupported/doc/examples/CMakeLists.txt
+++ b/unsupported/doc/examples/CMakeLists.txt
@@ -4,14 +4,14 @@ ADD_CUSTOM_TARGET(unsupported_examples)
FOREACH(example_src ${examples_SRCS})
GET_FILENAME_COMPONENT(example ${example_src} NAME_WE)
-ADD_EXECUTABLE(${example} ${example_src})
+ADD_EXECUTABLE(example_${example} ${example_src})
GET_TARGET_PROPERTY(example_executable
- ${example} LOCATION)
+ example_${example} LOCATION)
ADD_CUSTOM_COMMAND(
- TARGET ${example}
+ TARGET example_${example}
POST_BUILD
COMMAND ${example_executable}
ARGS >${CMAKE_CURRENT_BINARY_DIR}/${example}.out
)
-ADD_DEPENDENCIES(unsupported_examples ${example})
+ADD_DEPENDENCIES(unsupported_examples example_${example})
ENDFOREACH(example_src)
diff --git a/unsupported/doc/examples/MatrixExponential.cpp b/unsupported/doc/examples/MatrixExponential.cpp
new file mode 100644
index 000000000..7dc2396df
--- /dev/null
+++ b/unsupported/doc/examples/MatrixExponential.cpp
@@ -0,0 +1,18 @@
+#include <unsupported/Eigen/MatrixFunctions>
+
+using namespace Eigen;
+
+int main()
+{
+ const double pi = std::acos(-1.0);
+
+ MatrixXd A(3,3);
+ A << 0, -pi/4, 0,
+ pi/4, 0, 0,
+ 0, 0, 0;
+ std::cout << "The matrix A is:\n" << A << "\n\n";
+
+ MatrixXd B;
+ ei_matrix_exponential(A, &B);
+ std::cout << "The matrix exponential of A is:\n" << B << "\n\n";
+}
diff --git a/unsupported/doc/examples/MatrixFunction.cpp b/unsupported/doc/examples/MatrixFunction.cpp
new file mode 100644
index 000000000..c11cb821b
--- /dev/null
+++ b/unsupported/doc/examples/MatrixFunction.cpp
@@ -0,0 +1,23 @@
+#include <unsupported/Eigen/MatrixFunctions>
+
+using namespace Eigen;
+
+std::complex<double> expfn(std::complex<double> x, int)
+{
+ return std::exp(x);
+}
+
+int main()
+{
+ const double pi = std::acos(-1.0);
+
+ MatrixXd A(3,3);
+ A << 0, -pi/4, 0,
+ pi/4, 0, 0,
+ 0, 0, 0;
+ std::cout << "The matrix A is:\n" << A << "\n\n";
+
+ MatrixXd B;
+ ei_matrix_function(A, expfn, &B);
+ std::cout << "The matrix exponential of A is:\n" << B << "\n\n";
+}
diff --git a/unsupported/doc/snippets/CMakeLists.txt b/unsupported/doc/snippets/CMakeLists.txt
index fa529d139..19e9b1a1f 100644
--- a/unsupported/doc/snippets/CMakeLists.txt
+++ b/unsupported/doc/snippets/CMakeLists.txt
@@ -7,7 +7,7 @@ FOREACH(snippet_src ${snippets_SRCS})
SET(compile_snippet_target compile_${snippet})
SET(compile_snippet_src ${compile_snippet_target}.cpp)
FILE(READ ${snippet_src} snippet_source_code)
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/doc/compile_snippet.cpp.in
+ CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/doc/snippets/compile_snippet.cpp.in
${CMAKE_CURRENT_BINARY_DIR}/${compile_snippet_src})
ADD_EXECUTABLE(${compile_snippet_target}
${CMAKE_CURRENT_BINARY_DIR}/${compile_snippet_src})
diff --git a/unsupported/test/CMakeLists.txt b/unsupported/test/CMakeLists.txt
index 057c2026e..58af79351 100644
--- a/unsupported/test/CMakeLists.txt
+++ b/unsupported/test/CMakeLists.txt
@@ -1,8 +1,3 @@
-
-include(EigenTesting)
-
-enable_testing()
-
find_package(Adolc)
include_directories(../../test)
diff --git a/unsupported/test/Complex.cpp b/unsupported/test/Complex.cpp
index 969e3f4f9..9ea91cf42 100644
--- a/unsupported/test/Complex.cpp
+++ b/unsupported/test/Complex.cpp
@@ -40,7 +40,7 @@ template <typename T>
void take_std( std::complex<T> * dst, int n )
{
for (int i=0;i<n;++i)
- dst[i] = std::complex<T>(i,i);
+ dst[i] = std::complex<T>(static_cast<float>(i),static_cast<float>(i));
cout << dst[n-1] << endl;
}
diff --git a/unsupported/test/FFT.cpp b/unsupported/test/FFT.cpp
index ad0d426e4..056be2ef3 100644
--- a/unsupported/test/FFT.cpp
+++ b/unsupported/test/FFT.cpp
@@ -45,10 +45,11 @@ complex<long double> promote(long double x) { return complex<long double>( x);
long double totalpower=0;
long double difpower=0;
cerr <<"idx\ttruth\t\tvalue\t|dif|=\n";
- for (size_t k0=0;k0<size_t(fftbuf.size());++k0) {
+ long double pi = acos((long double)-1);
+ for (int k0=0;k0<fftbuf.size();++k0) {
complex<long double> acc = 0;
- long double phinc = -2.*k0* M_PIl / timebuf.size();
- for (size_t k1=0;k1<size_t(timebuf.size());++k1) {
+ long double phinc = -2.*k0* pi / timebuf.size();
+ for (int k1=0;k1<timebuf.size();++k1) {
acc += promote( timebuf[k1] ) * exp( complex<long double>(0,k1*phinc) );
}
totalpower += norm(acc);
@@ -66,8 +67,8 @@ complex<long double> promote(long double x) { return complex<long double>( x);
{
long double totalpower=0;
long double difpower=0;
- size_t n = min( buf1.size(),buf2.size() );
- for (size_t k=0;k<n;++k) {
+ int n = min( buf1.size(),buf2.size() );
+ for (int k=0;k<n;++k) {
totalpower += (norm( buf1[k] ) + norm(buf2[k]) )/2.;
difpower += norm(buf1[k] - buf2[k]);
}
@@ -106,7 +107,7 @@ void test_scalar_generic(int nfft)
// if we've asked for half-spectrum
fft.SetFlag(fft.HalfSpectrum );
fft.fwd( outbuf,inbuf);
- VERIFY(outbuf.size() == (nfft>>1)+1);
+ VERIFY(outbuf.size() == (size_t)( (nfft>>1)+1) );
VERIFY( fft_rmse(outbuf,inbuf) < test_precision<T>() );// gross check
fft.ClearFlag(fft.HalfSpectrum );
diff --git a/unsupported/test/FFTW.cpp b/unsupported/test/FFTW.cpp
index cf7be75aa..c182cab9d 100644
--- a/unsupported/test/FFTW.cpp
+++ b/unsupported/test/FFTW.cpp
@@ -45,10 +45,11 @@ complex<long double> promote(long double x) { return complex<long double>( x);
{
long double totalpower=0;
long double difpower=0;
+ long double pi = acos((long double)-1 );
cerr <<"idx\ttruth\t\tvalue\t|dif|=\n";
for (size_t k0=0;k0<fftbuf.size();++k0) {
complex<long double> acc = 0;
- long double phinc = -2.*k0* M_PIl / timebuf.size();
+ long double phinc = -2.*k0* pi / timebuf.size();
for (size_t k1=0;k1<timebuf.size();++k1) {
acc += promote( timebuf[k1] ) * exp( complex<long double>(0,k1*phinc) );
}
diff --git a/unsupported/test/autodiff.cpp b/unsupported/test/autodiff.cpp
index a96927b41..cac08cd4b 100644
--- a/unsupported/test/autodiff.cpp
+++ b/unsupported/test/autodiff.cpp
@@ -31,7 +31,7 @@ EIGEN_DONT_INLINE Scalar foo(const Scalar& x, const Scalar& y)
// return x+std::sin(y);
EIGEN_ASM_COMMENT("mybegin");
return static_cast<Scalar>(x*2 - std::pow(x,2) + 2*std::sqrt(y*y) - 4 * std::sin(x) + 2 * std::cos(y) - std::exp(-0.5*x*x));
-// return y/x;// - y*2;
+// return x - y;//x*2 -std::pow(x,2);//(2*y/x);// - y*2;
EIGEN_ASM_COMMENT("myend");
}
@@ -137,10 +137,12 @@ template<typename Func> void forward_jacobian(const Func& f)
void test_autodiff_scalar()
{
std::cerr << foo<float>(1,2) << "\n";
- AutoDiffScalar<Vector2f> ax(1,Vector2f::UnitX());
- AutoDiffScalar<Vector2f> ay(2,Vector2f::UnitY());
- std::cerr << foo<AutoDiffScalar<Vector2f> >(ax,ay).value() << " <> "
- << foo<AutoDiffScalar<Vector2f> >(ax,ay).derivatives().transpose() << "\n\n";
+ typedef AutoDiffScalar<Vector2f> AD;
+ AD ax(1,Vector2f::UnitX());
+ AD ay(2,Vector2f::UnitY());
+ foo<AD>(ax,ay);
+ std::cerr << foo<AD>(ax,ay).value() << " <> "
+ << foo<AD>(ax,ay).derivatives().transpose() << "\n\n";
}
void test_autodiff_jacobian()
diff --git a/unsupported/test/matrixExponential.cpp b/unsupported/test/matrixExponential.cpp
index f7ee71768..9e4d8e611 100644
--- a/unsupported/test/matrixExponential.cpp
+++ b/unsupported/test/matrixExponential.cpp
@@ -23,7 +23,6 @@
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#include "main.h"
-#include <Eigen/StdVector>
#include <unsupported/Eigen/MatrixFunctions>
double binom(int n, int k)
@@ -34,6 +33,18 @@ double binom(int n, int k)
return res;
}
+template <typename Derived, typename OtherDerived>
+double relerr(const MatrixBase<Derived>& A, const MatrixBase<OtherDerived>& B)
+{
+ return std::sqrt((A - B).cwise().abs2().sum() / std::min(A.cwise().abs2().sum(), B.cwise().abs2().sum()));
+}
+
+template <typename T>
+T expfn(T x, int)
+{
+ return std::exp(x);
+}
+
template <typename T>
void test2dRotation(double tol)
{
@@ -45,7 +56,13 @@ void test2dRotation(double tol)
{
angle = static_cast<T>(pow(10, i / 5. - 2));
B << cos(angle), sin(angle), -sin(angle), cos(angle);
+
+ ei_matrix_function(angle*A, expfn, &C);
+ std::cout << "test2dRotation: i = " << i << " error funm = " << relerr(C, B);
+ VERIFY(C.isApprox(B, static_cast<T>(tol)));
+
ei_matrix_exponential(angle*A, &C);
+ std::cout << " error expm = " << relerr(C, B) << "\n";
VERIFY(C.isApprox(B, static_cast<T>(tol)));
}
}
@@ -64,7 +81,13 @@ void test2dHyperbolicRotation(double tol)
sh = std::sinh(angle);
A << 0, angle*imagUnit, -angle*imagUnit, 0;
B << ch, sh*imagUnit, -sh*imagUnit, ch;
+
+ ei_matrix_function(A, expfn, &C);
+ std::cout << "test2dHyperbolicRotation: i = " << i << " error funm = " << relerr(C, B);
+ VERIFY(C.isApprox(B, static_cast<T>(tol)));
+
ei_matrix_exponential(A, &C);
+ std::cout << " error expm = " << relerr(C, B) << "\n";
VERIFY(C.isApprox(B, static_cast<T>(tol)));
}
}
@@ -82,7 +105,13 @@ void testPascal(double tol)
for (int i=0; i<size; i++)
for (int j=0; j<=i; j++)
B(i,j) = static_cast<T>(binom(i,j));
+
+ ei_matrix_function(A, expfn, &C);
+ std::cout << "testPascal: size = " << size << " error funm = " << relerr(C, B);
+ VERIFY(C.isApprox(B, static_cast<T>(tol)));
+
ei_matrix_exponential(A, &C);
+ std::cout << " error expm = " << relerr(C, B) << "\n";
VERIFY(C.isApprox(B, static_cast<T>(tol)));
}
}
@@ -102,26 +131,33 @@ void randomTest(const MatrixType& m, double tol)
for(int i = 0; i < g_repeat; i++) {
m1 = MatrixType::Random(rows, cols);
+
+ ei_matrix_function(m1, expfn, &m2);
+ ei_matrix_function(-m1, expfn, &m3);
+ std::cout << "randomTest: error funm = " << relerr(identity, m2 * m3);
+ VERIFY(identity.isApprox(m2 * m3, static_cast<RealScalar>(tol)));
+
ei_matrix_exponential(m1, &m2);
ei_matrix_exponential(-m1, &m3);
- VERIFY(identity.isApprox(m2 * m3, static_cast<RealScalar>(tol)));
+ std::cout << " error expm = " << relerr(identity, m2 * m3) << "\n";
+ VERIFY(identity.isApprox(m2 * m3, static_cast<RealScalar>(tol)));
}
}
void test_matrixExponential()
{
- CALL_SUBTEST_2(test2dRotation<double>(1e-14));
+ CALL_SUBTEST_2(test2dRotation<double>(1e-13));
CALL_SUBTEST_1(test2dRotation<float>(1e-5));
CALL_SUBTEST_2(test2dHyperbolicRotation<double>(1e-14));
CALL_SUBTEST_1(test2dHyperbolicRotation<float>(1e-5));
- CALL_SUBTEST_1(testPascal<float>(1e-5));
- CALL_SUBTEST_2(testPascal<double>(1e-14));
+ CALL_SUBTEST_6(testPascal<float>(1e-6));
+ CALL_SUBTEST_5(testPascal<double>(1e-15));
CALL_SUBTEST_2(randomTest(Matrix2d(), 1e-13));
- CALL_SUBTEST_2(randomTest(Matrix<double,3,3,RowMajor>(), 1e-13));
+ CALL_SUBTEST_7(randomTest(Matrix<double,3,3,RowMajor>(), 1e-13));
CALL_SUBTEST_3(randomTest(Matrix4cd(), 1e-13));
CALL_SUBTEST_4(randomTest(MatrixXd(8,8), 1e-13));
CALL_SUBTEST_1(randomTest(Matrix2f(), 1e-4));
- CALL_SUBTEST_5(randomTest(Matrix3cf(), 1e-4));
+ CALL_SUBTEST_5(randomTest(Matrix3cf(), 1e-4));
CALL_SUBTEST_1(randomTest(Matrix4f(), 1e-4));
CALL_SUBTEST_6(randomTest(MatrixXf(8,8), 1e-4));
}