aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2013-07-17 13:21:35 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2013-07-17 13:21:35 +0200
commit2f593ee67cd2ce995fcf52560daf88774c7c64f2 (patch)
tree973b12ded629a9778d2cb05961edba799d8e908e
parent231d4a6fdae342af5f2a482104539eafe4fc5cdb (diff)
parent20e535e1429cdb2f2dace3e2e6915e33968aa198 (diff)
merge with main branch
-rw-r--r--CMakeLists.txt7
-rw-r--r--CTestCustom.cmake.in5
-rw-r--r--Eigen/Core8
-rw-r--r--Eigen/SPQRSupport2
-rw-r--r--Eigen/Sparse14
-rw-r--r--Eigen/SparseCholesky11
-rw-r--r--Eigen/SparseLU3
-rw-r--r--Eigen/SparseQR4
-rw-r--r--Eigen/src/Cholesky/LDLT.h37
-rw-r--r--Eigen/src/Cholesky/LLT.h10
-rw-r--r--Eigen/src/CholmodSupport/CholmodSupport.h8
-rw-r--r--Eigen/src/Core/Array.h2
-rw-r--r--Eigen/src/Core/ArrayWrapper.h4
-rw-r--r--Eigen/src/Core/Assign.h24
-rw-r--r--Eigen/src/Core/CommaInitializer.h2
-rw-r--r--Eigen/src/Core/CwiseUnaryView.h4
-rw-r--r--Eigen/src/Core/DenseBase.h12
-rw-r--r--Eigen/src/Core/DenseStorage.h16
-rw-r--r--Eigen/src/Core/Diagonal.h4
-rw-r--r--Eigen/src/Core/DiagonalProduct.h37
-rw-r--r--Eigen/src/Core/Dot.h5
-rw-r--r--Eigen/src/Core/Functors.h24
-rw-r--r--Eigen/src/Core/Fuzzy.h4
-rw-r--r--Eigen/src/Core/GeneralProduct.h2
-rw-r--r--Eigen/src/Core/GenericPacketMath.h3
-rw-r--r--Eigen/src/Core/GlobalFunctions.h3
-rw-r--r--Eigen/src/Core/IO.h2
-rw-r--r--Eigen/src/Core/MathFunctions.h249
-rw-r--r--Eigen/src/Core/Matrix.h2
-rw-r--r--Eigen/src/Core/MatrixBase.h4
-rw-r--r--Eigen/src/Core/NoAlias.h4
-rw-r--r--Eigen/src/Core/PlainObjectBase.h2
-rw-r--r--Eigen/src/Core/ReturnByValue.h2
-rw-r--r--Eigen/src/Core/SelfAdjointView.h12
-rw-r--r--Eigen/src/Core/StableNorm.h10
-rw-r--r--Eigen/src/Core/Transpose.h9
-rw-r--r--Eigen/src/Core/arch/AltiVec/PacketMath.h3
-rw-r--r--Eigen/src/Core/arch/NEON/Complex.h10
-rw-r--r--Eigen/src/Core/arch/NEON/PacketMath.h11
-rw-r--r--Eigen/src/Core/arch/SSE/Complex.h8
-rw-r--r--Eigen/src/Core/arch/SSE/MathFunctions.h2
-rw-r--r--Eigen/src/Core/arch/SSE/PacketMath.h4
-rw-r--r--Eigen/src/Core/products/GeneralMatrixVector.h2
-rw-r--r--Eigen/src/Core/products/SelfadjointMatrixMatrix.h34
-rw-r--r--Eigen/src/Core/products/SelfadjointMatrixVector.h12
-rw-r--r--Eigen/src/Core/products/SelfadjointRank2Update.h12
-rw-r--r--Eigen/src/Core/products/TriangularMatrixVector.h2
-rw-r--r--Eigen/src/Core/util/BlasUtil.h11
-rw-r--r--Eigen/src/Core/util/Macros.h14
-rw-r--r--Eigen/src/Core/util/Memory.h17
-rw-r--r--Eigen/src/Core/util/XprHelper.h3
-rw-r--r--Eigen/src/Eigen2Support/Geometry/AlignedBox.h2
-rw-r--r--Eigen/src/Eigen2Support/Geometry/Hyperplane.h2
-rw-r--r--Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h2
-rw-r--r--Eigen/src/Eigen2Support/MathFunctions.h10
-rw-r--r--Eigen/src/Eigen2Support/SVD.h8
-rw-r--r--Eigen/src/Eigenvalues/ComplexEigenSolver.h2
-rw-r--r--Eigen/src/Eigenvalues/ComplexSchur.h10
-rw-r--r--Eigen/src/Eigenvalues/EigenSolver.h26
-rw-r--r--Eigen/src/Eigenvalues/HessenbergDecomposition.h4
-rw-r--r--Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h16
-rw-r--r--Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h2
-rw-r--r--Eigen/src/Eigenvalues/Tridiagonalization.h10
-rw-r--r--Eigen/src/Geometry/AlignedBox.h2
-rw-r--r--Eigen/src/Geometry/EulerAngles.h59
-rw-r--r--Eigen/src/Geometry/Homogeneous.h2
-rw-r--r--Eigen/src/Geometry/Hyperplane.h2
-rw-r--r--Eigen/src/Geometry/OrthoMethods.h26
-rw-r--r--Eigen/src/Geometry/ParametrizedLine.h2
-rw-r--r--Eigen/src/Householder/Householder.h10
-rw-r--r--Eigen/src/Householder/HouseholderSequence.h14
-rw-r--r--Eigen/src/IterativeLinearSolvers/BiCGSTAB.h26
-rw-r--r--Eigen/src/IterativeLinearSolvers/ConjugateGradient.h4
-rw-r--r--Eigen/src/IterativeLinearSolvers/IncompleteLUT.h5
-rw-r--r--Eigen/src/Jacobi/Jacobi.h50
-rw-r--r--Eigen/src/LU/Inverse.h2
-rw-r--r--Eigen/src/MetisSupport/MetisSupport.h2
-rw-r--r--Eigen/src/QR/ColPivHouseholderQR.h32
-rw-r--r--Eigen/src/QR/FullPivHouseholderQR.h27
-rw-r--r--Eigen/src/QR/HouseholderQR.h35
-rw-r--r--Eigen/src/SPQRSupport/SuiteSparseQRSupport.h14
-rw-r--r--Eigen/src/SVD/JacobiSVD.h23
-rw-r--r--Eigen/src/SVD/UpperBidiagonalization.h4
-rw-r--r--Eigen/src/SparseCholesky/SimplicialCholesky.h4
-rw-r--r--Eigen/src/SparseCholesky/SimplicialCholesky_impl.h8
-rw-r--r--Eigen/src/SparseCore/SparseBlock.h2
-rw-r--r--Eigen/src/SparseCore/SparseCwiseBinaryOp.h6
-rw-r--r--Eigen/src/SparseCore/SparseDenseProduct.h1
-rw-r--r--Eigen/src/SparseCore/SparseDiagonalProduct.h22
-rw-r--r--Eigen/src/SparseCore/SparseDot.h6
-rw-r--r--Eigen/src/SparseCore/SparseMatrix.h163
-rw-r--r--Eigen/src/SparseCore/SparseMatrixBase.h33
-rw-r--r--Eigen/src/SparseCore/SparseSelfAdjointView.h35
-rw-r--r--Eigen/src/SparseCore/SparseTranspose.h10
-rw-r--r--Eigen/src/SparseCore/SparseTriangularView.h31
-rw-r--r--Eigen/src/SparseCore/SparseUtil.h16
-rw-r--r--Eigen/src/SparseCore/SparseVector.h103
-rw-r--r--Eigen/src/SparseCore/SparseView.h3
-rw-r--r--Eigen/src/SparseLU/SparseLU.h338
-rw-r--r--Eigen/src/SparseLU/SparseLU_Memory.h6
-rw-r--r--Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h42
-rw-r--r--Eigen/src/SparseLU/SparseLU_column_dfs.h4
-rw-r--r--Eigen/src/SparseLU/SparseLU_pruneL.h2
-rw-r--r--Eigen/src/SparseQR/SparseQR.h128
-rw-r--r--Eigen/src/SuperLUSupport/SuperLUSupport.h4
-rw-r--r--Eigen/src/UmfPackSupport/UmfPackSupport.h14
-rw-r--r--Eigen/src/plugins/BlockMethods.h158
-rw-r--r--bench/spmv.cpp2
-rw-r--r--blas/PackedSelfadjointProduct.h5
-rw-r--r--blas/Rank2Update.h10
-rw-r--r--blas/level1_cplx_impl.h2
-rw-r--r--blas/level1_impl.h4
-rw-r--r--blas/level3_impl.h14
-rw-r--r--cmake/EigenConfigureTesting.cmake8
-rw-r--r--cmake/EigenTesting.cmake18
-rw-r--r--cmake/FindCholmod.cmake11
-rw-r--r--cmake/FindSPQR.cmake9
-rw-r--r--cmake/FindUmfpack.cmake23
-rw-r--r--doc/A05_PortingFrom2To3.dox2
-rw-r--r--doc/CMakeLists.txt2
-rw-r--r--doc/FunctionsTakingEigenTypes.dox50
-rw-r--r--doc/LinearLeastSquares.dox27
-rw-r--r--doc/Manual.dox2
-rw-r--r--doc/QuickReference.dox2
-rw-r--r--doc/TopicAliasing.dox50
-rw-r--r--doc/TutorialMatrixClass.dox13
-rw-r--r--doc/TutorialSparse.dox12
-rw-r--r--doc/UsingIntelMKL.dox2
-rw-r--r--doc/examples/function_taking_ref.cpp19
-rw-r--r--doc/snippets/Cwise_asin.cpp2
-rw-r--r--doc/snippets/MatrixBase_template_int_int_block_int_int_int_int.cpp5
-rw-r--r--doc/snippets/MatrixBase_template_int_int_bottomLeftCorner_int_int.cpp6
-rw-r--r--doc/snippets/MatrixBase_template_int_int_bottomRightCorner_int_int.cpp6
-rw-r--r--doc/snippets/MatrixBase_template_int_int_topLeftCorner_int_int.cpp6
-rw-r--r--doc/snippets/MatrixBase_template_int_int_topRightCorner_int_int.cpp6
-rw-r--r--lapack/CMakeLists.txt746
-rw-r--r--lapack/cholesky.cpp4
-rw-r--r--lapack/clacgv.f116
-rw-r--r--lapack/cladiv.f97
-rw-r--r--lapack/dladiv.f128
-rw-r--r--lapack/dlamch.f189
-rw-r--r--lapack/dlapy2.f104
-rw-r--r--lapack/dlapy3.f111
-rw-r--r--lapack/dsecnd_NONE.f52
-rw-r--r--lapack/ilaclc.f118
-rw-r--r--lapack/ilaclr.f121
-rw-r--r--lapack/iladlc.f118
-rw-r--r--lapack/iladlr.f121
-rw-r--r--lapack/ilaslc.f118
-rw-r--r--lapack/ilaslr.f121
-rw-r--r--lapack/ilazlc.f118
-rw-r--r--lapack/ilazlr.f121
-rw-r--r--lapack/lu.cpp4
-rw-r--r--lapack/second_NONE.f52
-rw-r--r--lapack/sladiv.f128
-rw-r--r--lapack/slamch.f192
-rw-r--r--lapack/slapy2.f104
-rw-r--r--lapack/slapy3.f111
-rw-r--r--lapack/zlacgv.f116
-rw-r--r--lapack/zladiv.f97
-rw-r--r--test/CMakeLists.txt2
-rw-r--r--test/adjoint.cpp17
-rw-r--r--test/array.cpp22
-rw-r--r--test/array_for_matrix.cpp6
-rw-r--r--test/basicstuff.cpp8
-rw-r--r--test/block.cpp14
-rw-r--r--test/cholesky.cpp57
-rw-r--r--test/corners.cpp20
-rw-r--r--test/determinant.cpp6
-rw-r--r--test/eigen2support.cpp4
-rw-r--r--test/eigensolver_complex.cpp7
-rw-r--r--test/eigensolver_generalized_real.cpp5
-rw-r--r--test/eigensolver_generic.cpp6
-rw-r--r--test/eigensolver_selfadjoint.cpp8
-rw-r--r--test/evaluators.cpp353
-rw-r--r--test/geo_alignedbox.cpp8
-rw-r--r--test/geo_eulerangles.cpp61
-rw-r--r--test/geo_quaternion.cpp8
-rw-r--r--test/householder.cpp27
-rw-r--r--test/inverse.cpp6
-rw-r--r--test/jacobi.cpp11
-rw-r--r--test/jacobisvd.cpp10
-rw-r--r--test/main.h58
-rw-r--r--test/mapped_matrix.cpp (renamed from test/map.cpp)2
-rw-r--r--test/mapstride.cpp4
-rw-r--r--test/nesting_ops.cpp11
-rw-r--r--test/packetmath.cpp10
-rw-r--r--test/product_extra.cpp2
-rw-r--r--test/product_notemporary.cpp2
-rw-r--r--test/product_selfadjoint.cpp8
-rw-r--r--test/product_trmm.cpp2
-rw-r--r--test/product_trmv.cpp4
-rw-r--r--test/real_qz.cpp4
-rw-r--r--test/redux.cpp32
-rw-r--r--test/ref.cpp2
-rw-r--r--test/selfadjoint.cpp4
-rw-r--r--test/sizeof.cpp2
-rw-r--r--test/sparse.h24
-rw-r--r--test/sparse_basic.cpp224
-rw-r--r--test/sparse_product.cpp19
-rw-r--r--test/sparse_solver.h79
-rw-r--r--test/sparse_vector.cpp5
-rw-r--r--test/sparselu.cpp4
-rw-r--r--test/sparseqr.cpp8
-rw-r--r--test/special_numbers.cpp5
-rw-r--r--test/spqr_support.cpp2
-rw-r--r--test/triangular.cpp6
-rw-r--r--test/umeyama.cpp2
-rw-r--r--test/upperbidiagonalization.cpp3
-rw-r--r--unsupported/Eigen/ArpackSupport2
-rw-r--r--unsupported/Eigen/MatrixFunctions1
-rw-r--r--unsupported/Eigen/NonLinearOptimization2
-rw-r--r--unsupported/Eigen/SVD39
-rw-r--r--unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h12
-rw-r--r--unsupported/Eigen/src/AutoDiff/AutoDiffVector.h4
-rw-r--r--unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h12
-rw-r--r--unsupported/Eigen/src/IterativeSolvers/DGMRES.h2
-rw-r--r--unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h6
-rw-r--r--unsupported/Eigen/src/LevenbergMarquardt/LevenbergMarquardt.h4
-rw-r--r--unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h2
-rw-r--r--unsupported/Eigen/src/MatrixFunctions/MatrixPower.h572
-rw-r--r--unsupported/Eigen/src/MatrixFunctions/MatrixPowerBase.h388
-rw-r--r--unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h2
-rw-r--r--unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h8
-rw-r--r--unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h12
-rw-r--r--unsupported/Eigen/src/NonLinearOptimization/dogleg.h4
-rw-r--r--unsupported/Eigen/src/Polynomials/PolynomialSolver.h8
-rw-r--r--unsupported/Eigen/src/Polynomials/PolynomialUtils.h2
-rw-r--r--unsupported/Eigen/src/SVD/BDCSVD.h748
-rw-r--r--unsupported/Eigen/src/SVD/CMakeLists.txt6
-rw-r--r--unsupported/Eigen/src/SVD/JacobiSVD.h782
-rw-r--r--unsupported/Eigen/src/SVD/SVDBase.h236
-rw-r--r--unsupported/Eigen/src/SVD/TODOBdcsvd.txt29
-rw-r--r--unsupported/Eigen/src/SVD/doneInBDCSVD.txt21
-rw-r--r--unsupported/Eigen/src/Splines/Spline.h5
-rw-r--r--unsupported/Eigen/src/Splines/SplineFitting.h3
-rw-r--r--unsupported/bench/bench_svd.cpp123
-rw-r--r--unsupported/test/CMakeLists.txt1
-rw-r--r--unsupported/test/bdcsvd.cpp213
-rw-r--r--unsupported/test/jacobisvd.cpp198
-rw-r--r--unsupported/test/kronecker_product.cpp4
-rw-r--r--unsupported/test/matrix_power.cpp77
-rw-r--r--unsupported/test/polynomialsolver.cpp3
-rw-r--r--unsupported/test/sparse_extra.cpp1
-rw-r--r--unsupported/test/svd_common.h261
245 files changed, 8364 insertions, 2518 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index de25c69f9..ad0269ea6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
project(Eigen)
-cmake_minimum_required(VERSION 2.6.2)
+cmake_minimum_required(VERSION 2.8.2)
# guard against in-source builds
@@ -150,11 +150,14 @@ if(NOT MSVC)
ei_add_cxx_compiler_flag("-fno-check-new")
ei_add_cxx_compiler_flag("-fno-common")
ei_add_cxx_compiler_flag("-fstrict-aliasing")
- ei_add_cxx_compiler_flag("-wd981") # disbale ICC's "operands are evaluated in unspecified order" remark
+ ei_add_cxx_compiler_flag("-wd981") # disable ICC's "operands are evaluated in unspecified order" remark
+ ei_add_cxx_compiler_flag("-wd2304") # disbale ICC's "warning #2304: non-explicit constructor with single argument may cause implicit type conversion" produced by -Wnon-virtual-dtor
# The -ansi flag must be added last, otherwise it is also used as a linker flag by check_cxx_compiler_flag making it fails
# Moreover we should not set both -strict-ansi and -ansi
check_cxx_compiler_flag("-strict-ansi" COMPILER_SUPPORT_STRICTANSI)
+ ei_add_cxx_compiler_flag("-Qunused-arguments") # disable clang warning: argument unused during compilation: '-ansi'
+
if(COMPILER_SUPPORT_STRICTANSI)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -strict-ansi")
else()
diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in
index 3b2bacaa0..9fed9d327 100644
--- a/CTestCustom.cmake.in
+++ b/CTestCustom.cmake.in
@@ -1,4 +1,3 @@
-## A tribute to Dynamic!
-set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS "33331")
-set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS "33331")
+set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS "2000")
+set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS "2000")
diff --git a/Eigen/Core b/Eigen/Core
index 1798264e9..d15795aed 100644
--- a/Eigen/Core
+++ b/Eigen/Core
@@ -40,6 +40,12 @@
// defined e.g. EIGEN_DONT_ALIGN) so it needs to be done before we do anything with vectorization.
#include "src/Core/util/Macros.h"
+// Disable the ipa-cp-clone optimization flag with MinGW 6.x or newer (enabled by default with -O3)
+// See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=556 for details.
+#if defined(__MINGW32__) && EIGEN_GNUC_AT_LEAST(4,6)
+ #pragma GCC optimize ("-fno-ipa-cp-clone")
+#endif
+
#include <complex>
// this include file manages BLAS and MKL related macros
@@ -266,8 +272,8 @@ using std::ptrdiff_t;
#include "src/Core/util/Constants.h"
#include "src/Core/util/ForwardDeclarations.h"
#include "src/Core/util/Meta.h"
-#include "src/Core/util/XprHelper.h"
#include "src/Core/util/StaticAssert.h"
+#include "src/Core/util/XprHelper.h"
#include "src/Core/util/Memory.h"
#include "src/Core/NumTraits.h"
diff --git a/Eigen/SPQRSupport b/Eigen/SPQRSupport
index 213e0284c..77016442e 100644
--- a/Eigen/SPQRSupport
+++ b/Eigen/SPQRSupport
@@ -26,4 +26,4 @@
#include "src/CholmodSupport/CholmodSupport.h"
#include "src/SPQRSupport/SuiteSparseQRSupport.h"
-#endif \ No newline at end of file
+#endif
diff --git a/Eigen/Sparse b/Eigen/Sparse
index 9d4da4c06..7cc9c0913 100644
--- a/Eigen/Sparse
+++ b/Eigen/Sparse
@@ -1,15 +1,15 @@
#ifndef EIGEN_SPARSE_MODULE_H
#define EIGEN_SPARSE_MODULE_H
-/** defgroup Sparse_modules Sparse modules
+/** \defgroup Sparse_Module Sparse meta-module
*
* Meta-module including all related modules:
- * - SparseCore
- * - OrderingMethods
- * - SparseCholesky
- * - SparseLU
- * - SparseQR
- * - IterativeLinearSolvers
+ * - \ref SparseCore_Module
+ * - \ref OrderingMethods_Module
+ * - \ref SparseCholesky_Module
+ * - \ref SparseLU_Module
+ * - \ref SparseQR_Module
+ * - \ref IterativeLinearSolvers_Module
*
* \code
* #include <Eigen/Sparse>
diff --git a/Eigen/SparseCholesky b/Eigen/SparseCholesky
index 800f17bc4..9f5056aa1 100644
--- a/Eigen/SparseCholesky
+++ b/Eigen/SparseCholesky
@@ -1,7 +1,17 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2008-2013 Gael Guennebaud <gael.guennebaud@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
#ifndef EIGEN_SPARSECHOLESKY_MODULE_H
#define EIGEN_SPARSECHOLESKY_MODULE_H
#include "SparseCore"
+#include "OrderingMethods"
#include "src/Core/util/DisableStupidWarnings.h"
@@ -26,7 +36,6 @@
#include "src/misc/Solve.h"
#include "src/misc/SparseSolve.h"
-
#include "src/SparseCholesky/SimplicialCholesky.h"
#ifndef EIGEN_MPL2_ONLY
diff --git a/Eigen/SparseLU b/Eigen/SparseLU
index 38b38b531..8527a49bd 100644
--- a/Eigen/SparseLU
+++ b/Eigen/SparseLU
@@ -20,6 +20,9 @@
* Please, see the documentation of the SparseLU class for more details.
*/
+#include "src/misc/Solve.h"
+#include "src/misc/SparseSolve.h"
+
// Ordering interface
#include "OrderingMethods"
diff --git a/Eigen/SparseQR b/Eigen/SparseQR
index f51913f7b..4ee42065e 100644
--- a/Eigen/SparseQR
+++ b/Eigen/SparseQR
@@ -20,6 +20,10 @@
*
*
*/
+
+#include "src/misc/Solve.h"
+#include "src/misc/SparseSolve.h"
+
#include "OrderingMethods"
#include "src/SparseCore/SparseColEtree.h"
#include "src/SparseQR/SparseQR.h"
diff --git a/Eigen/src/Cholesky/LDLT.h b/Eigen/src/Cholesky/LDLT.h
index 9bd60d648..05b300c56 100644
--- a/Eigen/src/Cholesky/LDLT.h
+++ b/Eigen/src/Cholesky/LDLT.h
@@ -259,7 +259,7 @@ template<> struct ldlt_inplace<Lower>
{
transpositions.setIdentity();
if(sign)
- *sign = real(mat.coeff(0,0))>0 ? 1:-1;
+ *sign = numext::real(mat.coeff(0,0))>0 ? 1:-1;
return true;
}
@@ -278,22 +278,13 @@ template<> struct ldlt_inplace<Lower>
// are compared; if any diagonal is negligible compared
// to the largest overall, the algorithm bails.
cutoff = abs(NumTraits<Scalar>::epsilon() * biggest_in_corner);
-
- if(sign)
- *sign = real(mat.diagonal().coeff(index_of_biggest_in_corner)) > 0 ? 1 : -1;
- }
- else if(sign)
- {
- // LDLT is not guaranteed to work for indefinite matrices, but let's try to get the sign right
- int newSign = real(mat.diagonal().coeff(index_of_biggest_in_corner)) > 0;
- if(newSign != *sign)
- *sign = 0;
}
// Finish early if the matrix is not full rank.
if(biggest_in_corner < cutoff)
{
for(Index i = k; i < size; i++) transpositions.coeffRef(i) = i;
+ if(sign) *sign = 0;
break;
}
@@ -309,11 +300,11 @@ template<> struct ldlt_inplace<Lower>
for(int i=k+1;i<index_of_biggest_in_corner;++i)
{
Scalar tmp = mat.coeffRef(i,k);
- mat.coeffRef(i,k) = conj(mat.coeffRef(index_of_biggest_in_corner,i));
- mat.coeffRef(index_of_biggest_in_corner,i) = conj(tmp);
+ mat.coeffRef(i,k) = numext::conj(mat.coeffRef(index_of_biggest_in_corner,i));
+ mat.coeffRef(index_of_biggest_in_corner,i) = numext::conj(tmp);
}
if(NumTraits<Scalar>::IsComplex)
- mat.coeffRef(index_of_biggest_in_corner,k) = conj(mat.coeff(index_of_biggest_in_corner,k));
+ mat.coeffRef(index_of_biggest_in_corner,k) = numext::conj(mat.coeff(index_of_biggest_in_corner,k));
}
// partition the matrix:
@@ -334,6 +325,16 @@ template<> struct ldlt_inplace<Lower>
}
if((rs>0) && (abs(mat.coeffRef(k,k)) > cutoff))
A21 /= mat.coeffRef(k,k);
+
+ if(sign)
+ {
+ // LDLT is not guaranteed to work for indefinite matrices, but let's try to get the sign right
+ int newSign = numext::real(mat.diagonal().coeff(index_of_biggest_in_corner)) > 0;
+ if(k == 0)
+ *sign = newSign;
+ else if(*sign != newSign)
+ *sign = 0;
+ }
}
return true;
@@ -349,7 +350,7 @@ template<> struct ldlt_inplace<Lower>
template<typename MatrixType, typename WDerived>
static bool updateInPlace(MatrixType& mat, MatrixBase<WDerived>& w, const typename MatrixType::RealScalar& sigma=1)
{
- using internal::isfinite;
+ using numext::isfinite;
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar;
typedef typename MatrixType::Index Index;
@@ -367,9 +368,9 @@ template<> struct ldlt_inplace<Lower>
break;
// Update the diagonal terms
- RealScalar dj = real(mat.coeff(j,j));
+ RealScalar dj = numext::real(mat.coeff(j,j));
Scalar wj = w.coeff(j);
- RealScalar swj2 = sigma*abs2(wj);
+ RealScalar swj2 = sigma*numext::abs2(wj);
RealScalar gamma = dj*alpha + swj2;
mat.coeffRef(j,j) += swj2/alpha;
@@ -380,7 +381,7 @@ template<> struct ldlt_inplace<Lower>
Index rs = size-j-1;
w.tail(rs) -= wj * mat.col(j).tail(rs);
if(gamma != 0)
- mat.col(j).tail(rs) += (sigma*conj(wj)/gamma)*w.tail(rs);
+ mat.col(j).tail(rs) += (sigma*numext::conj(wj)/gamma)*w.tail(rs);
}
return true;
}
diff --git a/Eigen/src/Cholesky/LLT.h b/Eigen/src/Cholesky/LLT.h
index db22a2f85..2e6189f7d 100644
--- a/Eigen/src/Cholesky/LLT.h
+++ b/Eigen/src/Cholesky/LLT.h
@@ -232,10 +232,10 @@ static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const V
RealScalar beta = 1;
for(Index j=0; j<n; ++j)
{
- RealScalar Ljj = real(mat.coeff(j,j));
- RealScalar dj = abs2(Ljj);
+ RealScalar Ljj = numext::real(mat.coeff(j,j));
+ RealScalar dj = numext::abs2(Ljj);
Scalar wj = temp.coeff(j);
- RealScalar swj2 = sigma*abs2(wj);
+ RealScalar swj2 = sigma*numext::abs2(wj);
RealScalar gamma = dj*beta + swj2;
RealScalar x = dj + swj2/beta;
@@ -251,7 +251,7 @@ static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const V
{
temp.tail(rs) -= (wj/Ljj) * mat.col(j).tail(rs);
if(gamma != 0)
- mat.col(j).tail(rs) = (nLjj/Ljj) * mat.col(j).tail(rs) + (nLjj * sigma*conj(wj)/gamma)*temp.tail(rs);
+ mat.col(j).tail(rs) = (nLjj/Ljj) * mat.col(j).tail(rs) + (nLjj * sigma*numext::conj(wj)/gamma)*temp.tail(rs);
}
}
}
@@ -277,7 +277,7 @@ template<typename Scalar> struct llt_inplace<Scalar, Lower>
Block<MatrixType,1,Dynamic> A10(mat,k,0,1,k);
Block<MatrixType,Dynamic,Dynamic> A20(mat,k+1,0,rs,k);
- RealScalar x = real(mat.coeff(k,k));
+ RealScalar x = numext::real(mat.coeff(k,k));
if (k>0) x -= A10.squaredNorm();
if (x<=RealScalar(0))
return k;
diff --git a/Eigen/src/CholmodSupport/CholmodSupport.h b/Eigen/src/CholmodSupport/CholmodSupport.h
index 42d289ad8..783324b0b 100644
--- a/Eigen/src/CholmodSupport/CholmodSupport.h
+++ b/Eigen/src/CholmodSupport/CholmodSupport.h
@@ -126,7 +126,7 @@ cholmod_dense viewAsCholmod(MatrixBase<Derived>& mat)
res.ncol = mat.cols();
res.nzmax = res.nrow * res.ncol;
res.d = Derived::IsVectorAtCompileTime ? mat.derived().size() : mat.derived().outerStride();
- res.x = mat.derived().data();
+ res.x = (void*)(mat.derived().data());
res.z = 0;
internal::cholmod_configure_matrix<Scalar>(res);
@@ -295,7 +295,8 @@ class CholmodBase : internal::noncopyable
eigen_assert(size==b.rows());
// note: cd stands for Cholmod Dense
- cholmod_dense b_cd = viewAsCholmod(b.const_cast_derived());
+ Rhs& b_ref(b.const_cast_derived());
+ cholmod_dense b_cd = viewAsCholmod(b_ref);
cholmod_dense* x_cd = cholmod_solve(CHOLMOD_A, m_cholmodFactor, &b_cd, &m_cholmod);
if(!x_cd)
{
@@ -312,6 +313,7 @@ class CholmodBase : internal::noncopyable
{
eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
const Index size = m_cholmodFactor->n;
+ EIGEN_UNUSED_VARIABLE(size);
eigen_assert(size==b.rows());
// note: cs stands for Cholmod Sparse
@@ -344,7 +346,7 @@ class CholmodBase : internal::noncopyable
}
template<typename Stream>
- void dumpMemory(Stream& s)
+ void dumpMemory(Stream& /*s*/)
{}
protected:
diff --git a/Eigen/src/Core/Array.h b/Eigen/src/Core/Array.h
index 4c83f7e7f..2539b1c72 100644
--- a/Eigen/src/Core/Array.h
+++ b/Eigen/src/Core/Array.h
@@ -111,7 +111,7 @@ class Array
* \sa resize(Index,Index)
*/
EIGEN_DEVICE_FUNC
- EIGEN_STRONG_INLINE explicit Array() : Base()
+ EIGEN_STRONG_INLINE Array() : Base()
{
Base::_check_template_params();
EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
diff --git a/Eigen/src/Core/ArrayWrapper.h b/Eigen/src/Core/ArrayWrapper.h
index 1e021b0b9..a791bc358 100644
--- a/Eigen/src/Core/ArrayWrapper.h
+++ b/Eigen/src/Core/ArrayWrapper.h
@@ -55,7 +55,7 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
inline Index outerStride() const { return m_expression.outerStride(); }
inline Index innerStride() const { return m_expression.innerStride(); }
- inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
+ inline ScalarWithConstIfNotLvalue* data() { return m_expression.const_cast_derived().data(); }
inline const Scalar* data() const { return m_expression.data(); }
inline CoeffReturnType coeff(Index rowId, Index colId) const
@@ -175,7 +175,7 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
inline Index outerStride() const { return m_expression.outerStride(); }
inline Index innerStride() const { return m_expression.innerStride(); }
- inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
+ inline ScalarWithConstIfNotLvalue* data() { return m_expression.const_cast_derived().data(); }
inline const Scalar* data() const { return m_expression.data(); }
inline CoeffReturnType coeff(Index rowId, Index colId) const
diff --git a/Eigen/src/Core/Assign.h b/Eigen/src/Core/Assign.h
index 8c9078f06..b5a5a9fdb 100644
--- a/Eigen/src/Core/Assign.h
+++ b/Eigen/src/Core/Assign.h
@@ -519,20 +519,20 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>
namespace internal {
template<typename Derived, typename OtherDerived,
- bool EvalBeforeAssigning = (int(OtherDerived::Flags) & EvalBeforeAssigningBit) != 0,
- bool NeedToTranspose = Derived::IsVectorAtCompileTime
- && OtherDerived::IsVectorAtCompileTime
- && ((int(Derived::RowsAtCompileTime) == 1 && int(OtherDerived::ColsAtCompileTime) == 1)
- | // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&".
- // revert to || as soon as not needed anymore.
- (int(Derived::ColsAtCompileTime) == 1 && int(OtherDerived::RowsAtCompileTime) == 1))
- && int(Derived::SizeAtCompileTime) != 1>
+ bool EvalBeforeAssigning = (int(internal::traits<OtherDerived>::Flags) & EvalBeforeAssigningBit) != 0,
+ bool NeedToTranspose = ((int(Derived::RowsAtCompileTime) == 1 && int(OtherDerived::ColsAtCompileTime) == 1)
+ | // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&".
+ // revert to || as soon as not needed anymore.
+ (int(Derived::ColsAtCompileTime) == 1 && int(OtherDerived::RowsAtCompileTime) == 1))
+ && int(Derived::SizeAtCompileTime) != 1>
struct assign_selector;
template<typename Derived, typename OtherDerived>
struct assign_selector<Derived,OtherDerived,false,false> {
EIGEN_DEVICE_FUNC
static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); }
+ template<typename ActualDerived, typename ActualOtherDerived>
+ static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { other.evalTo(dst); return dst; }
};
template<typename Derived, typename OtherDerived>
struct assign_selector<Derived,OtherDerived,true,false> {
@@ -543,6 +543,8 @@ template<typename Derived, typename OtherDerived>
struct assign_selector<Derived,OtherDerived,false,true> {
EIGEN_DEVICE_FUNC
static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); }
+ template<typename ActualDerived, typename ActualOtherDerived>
+ static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { Transpose<ActualDerived> dstTrans(dst); other.evalTo(dstTrans); return dst; }
};
template<typename Derived, typename OtherDerived>
struct assign_selector<Derived,OtherDerived,true,true> {
@@ -582,16 +584,14 @@ template<typename Derived>
template <typename OtherDerived>
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const EigenBase<OtherDerived>& other)
{
- other.derived().evalTo(derived());
- return derived();
+ return internal::assign_selector<Derived,OtherDerived,false>::evalTo(derived(), other.derived());
}
template<typename Derived>
template<typename OtherDerived>
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
{
- other.evalTo(derived());
- return derived();
+ return internal::assign_selector<Derived,OtherDerived,false>::evalTo(derived(), other.derived());
}
} // end namespace Eigen
diff --git a/Eigen/src/Core/CommaInitializer.h b/Eigen/src/Core/CommaInitializer.h
index 1f801e2a0..2bbf74b05 100644
--- a/Eigen/src/Core/CommaInitializer.h
+++ b/Eigen/src/Core/CommaInitializer.h
@@ -124,6 +124,8 @@ struct CommaInitializer
*
* Example: \include MatrixBase_set.cpp
* Output: \verbinclude MatrixBase_set.out
+ *
+ * \note According the c++ standard, the argument expressions of this comma initializer are evaluated in arbitrary order.
*
* \sa CommaInitializer::finished(), class CommaInitializer
*/
diff --git a/Eigen/src/Core/CwiseUnaryView.h b/Eigen/src/Core/CwiseUnaryView.h
index 9f9d4972d..b2638d326 100644
--- a/Eigen/src/Core/CwiseUnaryView.h
+++ b/Eigen/src/Core/CwiseUnaryView.h
@@ -56,8 +56,7 @@ template<typename ViewOp, typename MatrixType, typename StorageKind>
class CwiseUnaryViewImpl;
template<typename ViewOp, typename MatrixType>
-class CwiseUnaryView : internal::no_assignment_operator,
- public CwiseUnaryViewImpl<ViewOp, MatrixType, typename internal::traits<MatrixType>::StorageKind>
+class CwiseUnaryView : public CwiseUnaryViewImpl<ViewOp, MatrixType, typename internal::traits<MatrixType>::StorageKind>
{
public:
@@ -99,6 +98,7 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
typedef typename internal::dense_xpr_base< CwiseUnaryView<ViewOp, MatrixType> >::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryViewImpl)
inline Scalar* data() { return &coeffRef(0); }
inline const Scalar* data() const { return &coeff(0); }
diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h
index 6a6ba2954..097717075 100644
--- a/Eigen/src/Core/DenseBase.h
+++ b/Eigen/src/Core/DenseBase.h
@@ -13,6 +13,16 @@
namespace Eigen {
+namespace internal {
+
+// The index type defined by EIGEN_DEFAULT_DENSE_INDEX_TYPE must be a signed type.
+// This dummy function simply aims at checking that at compile time.
+static inline void check_DenseIndex_is_signed() {
+ EIGEN_STATIC_ASSERT(NumTraits<DenseIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
+}
+
+} // end namespace internal
+
/** \class DenseBase
* \ingroup Core_Module
*
@@ -286,7 +296,7 @@ template<typename Derived> class DenseBase
EIGEN_DEVICE_FUNC
Eigen::Transpose<Derived> transpose();
- typedef const Transpose<const Derived> ConstTransposeReturnType;
+ typedef typename internal::add_const<Transpose<const Derived> >::type ConstTransposeReturnType;
EIGEN_DEVICE_FUNC
ConstTransposeReturnType transpose() const;
EIGEN_DEVICE_FUNC
diff --git a/Eigen/src/Core/DenseStorage.h b/Eigen/src/Core/DenseStorage.h
index 203944620..5832868a5 100644
--- a/Eigen/src/Core/DenseStorage.h
+++ b/Eigen/src/Core/DenseStorage.h
@@ -118,7 +118,7 @@ template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseSt
{
internal::plain_array<T,Size,_Options> m_data;
public:
- EIGEN_DEVICE_FUNC inline explicit DenseStorage() {}
+ EIGEN_DEVICE_FUNC inline DenseStorage() {}
EIGEN_DEVICE_FUNC inline DenseStorage(internal::constructor_without_unaligned_array_assert)
: m_data(internal::constructor_without_unaligned_array_assert()) {}
EIGEN_DEVICE_FUNC inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
@@ -135,7 +135,7 @@ template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseSt
template<typename T, int _Rows, int _Cols, int _Options> class DenseStorage<T, 0, _Rows, _Cols, _Options>
{
public:
- inline explicit DenseStorage() {}
+ inline DenseStorage() {}
inline DenseStorage(internal::constructor_without_unaligned_array_assert) {}
inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
inline void swap(DenseStorage& ) {}
@@ -164,7 +164,7 @@ template<typename T, int Size, int _Options> class DenseStorage<T, Size, Dynamic
DenseIndex m_rows;
DenseIndex m_cols;
public:
- inline explicit DenseStorage() : m_rows(0), m_cols(0) {}
+ inline DenseStorage() : m_rows(0), m_cols(0) {}
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
inline DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) : m_rows(nbRows), m_cols(nbCols) {}
@@ -184,7 +184,7 @@ template<typename T, int Size, int _Cols, int _Options> class DenseStorage<T, Si
internal::plain_array<T,Size,_Options> m_data;
DenseIndex m_rows;
public:
- inline explicit DenseStorage() : m_rows(0) {}
+ inline DenseStorage() : m_rows(0) {}
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {}
inline DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex) : m_rows(nbRows) {}
@@ -203,7 +203,7 @@ template<typename T, int Size, int _Rows, int _Options> class DenseStorage<T, Si
internal::plain_array<T,Size,_Options> m_data;
DenseIndex m_cols;
public:
- inline explicit DenseStorage() : m_cols(0) {}
+ inline DenseStorage() : m_cols(0) {}
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
: m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {}
inline DenseStorage(DenseIndex, DenseIndex, DenseIndex nbCols) : m_cols(nbCols) {}
@@ -223,7 +223,7 @@ template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynam
DenseIndex m_rows;
DenseIndex m_cols;
public:
- inline explicit DenseStorage() : m_data(0), m_rows(0), m_cols(0) {}
+ inline DenseStorage() : m_data(0), m_rows(0), m_cols(0) {}
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
: m_data(0), m_rows(0), m_cols(0) {}
inline DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols)
@@ -264,7 +264,7 @@ template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Ro
T *m_data;
DenseIndex m_cols;
public:
- inline explicit DenseStorage() : m_data(0), m_cols(0) {}
+ inline DenseStorage() : m_data(0), m_cols(0) {}
inline DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
inline DenseStorage(DenseIndex size, DenseIndex, DenseIndex nbCols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_cols(nbCols)
{ EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
@@ -300,7 +300,7 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dyn
T *m_data;
DenseIndex m_rows;
public:
- inline explicit DenseStorage() : m_data(0), m_rows(0) {}
+ inline DenseStorage() : m_data(0), m_rows(0) {}
inline DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
inline DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(nbRows)
{ EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
diff --git a/Eigen/src/Core/Diagonal.h b/Eigen/src/Core/Diagonal.h
index 0927e9969..aab8007b3 100644
--- a/Eigen/src/Core/Diagonal.h
+++ b/Eigen/src/Core/Diagonal.h
@@ -75,7 +75,7 @@ template<typename MatrixType, int _DiagIndex> class Diagonal
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Diagonal)
inline Index rows() const
- { return m_index.value()<0 ? (std::min)(m_matrix.cols(),m_matrix.rows()+m_index.value()) : (std::min)(m_matrix.rows(),m_matrix.cols()-m_index.value()); }
+ { return m_index.value()<0 ? (std::min<Index>)(m_matrix.cols(),m_matrix.rows()+m_index.value()) : (std::min<Index>)(m_matrix.rows(),m_matrix.cols()-m_index.value()); }
inline Index cols() const { return 1; }
@@ -172,7 +172,7 @@ MatrixBase<Derived>::diagonal()
/** This is the const version of diagonal(). */
template<typename Derived>
-inline const typename MatrixBase<Derived>::ConstDiagonalReturnType
+inline typename MatrixBase<Derived>::ConstDiagonalReturnType
MatrixBase<Derived>::diagonal() const
{
return ConstDiagonalReturnType(derived());
diff --git a/Eigen/src/Core/DiagonalProduct.h b/Eigen/src/Core/DiagonalProduct.h
index d55b2c250..c03a0c2e1 100644
--- a/Eigen/src/Core/DiagonalProduct.h
+++ b/Eigen/src/Core/DiagonalProduct.h
@@ -26,14 +26,15 @@ struct traits<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> >
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
_StorageOrder = MatrixType::Flags & RowMajorBit ? RowMajor : ColMajor,
- _PacketOnDiag = !((int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheLeft)
- ||(int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheRight)),
+ _ScalarAccessOnDiag = !((int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheLeft)
+ ||(int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheRight)),
_SameTypes = is_same<typename MatrixType::Scalar, typename DiagonalType::Scalar>::value,
// FIXME currently we need same types, but in the future the next rule should be the one
- //_Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagonalType::Flags)&PacketAccessBit))),
- _Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && _SameTypes && ((!_PacketOnDiag) || (bool(int(DiagonalType::Flags)&PacketAccessBit))),
+ //_Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagonalType::DiagonalVectorType::Flags)&PacketAccessBit))),
+ _Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && _SameTypes && (_ScalarAccessOnDiag || (bool(int(DiagonalType::DiagonalVectorType::Flags)&PacketAccessBit))),
+ _LinearAccessMask = (RowsAtCompileTime==1 || ColsAtCompileTime==1) ? LinearAccessBit : 0,
- Flags = (HereditaryBits & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0),
+ Flags = ((HereditaryBits|_LinearAccessMask) & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0) | AlignedBit,//(int(MatrixType::Flags)&int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit),
CoeffReadCost = NumTraits<Scalar>::MulCost + MatrixType::CoeffReadCost + DiagonalType::DiagonalVectorType::CoeffReadCost
};
};
@@ -54,13 +55,21 @@ class DiagonalProduct : internal::no_assignment_operator,
eigen_assert(diagonal.diagonal().size() == (ProductOrder == OnTheLeft ? matrix.rows() : matrix.cols()));
}
- inline Index rows() const { return m_matrix.rows(); }
- inline Index cols() const { return m_matrix.cols(); }
+ EIGEN_STRONG_INLINE Index rows() const { return m_matrix.rows(); }
+ EIGEN_STRONG_INLINE Index cols() const { return m_matrix.cols(); }
- const Scalar coeff(Index row, Index col) const
+ EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const
{
return m_diagonal.diagonal().coeff(ProductOrder == OnTheLeft ? row : col) * m_matrix.coeff(row, col);
}
+
+ EIGEN_STRONG_INLINE const Scalar coeff(Index idx) const
+ {
+ enum {
+ StorageOrder = int(MatrixType::Flags) & RowMajorBit ? RowMajor : ColMajor
+ };
+ return coeff(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx);
+ }
template<int LoadMode>
EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
@@ -69,11 +78,19 @@ class DiagonalProduct : internal::no_assignment_operator,
StorageOrder = Flags & RowMajorBit ? RowMajor : ColMajor
};
const Index indexInDiagonalVector = ProductOrder == OnTheLeft ? row : col;
-
return packet_impl<LoadMode>(row,col,indexInDiagonalVector,typename internal::conditional<
((int(StorageOrder) == RowMajor && int(ProductOrder) == OnTheLeft)
||(int(StorageOrder) == ColMajor && int(ProductOrder) == OnTheRight)), internal::true_type, internal::false_type>::type());
}
+
+ template<int LoadMode>
+ EIGEN_STRONG_INLINE PacketScalar packet(Index idx) const
+ {
+ enum {
+ StorageOrder = int(MatrixType::Flags) & RowMajorBit ? RowMajor : ColMajor
+ };
+ return packet<LoadMode>(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx);
+ }
protected:
template<int LoadMode>
@@ -88,7 +105,7 @@ class DiagonalProduct : internal::no_assignment_operator,
{
enum {
InnerSize = (MatrixType::Flags & RowMajorBit) ? MatrixType::ColsAtCompileTime : MatrixType::RowsAtCompileTime,
- DiagonalVectorPacketLoadMode = (LoadMode == Aligned && ((InnerSize%16) == 0)) ? Aligned : Unaligned
+ DiagonalVectorPacketLoadMode = (LoadMode == Aligned && (((InnerSize%16) == 0) || (int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit)==AlignedBit) ? Aligned : Unaligned)
};
return internal::pmul(m_matrix.template packet<LoadMode>(row, col),
m_diagonal.diagonal().template packet<DiagonalVectorPacketLoadMode>(id));
diff --git a/Eigen/src/Core/Dot.h b/Eigen/src/Core/Dot.h
index dacd71f5f..718de5d1a 100644
--- a/Eigen/src/Core/Dot.h
+++ b/Eigen/src/Core/Dot.h
@@ -115,7 +115,7 @@ MatrixBase<Derived>::eigen2_dot(const MatrixBase<OtherDerived>& other) const
template<typename Derived>
EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::squaredNorm() const
{
- return internal::real((*this).cwiseAbs2().sum());
+ return numext::real((*this).cwiseAbs2().sum());
}
/** \returns, for vectors, the \em l2 norm of \c *this, and for matrices the Frobenius norm.
@@ -170,6 +170,7 @@ struct lpNorm_selector
EIGEN_DEVICE_FUNC
static inline RealScalar run(const MatrixBase<Derived>& m)
{
+ using std::pow;
return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p);
}
};
@@ -235,7 +236,7 @@ bool MatrixBase<Derived>::isOrthogonal
{
typename internal::nested<Derived,2>::type nested(derived());
typename internal::nested<OtherDerived,2>::type otherNested(other.derived());
- return internal::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm();
+ return numext::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm();
}
/** \returns true if *this is approximately an unitary matrix,
diff --git a/Eigen/src/Core/Functors.h b/Eigen/src/Core/Functors.h
index 217cc90d7..74eb9cc54 100644
--- a/Eigen/src/Core/Functors.h
+++ b/Eigen/src/Core/Functors.h
@@ -171,7 +171,8 @@ struct functor_traits<scalar_hypot_op<Scalar> > {
*/
template<typename Scalar, typename OtherScalar> struct scalar_binary_pow_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_binary_pow_op)
- EIGEN_DEVICE_FUNC inline Scalar operator() (const Scalar& a, const OtherScalar& b) const { return internal::pow(a, b); }
+ EIGEN_DEVICE_FUNC
+ inline Scalar operator() (const Scalar& a, const OtherScalar& b) const { return numext::pow(a, b); }
};
template<typename Scalar, typename OtherScalar>
struct functor_traits<scalar_binary_pow_op<Scalar,OtherScalar> > {
@@ -310,7 +311,8 @@ struct functor_traits<scalar_abs_op<Scalar> >
template<typename Scalar> struct scalar_abs2_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_abs2_op)
typedef typename NumTraits<Scalar>::Real result_type;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return internal::abs2(a); }
+ EIGEN_DEVICE_FUNC
+ EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return numext::abs2(a); }
template<typename Packet>
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
{ return internal::pmul(a,a); }
@@ -326,7 +328,8 @@ struct functor_traits<scalar_abs2_op<Scalar> >
*/
template<typename Scalar> struct scalar_conjugate_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_conjugate_op)
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { using internal::conj; return conj(a); }
+ EIGEN_DEVICE_FUNC
+ EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { using numext::conj; return conj(a); }
template<typename Packet>
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pconj(a); }
};
@@ -363,7 +366,8 @@ template<typename Scalar>
struct scalar_real_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_real_op)
typedef typename NumTraits<Scalar>::Real result_type;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return internal::real(a); }
+ EIGEN_DEVICE_FUNC
+ EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::real(a); }
};
template<typename Scalar>
struct functor_traits<scalar_real_op<Scalar> >
@@ -378,7 +382,8 @@ template<typename Scalar>
struct scalar_imag_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_op)
typedef typename NumTraits<Scalar>::Real result_type;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return internal::imag(a); }
+ EIGEN_DEVICE_FUNC
+ EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::imag(a); }
};
template<typename Scalar>
struct functor_traits<scalar_imag_op<Scalar> >
@@ -393,7 +398,8 @@ template<typename Scalar>
struct scalar_real_ref_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_real_ref_op)
typedef typename NumTraits<Scalar>::Real result_type;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return internal::real_ref(*const_cast<Scalar*>(&a)); }
+ EIGEN_DEVICE_FUNC
+ EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::real_ref(*const_cast<Scalar*>(&a)); }
};
template<typename Scalar>
struct functor_traits<scalar_real_ref_op<Scalar> >
@@ -408,7 +414,8 @@ template<typename Scalar>
struct scalar_imag_ref_op {
EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_ref_op)
typedef typename NumTraits<Scalar>::Real result_type;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return internal::imag_ref(*const_cast<Scalar*>(&a)); }
+ EIGEN_DEVICE_FUNC
+ EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::imag_ref(*const_cast<Scalar*>(&a)); }
};
template<typename Scalar>
struct functor_traits<scalar_imag_ref_op<Scalar> >
@@ -804,7 +811,8 @@ struct scalar_pow_op {
// FIXME default copy constructors seems bugged with std::complex<>
inline scalar_pow_op(const scalar_pow_op& other) : m_exponent(other.m_exponent) { }
inline scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {}
- EIGEN_DEVICE_FUNC inline Scalar operator() (const Scalar& a) const { return internal::pow(a, m_exponent); }
+ EIGEN_DEVICE_FUNC
+ inline Scalar operator() (const Scalar& a) const { return numext::pow(a, m_exponent); }
const Scalar m_exponent;
};
template<typename Scalar>
diff --git a/Eigen/src/Core/Fuzzy.h b/Eigen/src/Core/Fuzzy.h
index a7c91d302..f9a88dd3c 100644
--- a/Eigen/src/Core/Fuzzy.h
+++ b/Eigen/src/Core/Fuzzy.h
@@ -45,7 +45,7 @@ struct isMuchSmallerThan_object_selector
EIGEN_DEVICE_FUNC
static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar& prec)
{
- return x.cwiseAbs2().sum() <= abs2(prec) * y.cwiseAbs2().sum();
+ return x.cwiseAbs2().sum() <= numext::abs2(prec) * y.cwiseAbs2().sum();
}
};
@@ -65,7 +65,7 @@ struct isMuchSmallerThan_scalar_selector
EIGEN_DEVICE_FUNC
static bool run(const Derived& x, const typename Derived::RealScalar& y, const typename Derived::RealScalar& prec)
{
- return x.cwiseAbs2().sum() <= abs2(prec * y);
+ return x.cwiseAbs2().sum() <= numext::abs2(prec * y);
}
};
diff --git a/Eigen/src/Core/GeneralProduct.h b/Eigen/src/Core/GeneralProduct.h
index 557286003..9d7d18427 100644
--- a/Eigen/src/Core/GeneralProduct.h
+++ b/Eigen/src/Core/GeneralProduct.h
@@ -435,7 +435,7 @@ template<> struct gemv_selector<OnTheRight,ColMajor,true>
gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest;
- bool alphaIsCompatible = (!ComplexByReal) || (imag(actualAlpha)==RealScalar(0));
+ bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0));
bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
diff --git a/Eigen/src/Core/GenericPacketMath.h b/Eigen/src/Core/GenericPacketMath.h
index 17b7ae87d..b0469fa1e 100644
--- a/Eigen/src/Core/GenericPacketMath.h
+++ b/Eigen/src/Core/GenericPacketMath.h
@@ -105,8 +105,9 @@ template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
pnegate(const Packet& a) { return -a; }
/** \internal \returns conj(a) (coeff-wise) */
+
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-pconj(const Packet& a) { return conj(a); }
+pconj(const Packet& a) { return numext::conj(a); }
/** \internal \returns a * b (coeff-wise) */
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
diff --git a/Eigen/src/Core/GlobalFunctions.h b/Eigen/src/Core/GlobalFunctions.h
index 02cae552e..2acf97723 100644
--- a/Eigen/src/Core/GlobalFunctions.h
+++ b/Eigen/src/Core/GlobalFunctions.h
@@ -39,6 +39,7 @@ namespace Eigen
{
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(real,scalar_real_op)
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(imag,scalar_imag_op)
+ EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(conj,scalar_conjugate_op)
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sin,scalar_sin_op)
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cos,scalar_cos_op)
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(asin,scalar_asin_op)
@@ -86,6 +87,6 @@ namespace Eigen
}
}
-// TODO: cleanly disable those functions that are not supported on Array (internal::real_ref, internal::random, internal::isApprox...)
+// TODO: cleanly disable those functions that are not supported on Array (numext::real_ref, internal::random, internal::isApprox...)
#endif // EIGEN_GLOBAL_FUNCTIONS_H
diff --git a/Eigen/src/Core/IO.h b/Eigen/src/Core/IO.h
index 50bf93d9f..c8d5f6379 100644
--- a/Eigen/src/Core/IO.h
+++ b/Eigen/src/Core/IO.h
@@ -55,7 +55,7 @@ struct IOFormat
const std::string& _rowSeparator = "\n", const std::string& _rowPrefix="", const std::string& _rowSuffix="",
const std::string& _matPrefix="", const std::string& _matSuffix="")
: matPrefix(_matPrefix), matSuffix(_matSuffix), rowPrefix(_rowPrefix), rowSuffix(_rowSuffix), rowSeparator(_rowSeparator),
- coeffSeparator(_coeffSeparator), precision(_precision), flags(_flags)
+ rowSpacer(""), coeffSeparator(_coeffSeparator), precision(_precision), flags(_flags)
{
int i = int(matSuffix.length())-1;
while (i>=0 && matSuffix[i]!='\n')
diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h
index 9d3d7fbbb..2555d3a83 100644
--- a/Eigen/src/Core/MathFunctions.h
+++ b/Eigen/src/Core/MathFunctions.h
@@ -51,16 +51,15 @@ struct global_math_functions_filtering_base
typedef typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl type;
};
-#define EIGEN_MATHFUNC_IMPL(func, scalar) func##_impl<typename global_math_functions_filtering_base<scalar>::type>
-#define EIGEN_MATHFUNC_RETVAL(func, scalar) typename func##_retval<typename global_math_functions_filtering_base<scalar>::type>::type
-
+#define EIGEN_MATHFUNC_IMPL(func, scalar) Eigen::internal::func##_impl<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>
+#define EIGEN_MATHFUNC_RETVAL(func, scalar) typename Eigen::internal::func##_retval<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>::type
/****************************************************************************
* Implementation of real *
****************************************************************************/
-template<typename Scalar>
-struct real_impl
+template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
+struct real_default_impl
{
typedef typename NumTraits<Scalar>::Real RealScalar;
EIGEN_DEVICE_FUNC
@@ -70,36 +69,32 @@ struct real_impl
}
};
-template<typename RealScalar>
-struct real_impl<std::complex<RealScalar> >
+template<typename Scalar>
+struct real_default_impl<Scalar,true>
{
+ typedef typename NumTraits<Scalar>::Real RealScalar;
EIGEN_DEVICE_FUNC
- static inline RealScalar run(const std::complex<RealScalar>& x)
+ static inline RealScalar run(const Scalar& x)
{
using std::real;
return real(x);
}
};
+template<typename Scalar> struct real_impl : real_default_impl<Scalar> {};
+
template<typename Scalar>
struct real_retval
{
typedef typename NumTraits<Scalar>::Real type;
};
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
-{
- return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
-}
-
/****************************************************************************
* Implementation of imag *
****************************************************************************/
-template<typename Scalar>
-struct imag_impl
+template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
+struct imag_default_impl
{
typedef typename NumTraits<Scalar>::Real RealScalar;
EIGEN_DEVICE_FUNC
@@ -109,30 +104,26 @@ struct imag_impl
}
};
-template<typename RealScalar>
-struct imag_impl<std::complex<RealScalar> >
+template<typename Scalar>
+struct imag_default_impl<Scalar,true>
{
+ typedef typename NumTraits<Scalar>::Real RealScalar;
EIGEN_DEVICE_FUNC
- static inline RealScalar run(const std::complex<RealScalar>& x)
+ static inline RealScalar run(const Scalar& x)
{
using std::imag;
return imag(x);
}
};
+template<typename Scalar> struct imag_impl : imag_default_impl<Scalar> {};
+
template<typename Scalar>
struct imag_retval
{
typedef typename NumTraits<Scalar>::Real type;
};
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
-{
- return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
-}
-
/****************************************************************************
* Implementation of real_ref *
****************************************************************************/
@@ -159,20 +150,6 @@ struct real_ref_retval
typedef typename NumTraits<Scalar>::Real & type;
};
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline typename add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(const Scalar& x)
-{
- return real_ref_impl<Scalar>::run(x);
-}
-
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
-{
- return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
-}
-
/****************************************************************************
* Implementation of imag_ref *
****************************************************************************/
@@ -217,25 +194,11 @@ struct imag_ref_retval
typedef typename NumTraits<Scalar>::Real & type;
};
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline typename add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x)
-{
- return imag_ref_impl<Scalar>::run(x);
-}
-
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
-{
- return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
-}
-
/****************************************************************************
* Implementation of conj *
****************************************************************************/
-template<typename Scalar>
+template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
struct conj_impl
{
EIGEN_DEVICE_FUNC
@@ -245,11 +208,11 @@ struct conj_impl
}
};
-template<typename RealScalar>
-struct conj_impl<std::complex<RealScalar> >
+template<typename Scalar>
+struct conj_impl<Scalar,true>
{
EIGEN_DEVICE_FUNC
- static inline std::complex<RealScalar> run(const std::complex<RealScalar>& x)
+ static inline Scalar run(const Scalar& x)
{
using std::conj;
return conj(x);
@@ -262,13 +225,6 @@ struct conj_retval
typedef Scalar type;
};
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
-{
- return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
-}
-
/****************************************************************************
* Implementation of abs2 *
****************************************************************************/
@@ -300,13 +256,6 @@ struct abs2_retval
typedef typename NumTraits<Scalar>::Real type;
};
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
-{
- return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
-}
-
/****************************************************************************
* Implementation of norm1 *
****************************************************************************/
@@ -343,13 +292,6 @@ struct norm1_retval
typedef typename NumTraits<Scalar>::Real type;
};
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
-{
- return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
-}
-
/****************************************************************************
* Implementation of hypot *
****************************************************************************/
@@ -367,6 +309,7 @@ struct hypot_impl
RealScalar _x = abs(x);
RealScalar _y = abs(y);
RealScalar p = (max)(_x, _y);
+ if(p==RealScalar(0)) return 0;
RealScalar q = (min)(_x, _y);
RealScalar qp = q/p;
return p * sqrt(RealScalar(1) + qp*qp);
@@ -379,12 +322,6 @@ struct hypot_retval
typedef typename NumTraits<Scalar>::Real type;
};
-template<typename Scalar>
-inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y)
-{
- return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y);
-}
-
/****************************************************************************
* Implementation of cast *
****************************************************************************/
@@ -447,12 +384,6 @@ struct atanh2_retval
typedef Scalar type;
};
-template<typename Scalar>
-inline EIGEN_MATHFUNC_RETVAL(atanh2, Scalar) atanh2(const Scalar& x, const Scalar& y)
-{
- return EIGEN_MATHFUNC_IMPL(atanh2, Scalar)::run(x, y);
-}
-
/****************************************************************************
* Implementation of pow *
****************************************************************************/
@@ -496,12 +427,6 @@ struct pow_retval
typedef Scalar type;
};
-template<typename Scalar>
-inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y)
-{
- return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y);
-}
-
/****************************************************************************
* Implementation of random *
****************************************************************************/
@@ -600,11 +525,10 @@ struct random_default_impl<Scalar, false, true>
#else
enum { rand_bits = floor_log2<(unsigned int)(RAND_MAX)+1>::value,
scalar_bits = sizeof(Scalar) * CHAR_BIT,
- shift = EIGEN_PLAIN_ENUM_MAX(0, int(rand_bits) - int(scalar_bits))
+ shift = EIGEN_PLAIN_ENUM_MAX(0, int(rand_bits) - int(scalar_bits)),
+ offset = NumTraits<Scalar>::IsSigned ? (1 << (EIGEN_PLAIN_ENUM_MIN(rand_bits,scalar_bits)-1)) : 0
};
- Scalar x = Scalar(std::rand() >> shift);
- Scalar offset = NumTraits<Scalar>::IsSigned ? Scalar(1 << (rand_bits-1)) : Scalar(0);
- return x - offset;
+ return Scalar((std::rand() >> shift) - offset);
#endif
}
};
@@ -636,6 +560,111 @@ inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
return EIGEN_MATHFUNC_IMPL(random, Scalar)::run();
}
+} // end namespace internal
+
+/****************************************************************************
+* Generic math function *
+****************************************************************************/
+
+namespace numext {
+
+template<typename Scalar>
+EIGEN_DEVICE_FUNC
+inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
+{
+ return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
+}
+
+template<typename Scalar>
+EIGEN_DEVICE_FUNC
+inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(const Scalar& x)
+{
+ return internal::real_ref_impl<Scalar>::run(x);
+}
+
+template<typename Scalar>
+EIGEN_DEVICE_FUNC
+inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
+{
+ return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
+}
+
+template<typename Scalar>
+EIGEN_DEVICE_FUNC
+inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
+{
+ return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
+}
+
+template<typename Scalar>
+EIGEN_DEVICE_FUNC
+inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x)
+{
+ return internal::imag_ref_impl<Scalar>::run(x);
+}
+
+template<typename Scalar>
+EIGEN_DEVICE_FUNC
+inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
+{
+ return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
+}
+
+template<typename Scalar>
+EIGEN_DEVICE_FUNC
+inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
+{
+ return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
+}
+
+template<typename Scalar>
+EIGEN_DEVICE_FUNC
+inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
+{
+ return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
+}
+
+template<typename Scalar>
+EIGEN_DEVICE_FUNC
+inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
+{
+ return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
+}
+
+template<typename Scalar>
+EIGEN_DEVICE_FUNC
+inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y)
+{
+ return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y);
+}
+
+template<typename Scalar>
+EIGEN_DEVICE_FUNC
+inline EIGEN_MATHFUNC_RETVAL(atanh2, Scalar) atanh2(const Scalar& x, const Scalar& y)
+{
+ return EIGEN_MATHFUNC_IMPL(atanh2, Scalar)::run(x, y);
+}
+
+template<typename Scalar>
+EIGEN_DEVICE_FUNC
+inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y)
+{
+ return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y);
+}
+
+// std::isfinite is non standard, so let's define our own version,
+// even though it is not very efficient.
+template<typename T>
+EIGEN_DEVICE_FUNC
+bool (isfinite)(const T& x)
+{
+ return x<NumTraits<T>::highest() && x>NumTraits<T>::lowest();
+}
+
+} // end namespace numext
+
+namespace internal {
+
/****************************************************************************
* Implementation of fuzzy comparisons *
****************************************************************************/
@@ -697,12 +726,12 @@ struct scalar_fuzzy_default_impl<Scalar, true, false>
template<typename OtherScalar>
static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
{
- return abs2(x) <= abs2(y) * prec * prec;
+ return numext::abs2(x) <= numext::abs2(y) * prec * prec;
}
static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
{
EIGEN_USING_STD_MATH(min);
- return abs2(x - y) <= (min)(abs2(x), abs2(y)) * prec * prec;
+ return numext::abs2(x - y) <= (min)(numext::abs2(x), numext::abs2(y)) * prec * prec;
}
};
@@ -766,17 +795,7 @@ template<> struct scalar_fuzzy_impl<bool>
};
-/****************************************************************************
-* Special functions *
-****************************************************************************/
-
-// std::isfinite is non standard, so let's define our own version,
-// even though it is not very efficient.
-template<typename T> bool (isfinite)(const T& x)
-{
- return x<NumTraits<T>::highest() && x>NumTraits<T>::lowest();
-}
-
+
} // end namespace internal
} // end namespace Eigen
diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h
index 70c1857dd..8c3780ca2 100644
--- a/Eigen/src/Core/Matrix.h
+++ b/Eigen/src/Core/Matrix.h
@@ -205,7 +205,7 @@ class Matrix
* \sa resize(Index,Index)
*/
EIGEN_DEVICE_FUNC
- EIGEN_STRONG_INLINE explicit Matrix() : Base()
+ EIGEN_STRONG_INLINE Matrix() : Base()
{
Base::_check_template_params();
EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h
index 8dbe71b93..eed10de2d 100644
--- a/Eigen/src/Core/MatrixBase.h
+++ b/Eigen/src/Core/MatrixBase.h
@@ -232,8 +232,8 @@ template<typename Derived> class MatrixBase
typedef Diagonal<Derived> DiagonalReturnType;
DiagonalReturnType diagonal();
- typedef const Diagonal<const Derived> ConstDiagonalReturnType;
- const ConstDiagonalReturnType diagonal() const;
+ typedef typename internal::add_const<Diagonal<const Derived> >::type ConstDiagonalReturnType;
+ ConstDiagonalReturnType diagonal() const;
template<int Index> struct DiagonalIndexReturnType { typedef Diagonal<Derived,Index> Type; };
template<int Index> struct ConstDiagonalIndexReturnType { typedef const Diagonal<const Derived,Index> Type; };
diff --git a/Eigen/src/Core/NoAlias.h b/Eigen/src/Core/NoAlias.h
index 9e371538a..0a1c32743 100644
--- a/Eigen/src/Core/NoAlias.h
+++ b/Eigen/src/Core/NoAlias.h
@@ -86,6 +86,10 @@ class NoAlias
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE ExpressionType& operator-=(const CoeffBasedProduct<Lhs,Rhs,NestingFlags>& other)
{ return m_expression.derived() -= CoeffBasedProduct<Lhs,Rhs,NestByRefBit>(other.lhs(), other.rhs()); }
+
+ template<typename OtherDerived>
+ ExpressionType& operator=(const ReturnByValue<OtherDerived>& func)
+ { return m_expression = func; }
#endif
EIGEN_DEVICE_FUNC
diff --git a/Eigen/src/Core/PlainObjectBase.h b/Eigen/src/Core/PlainObjectBase.h
index 037242595..39d422f78 100644
--- a/Eigen/src/Core/PlainObjectBase.h
+++ b/Eigen/src/Core/PlainObjectBase.h
@@ -437,7 +437,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
}
EIGEN_DEVICE_FUNC
- EIGEN_STRONG_INLINE explicit PlainObjectBase() : m_storage()
+ EIGEN_STRONG_INLINE PlainObjectBase() : m_storage()
{
// _check_template_params();
// EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
diff --git a/Eigen/src/Core/ReturnByValue.h b/Eigen/src/Core/ReturnByValue.h
index 87c6d9194..7834f6cbc 100644
--- a/Eigen/src/Core/ReturnByValue.h
+++ b/Eigen/src/Core/ReturnByValue.h
@@ -48,7 +48,7 @@ struct nested<ReturnByValue<Derived>, n, PlainObject>
} // end namespace internal
template<typename Derived> class ReturnByValue
- : public internal::dense_xpr_base< ReturnByValue<Derived> >::type
+ : internal::no_assignment_operator, public internal::dense_xpr_base< ReturnByValue<Derived> >::type
{
public:
typedef typename internal::traits<Derived>::ReturnType ReturnType;
diff --git a/Eigen/src/Core/SelfAdjointView.h b/Eigen/src/Core/SelfAdjointView.h
index d43789123..6fa7cd15e 100644
--- a/Eigen/src/Core/SelfAdjointView.h
+++ b/Eigen/src/Core/SelfAdjointView.h
@@ -214,9 +214,9 @@ struct triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Upper), U
triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Upper), UnrollCount-1, ClearOpposite>::run(dst, src);
if(row == col)
- dst.coeffRef(row, col) = real(src.coeff(row, col));
+ dst.coeffRef(row, col) = numext::real(src.coeff(row, col));
else if(row < col)
- dst.coeffRef(col, row) = conj(dst.coeffRef(row, col) = src.coeff(row, col));
+ dst.coeffRef(col, row) = numext::conj(dst.coeffRef(row, col) = src.coeff(row, col));
}
};
@@ -239,9 +239,9 @@ struct triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Lower), U
triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Lower), UnrollCount-1, ClearOpposite>::run(dst, src);
if(row == col)
- dst.coeffRef(row, col) = real(src.coeff(row, col));
+ dst.coeffRef(row, col) = numext::real(src.coeff(row, col));
else if(row > col)
- dst.coeffRef(col, row) = conj(dst.coeffRef(row, col) = src.coeff(row, col));
+ dst.coeffRef(col, row) = numext::conj(dst.coeffRef(row, col) = src.coeff(row, col));
}
};
@@ -262,7 +262,7 @@ struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Upper, Dyn
for(Index i = 0; i < j; ++i)
{
dst.copyCoeff(i, j, src);
- dst.coeffRef(j,i) = conj(dst.coeff(i,j));
+ dst.coeffRef(j,i) = numext::conj(dst.coeff(i,j));
}
dst.copyCoeff(j, j, src);
}
@@ -280,7 +280,7 @@ struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Lower, Dyn
for(Index j = 0; j < i; ++j)
{
dst.copyCoeff(i, j, src);
- dst.coeffRef(j,i) = conj(dst.coeff(i,j));
+ dst.coeffRef(j,i) = numext::conj(dst.coeff(i,j));
}
dst.copyCoeff(i, i, src);
}
diff --git a/Eigen/src/Core/StableNorm.h b/Eigen/src/Core/StableNorm.h
index ea227c535..c219e2f53 100644
--- a/Eigen/src/Core/StableNorm.h
+++ b/Eigen/src/Core/StableNorm.h
@@ -20,7 +20,7 @@ inline void stable_norm_kernel(const ExpressionType& bl, Scalar& ssq, Scalar& sc
Scalar max = bl.cwiseAbs().maxCoeff();
if (max>scale)
{
- ssq = ssq * abs2(scale/max);
+ ssq = ssq * numext::abs2(scale/max);
scale = max;
invScale = Scalar(1)/scale;
}
@@ -84,9 +84,9 @@ blueNorm_impl(const EigenBase<Derived>& _vec)
for(typename Derived::InnerIterator it(vec, 0); it; ++it)
{
RealScalar ax = abs(it.value());
- if(ax > ab2) abig += internal::abs2(ax*s2m);
- else if(ax < b1) asml += internal::abs2(ax*s1m);
- else amed += internal::abs2(ax);
+ if(ax > ab2) abig += numext::abs2(ax*s2m);
+ else if(ax < b1) asml += numext::abs2(ax*s1m);
+ else amed += numext::abs2(ax);
}
if(abig > RealScalar(0))
{
@@ -120,7 +120,7 @@ blueNorm_impl(const EigenBase<Derived>& _vec)
if(asml <= abig*relerr)
return abig;
else
- return abig * sqrt(RealScalar(1) + internal::abs2(asml/abig));
+ return abig * sqrt(RealScalar(1) + numext::abs2(asml/abig));
}
} // end namespace internal
diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h
index 6c2da09cb..976708a0f 100644
--- a/Eigen/src/Core/Transpose.h
+++ b/Eigen/src/Core/Transpose.h
@@ -107,6 +107,7 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
typedef typename internal::TransposeImpl_base<MatrixType>::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>)
+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TransposeImpl)
EIGEN_DEVICE_FUNC inline Index innerStride() const { return derived().nestedExpression().innerStride(); }
EIGEN_DEVICE_FUNC inline Index outerStride() const { return derived().nestedExpression().outerStride(); }
@@ -215,7 +216,7 @@ DenseBase<Derived>::transpose()
*
* \sa transposeInPlace(), adjoint() */
template<typename Derived>
-inline const typename DenseBase<Derived>::ConstTransposeReturnType
+inline typename DenseBase<Derived>::ConstTransposeReturnType
DenseBase<Derived>::transpose() const
{
return ConstTransposeReturnType(derived());
@@ -261,7 +262,7 @@ struct inplace_transpose_selector;
template<typename MatrixType>
struct inplace_transpose_selector<MatrixType,true> { // square matrix
static void run(MatrixType& m) {
- m.template triangularView<StrictlyUpper>().swap(m.transpose());
+ m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose());
}
};
@@ -269,7 +270,7 @@ template<typename MatrixType>
struct inplace_transpose_selector<MatrixType,false> { // non square matrix
static void run(MatrixType& m) {
if (m.rows()==m.cols())
- m.template triangularView<StrictlyUpper>().swap(m.transpose());
+ m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose());
else
m = m.transpose().eval();
}
@@ -396,7 +397,7 @@ struct checkTransposeAliasing_impl
eigen_assert((!check_transpose_aliasing_run_time_selector
<typename Derived::Scalar,blas_traits<Derived>::IsTransposed,OtherDerived>
::run(extract_data(dst), other))
- && "aliasing detected during tranposition, use transposeInPlace() "
+ && "aliasing detected during transposition, use transposeInPlace() "
"or evaluate the rhs into a temporary using .eval()");
}
diff --git a/Eigen/src/Core/arch/AltiVec/PacketMath.h b/Eigen/src/Core/arch/AltiVec/PacketMath.h
index 75de19311..e4089962d 100644
--- a/Eigen/src/Core/arch/AltiVec/PacketMath.h
+++ b/Eigen/src/Core/arch/AltiVec/PacketMath.h
@@ -173,6 +173,9 @@ template<> EIGEN_STRONG_INLINE Packet4i psub<Packet4i>(const Packet4i& a, const
template<> EIGEN_STRONG_INLINE Packet4f pnegate(const Packet4f& a) { return psub<Packet4f>(p4f_ZERO, a); }
template<> EIGEN_STRONG_INLINE Packet4i pnegate(const Packet4i& a) { return psub<Packet4i>(p4i_ZERO, a); }
+template<> EIGEN_STRONG_INLINE Packet4f pconj(const Packet4f& a) { return a; }
+template<> EIGEN_STRONG_INLINE Packet4i pconj(const Packet4i& a) { return a; }
+
template<> EIGEN_STRONG_INLINE Packet4f pmul<Packet4f>(const Packet4f& a, const Packet4f& b) { return vec_madd(a,b,p4f_ZERO); }
/* Commented out: it's actually slower than processing it scalar
*
diff --git a/Eigen/src/Core/arch/NEON/Complex.h b/Eigen/src/Core/arch/NEON/Complex.h
index 795b4be73..f183d31de 100644
--- a/Eigen/src/Core/arch/NEON/Complex.h
+++ b/Eigen/src/Core/arch/NEON/Complex.h
@@ -68,7 +68,6 @@ template<> EIGEN_STRONG_INLINE Packet2cf pconj(const Packet2cf& a)
template<> EIGEN_STRONG_INLINE Packet2cf pmul<Packet2cf>(const Packet2cf& a, const Packet2cf& b)
{
Packet4f v1, v2;
- float32x2_t a_lo, a_hi;
// Get the real values of a | a1_re | a1_re | a2_re | a2_re |
v1 = vcombine_f32(vdup_lane_f32(vget_low_f32(a.v), 0), vdup_lane_f32(vget_high_f32(a.v), 0));
@@ -81,9 +80,7 @@ template<> EIGEN_STRONG_INLINE Packet2cf pmul<Packet2cf>(const Packet2cf& a, con
// Conjugate v2
v2 = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(v2), p4ui_CONJ_XOR));
// Swap real/imag elements in v2.
- a_lo = vrev64_f32(vget_low_f32(v2));
- a_hi = vrev64_f32(vget_high_f32(v2));
- v2 = vcombine_f32(a_lo, a_hi);
+ v2 = vrev64q_f32(v2);
// Add and return the result
return Packet2cf(vaddq_f32(v1, v2));
}
@@ -241,13 +238,10 @@ template<> EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, con
// TODO optimize it for AltiVec
Packet2cf res = conj_helper<Packet2cf,Packet2cf,false,true>().pmul(a,b);
Packet4f s, rev_s;
- float32x2_t a_lo, a_hi;
// this computes the norm
s = vmulq_f32(b.v, b.v);
- a_lo = vrev64_f32(vget_low_f32(s));
- a_hi = vrev64_f32(vget_high_f32(s));
- rev_s = vcombine_f32(a_lo, a_hi);
+ rev_s = vrev64q_f32(s);
return Packet2cf(pdiv(res.v, vaddq_f32(s,rev_s)));
}
diff --git a/Eigen/src/Core/arch/NEON/PacketMath.h b/Eigen/src/Core/arch/NEON/PacketMath.h
index 2662e2ebf..163bac215 100644
--- a/Eigen/src/Core/arch/NEON/PacketMath.h
+++ b/Eigen/src/Core/arch/NEON/PacketMath.h
@@ -115,6 +115,9 @@ template<> EIGEN_STRONG_INLINE Packet4i psub<Packet4i>(const Packet4i& a, const
template<> EIGEN_STRONG_INLINE Packet4f pnegate(const Packet4f& a) { return vnegq_f32(a); }
template<> EIGEN_STRONG_INLINE Packet4i pnegate(const Packet4i& a) { return vnegq_s32(a); }
+template<> EIGEN_STRONG_INLINE Packet4f pconj(const Packet4f& a) { return a; }
+template<> EIGEN_STRONG_INLINE Packet4i pconj(const Packet4i& a) { return a; }
+
template<> EIGEN_STRONG_INLINE Packet4f pmul<Packet4f>(const Packet4f& a, const Packet4f& b) { return vmulq_f32(a,b); }
template<> EIGEN_STRONG_INLINE Packet4i pmul<Packet4i>(const Packet4i& a, const Packet4i& b) { return vmulq_s32(a,b); }
@@ -188,15 +191,15 @@ template<> EIGEN_STRONG_INLINE Packet4i ploadu<Packet4i>(const int* from) { EI
template<> EIGEN_STRONG_INLINE Packet4f ploaddup<Packet4f>(const float* from)
{
float32x2_t lo, hi;
- lo = vdup_n_f32(*from);
- hi = vdup_n_f32(*(from+1));
+ lo = vld1_dup_f32(from);
+ hi = vld1_dup_f32(from+1);
return vcombine_f32(lo, hi);
}
template<> EIGEN_STRONG_INLINE Packet4i ploaddup<Packet4i>(const int* from)
{
int32x2_t lo, hi;
- lo = vdup_n_s32(*from);
- hi = vdup_n_s32(*(from+1));
+ lo = vld1_dup_s32(from);
+ hi = vld1_dup_s32(from+1);
return vcombine_s32(lo, hi);
}
diff --git a/Eigen/src/Core/arch/SSE/Complex.h b/Eigen/src/Core/arch/SSE/Complex.h
index bd76d75ed..91bba5e38 100644
--- a/Eigen/src/Core/arch/SSE/Complex.h
+++ b/Eigen/src/Core/arch/SSE/Complex.h
@@ -81,8 +81,8 @@ template<> EIGEN_STRONG_INLINE Packet2cf por <Packet2cf>(const Packet2cf& a,
template<> EIGEN_STRONG_INLINE Packet2cf pxor <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_xor_ps(a.v,b.v)); }
template<> EIGEN_STRONG_INLINE Packet2cf pandnot<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_andnot_ps(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet2cf pload <Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload<Packet4f>(&real_ref(*from))); }
-template<> EIGEN_STRONG_INLINE Packet2cf ploadu<Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu<Packet4f>(&real_ref(*from))); }
+template<> EIGEN_STRONG_INLINE Packet2cf pload <Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload<Packet4f>(&numext::real_ref(*from))); }
+template<> EIGEN_STRONG_INLINE Packet2cf ploadu<Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu<Packet4f>(&numext::real_ref(*from))); }
template<> EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<float>& from)
{
@@ -104,8 +104,8 @@ template<> EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<flo
template<> EIGEN_STRONG_INLINE Packet2cf ploaddup<Packet2cf>(const std::complex<float>* from) { return pset1<Packet2cf>(*from); }
-template<> EIGEN_STRONG_INLINE void pstore <std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore(&real_ref(*to), from.v); }
-template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu(&real_ref(*to), from.v); }
+template<> EIGEN_STRONG_INLINE void pstore <std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore(&numext::real_ref(*to), from.v); }
+template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu(&numext::real_ref(*to), from.v); }
template<> EIGEN_STRONG_INLINE void prefetch<std::complex<float> >(const std::complex<float> * addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
diff --git a/Eigen/src/Core/arch/SSE/MathFunctions.h b/Eigen/src/Core/arch/SSE/MathFunctions.h
index 5ede55fba..3376a984e 100644
--- a/Eigen/src/Core/arch/SSE/MathFunctions.h
+++ b/Eigen/src/Core/arch/SSE/MathFunctions.h
@@ -450,7 +450,7 @@ Packet4f psqrt<Packet4f>(const Packet4f& _x)
Packet4f half = pmul(_x, pset1<Packet4f>(.5f));
/* select only the inverse sqrt of non-zero inputs */
- Packet4f non_zero_mask = _mm_cmpgt_ps(_x, pset1<Packet4f>(std::numeric_limits<float>::epsilon()));
+ Packet4f non_zero_mask = _mm_cmpge_ps(_x, pset1<Packet4f>((std::numeric_limits<float>::min)()));
Packet4f x = _mm_and_ps(non_zero_mask, _mm_rsqrt_ps(_x));
x = pmul(x, psub(pset1<Packet4f>(1.5f), pmul(half, pmul(x,x))));
diff --git a/Eigen/src/Core/arch/SSE/PacketMath.h b/Eigen/src/Core/arch/SSE/PacketMath.h
index addb2fc0e..e256f4bac 100644
--- a/Eigen/src/Core/arch/SSE/PacketMath.h
+++ b/Eigen/src/Core/arch/SSE/PacketMath.h
@@ -141,6 +141,10 @@ template<> EIGEN_STRONG_INLINE Packet4i pnegate(const Packet4i& a)
return psub(_mm_setr_epi32(0,0,0,0), a);
}
+template<> EIGEN_STRONG_INLINE Packet4f pconj(const Packet4f& a) { return a; }
+template<> EIGEN_STRONG_INLINE Packet2d pconj(const Packet2d& a) { return a; }
+template<> EIGEN_STRONG_INLINE Packet4i pconj(const Packet4i& a) { return a; }
+
template<> EIGEN_STRONG_INLINE Packet4f pmul<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_mul_ps(a,b); }
template<> EIGEN_STRONG_INLINE Packet2d pmul<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_mul_pd(a,b); }
template<> EIGEN_STRONG_INLINE Packet4i pmul<Packet4i>(const Packet4i& a, const Packet4i& b)
diff --git a/Eigen/src/Core/products/GeneralMatrixVector.h b/Eigen/src/Core/products/GeneralMatrixVector.h
index 9bdd588df..c1cb78498 100644
--- a/Eigen/src/Core/products/GeneralMatrixVector.h
+++ b/Eigen/src/Core/products/GeneralMatrixVector.h
@@ -86,7 +86,7 @@ EIGEN_DONT_INLINE void general_matrix_vector_product<Index,LhsScalar,ColMajor,Co
conj_helper<LhsScalar,RhsScalar,ConjugateLhs,ConjugateRhs> cj;
conj_helper<LhsPacket,RhsPacket,ConjugateLhs,ConjugateRhs> pcj;
if(ConjugateRhs)
- alpha = conj(alpha);
+ alpha = numext::conj(alpha);
enum { AllAligned = 0, EvenAligned, FirstAligned, NoneAligned };
const Index columnsAtOnce = 4;
diff --git a/Eigen/src/Core/products/SelfadjointMatrixMatrix.h b/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
index ee619df99..99cf9e0ae 100644
--- a/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
+++ b/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
@@ -30,9 +30,9 @@ struct symm_pack_lhs
for(Index k=i; k<i+BlockRows; k++)
{
for(Index w=0; w<h; w++)
- blockA[count++] = conj(lhs(k, i+w)); // transposed
+ blockA[count++] = numext::conj(lhs(k, i+w)); // transposed
- blockA[count++] = real(lhs(k,k)); // real (diagonal)
+ blockA[count++] = numext::real(lhs(k,k)); // real (diagonal)
for(Index w=h+1; w<BlockRows; w++)
blockA[count++] = lhs(i+w, k); // normal
@@ -41,7 +41,7 @@ struct symm_pack_lhs
// transposed copy
for(Index k=i+BlockRows; k<cols; k++)
for(Index w=0; w<BlockRows; w++)
- blockA[count++] = conj(lhs(k, i+w)); // transposed
+ blockA[count++] = numext::conj(lhs(k, i+w)); // transposed
}
void operator()(Scalar* blockA, const Scalar* _lhs, Index lhsStride, Index cols, Index rows)
{
@@ -65,10 +65,10 @@ struct symm_pack_lhs
for(Index k=0; k<i; k++)
blockA[count++] = lhs(i, k); // normal
- blockA[count++] = real(lhs(i, i)); // real (diagonal)
+ blockA[count++] = numext::real(lhs(i, i)); // real (diagonal)
for(Index k=i+1; k<cols; k++)
- blockA[count++] = conj(lhs(k, i)); // transposed
+ blockA[count++] = numext::conj(lhs(k, i)); // transposed
}
}
};
@@ -107,12 +107,12 @@ struct symm_pack_rhs
// transpose
for(Index k=k2; k<j2; k++)
{
- blockB[count+0] = conj(rhs(j2+0,k));
- blockB[count+1] = conj(rhs(j2+1,k));
+ blockB[count+0] = numext::conj(rhs(j2+0,k));
+ blockB[count+1] = numext::conj(rhs(j2+1,k));
if (nr==4)
{
- blockB[count+2] = conj(rhs(j2+2,k));
- blockB[count+3] = conj(rhs(j2+3,k));
+ blockB[count+2] = numext::conj(rhs(j2+2,k));
+ blockB[count+3] = numext::conj(rhs(j2+3,k));
}
count += nr;
}
@@ -124,11 +124,11 @@ struct symm_pack_rhs
for (Index w=0 ; w<h; ++w)
blockB[count+w] = rhs(k,j2+w);
- blockB[count+h] = real(rhs(k,k));
+ blockB[count+h] = numext::real(rhs(k,k));
// transpose
for (Index w=h+1 ; w<nr; ++w)
- blockB[count+w] = conj(rhs(j2+w,k));
+ blockB[count+w] = numext::conj(rhs(j2+w,k));
count += nr;
++h;
}
@@ -151,12 +151,12 @@ struct symm_pack_rhs
{
for(Index k=k2; k<end_k; k++)
{
- blockB[count+0] = conj(rhs(j2+0,k));
- blockB[count+1] = conj(rhs(j2+1,k));
+ blockB[count+0] = numext::conj(rhs(j2+0,k));
+ blockB[count+1] = numext::conj(rhs(j2+1,k));
if (nr==4)
{
- blockB[count+2] = conj(rhs(j2+2,k));
- blockB[count+3] = conj(rhs(j2+3,k));
+ blockB[count+2] = numext::conj(rhs(j2+2,k));
+ blockB[count+3] = numext::conj(rhs(j2+3,k));
}
count += nr;
}
@@ -169,13 +169,13 @@ struct symm_pack_rhs
Index half = (std::min)(end_k,j2);
for(Index k=k2; k<half; k++)
{
- blockB[count] = conj(rhs(j2,k));
+ blockB[count] = numext::conj(rhs(j2,k));
count += 1;
}
if(half==j2 && half<k2+rows)
{
- blockB[count] = real(rhs(j2,j2));
+ blockB[count] = numext::real(rhs(j2,j2));
count += 1;
}
else
diff --git a/Eigen/src/Core/products/SelfadjointMatrixVector.h b/Eigen/src/Core/products/SelfadjointMatrixVector.h
index f70f4894c..c40e80f53 100644
--- a/Eigen/src/Core/products/SelfadjointMatrixVector.h
+++ b/Eigen/src/Core/products/SelfadjointMatrixVector.h
@@ -59,7 +59,7 @@ EIGEN_DONT_INLINE void selfadjoint_matrix_vector_product<Scalar,Index,StorageOrd
conj_helper<Packet,Packet,NumTraits<Scalar>::IsComplex && EIGEN_LOGICAL_XOR(ConjugateLhs, IsRowMajor), ConjugateRhs> pcj0;
conj_helper<Packet,Packet,NumTraits<Scalar>::IsComplex && EIGEN_LOGICAL_XOR(ConjugateLhs, !IsRowMajor), ConjugateRhs> pcj1;
- Scalar cjAlpha = ConjugateRhs ? conj(alpha) : alpha;
+ Scalar cjAlpha = ConjugateRhs ? numext::conj(alpha) : alpha;
// FIXME this copy is now handled outside product_selfadjoint_vector, so it could probably be removed.
// if the rhs is not sequentially stored in memory we copy it to a temporary buffer,
@@ -98,8 +98,8 @@ EIGEN_DONT_INLINE void selfadjoint_matrix_vector_product<Scalar,Index,StorageOrd
size_t alignedEnd = alignedStart + ((endi-alignedStart)/(PacketSize))*(PacketSize);
// TODO make sure this product is a real * complex and that the rhs is properly conjugated if needed
- res[j] += cjd.pmul(internal::real(A0[j]), t0);
- res[j+1] += cjd.pmul(internal::real(A1[j+1]), t1);
+ res[j] += cjd.pmul(numext::real(A0[j]), t0);
+ res[j+1] += cjd.pmul(numext::real(A1[j+1]), t1);
if(FirstTriangular)
{
res[j] += cj0.pmul(A1[j], t1);
@@ -114,8 +114,8 @@ EIGEN_DONT_INLINE void selfadjoint_matrix_vector_product<Scalar,Index,StorageOrd
for (size_t i=starti; i<alignedStart; ++i)
{
res[i] += t0 * A0[i] + t1 * A1[i];
- t2 += conj(A0[i]) * rhs[i];
- t3 += conj(A1[i]) * rhs[i];
+ t2 += numext::conj(A0[i]) * rhs[i];
+ t3 += numext::conj(A1[i]) * rhs[i];
}
// Yes this an optimization for gcc 4.3 and 4.4 (=> huge speed up)
// gcc 4.2 does this optimization automatically.
@@ -152,7 +152,7 @@ EIGEN_DONT_INLINE void selfadjoint_matrix_vector_product<Scalar,Index,StorageOrd
Scalar t1 = cjAlpha * rhs[j];
Scalar t2(0);
// TODO make sure this product is a real * complex and that the rhs is properly conjugated if needed
- res[j] += cjd.pmul(internal::real(A0[j]), t1);
+ res[j] += cjd.pmul(numext::real(A0[j]), t1);
for (Index i=FirstTriangular ? 0 : j+1; i<(FirstTriangular ? j : size); i++)
{
res[i] += cj0.pmul(A0[i], t1);
diff --git a/Eigen/src/Core/products/SelfadjointRank2Update.h b/Eigen/src/Core/products/SelfadjointRank2Update.h
index 4b57f189d..8594a97ce 100644
--- a/Eigen/src/Core/products/SelfadjointRank2Update.h
+++ b/Eigen/src/Core/products/SelfadjointRank2Update.h
@@ -30,8 +30,8 @@ struct selfadjoint_rank2_update_selector<Scalar,Index,UType,VType,Lower>
for (Index i=0; i<size; ++i)
{
Map<Matrix<Scalar,Dynamic,1> >(mat+stride*i+i, size-i) +=
- (conj(alpha) * conj(u.coeff(i))) * v.tail(size-i)
- + (alpha * conj(v.coeff(i))) * u.tail(size-i);
+ (numext::conj(alpha) * numext::conj(u.coeff(i))) * v.tail(size-i)
+ + (alpha * numext::conj(v.coeff(i))) * u.tail(size-i);
}
}
};
@@ -44,8 +44,8 @@ struct selfadjoint_rank2_update_selector<Scalar,Index,UType,VType,Upper>
const Index size = u.size();
for (Index i=0; i<size; ++i)
Map<Matrix<Scalar,Dynamic,1> >(mat+stride*i, i+1) +=
- (conj(alpha) * conj(u.coeff(i))) * v.head(i+1)
- + (alpha * conj(v.coeff(i))) * u.head(i+1);
+ (numext::conj(alpha) * numext::conj(u.coeff(i))) * v.head(i+1)
+ + (alpha * numext::conj(v.coeff(i))) * u.head(i+1);
}
};
@@ -75,9 +75,9 @@ SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo>
enum { IsRowMajor = (internal::traits<MatrixType>::Flags&RowMajorBit) ? 1 : 0 };
Scalar actualAlpha = alpha * UBlasTraits::extractScalarFactor(u.derived())
- * internal::conj(VBlasTraits::extractScalarFactor(v.derived()));
+ * numext::conj(VBlasTraits::extractScalarFactor(v.derived()));
if (IsRowMajor)
- actualAlpha = internal::conj(actualAlpha);
+ actualAlpha = numext::conj(actualAlpha);
internal::selfadjoint_rank2_update_selector<Scalar, Index,
typename internal::remove_all<typename internal::conj_expr_if<IsRowMajor ^ UBlasTraits::NeedToConjugate,_ActualUType>::type>::type,
diff --git a/Eigen/src/Core/products/TriangularMatrixVector.h b/Eigen/src/Core/products/TriangularMatrixVector.h
index c8b7d28c4..6117d5a82 100644
--- a/Eigen/src/Core/products/TriangularMatrixVector.h
+++ b/Eigen/src/Core/products/TriangularMatrixVector.h
@@ -245,7 +245,7 @@ template<> struct trmv_selector<ColMajor>
gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest;
- bool alphaIsCompatible = (!ComplexByReal) || (imag(actualAlpha)==RealScalar(0));
+ bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0));
bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
diff --git a/Eigen/src/Core/util/BlasUtil.h b/Eigen/src/Core/util/BlasUtil.h
index a4026376e..0d8e2705a 100644
--- a/Eigen/src/Core/util/BlasUtil.h
+++ b/Eigen/src/Core/util/BlasUtil.h
@@ -42,7 +42,7 @@ template<bool Conjugate> struct conj_if;
template<> struct conj_if<true> {
template<typename T>
- inline T operator()(const T& x) { return conj(x); }
+ inline T operator()(const T& x) { return numext::conj(x); }
template<typename T>
inline T pconj(const T& x) { return internal::pconj(x); }
};
@@ -67,7 +67,7 @@ template<typename RealScalar> struct conj_helper<std::complex<RealScalar>, std::
{ return c + pmul(x,y); }
EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const
- { return Scalar(real(x)*real(y) + imag(x)*imag(y), imag(x)*real(y) - real(x)*imag(y)); }
+ { return Scalar(numext::real(x)*numext::real(y) + numext::imag(x)*numext::imag(y), numext::imag(x)*numext::real(y) - numext::real(x)*numext::imag(y)); }
};
template<typename RealScalar> struct conj_helper<std::complex<RealScalar>, std::complex<RealScalar>, true,false>
@@ -77,7 +77,7 @@ template<typename RealScalar> struct conj_helper<std::complex<RealScalar>, std::
{ return c + pmul(x,y); }
EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const
- { return Scalar(real(x)*real(y) + imag(x)*imag(y), real(x)*imag(y) - imag(x)*real(y)); }
+ { return Scalar(numext::real(x)*numext::real(y) + numext::imag(x)*numext::imag(y), numext::real(x)*numext::imag(y) - numext::imag(x)*numext::real(y)); }
};
template<typename RealScalar> struct conj_helper<std::complex<RealScalar>, std::complex<RealScalar>, true,true>
@@ -87,7 +87,7 @@ template<typename RealScalar> struct conj_helper<std::complex<RealScalar>, std::
{ return c + pmul(x,y); }
EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const
- { return Scalar(real(x)*real(y) - imag(x)*imag(y), - real(x)*imag(y) - imag(x)*real(y)); }
+ { return Scalar(numext::real(x)*numext::real(y) - numext::imag(x)*numext::imag(y), - numext::real(x)*numext::imag(y) - numext::imag(x)*numext::real(y)); }
};
template<typename RealScalar,bool Conj> struct conj_helper<std::complex<RealScalar>, RealScalar, Conj,false>
@@ -113,7 +113,8 @@ template<typename From,typename To> struct get_factor {
};
template<typename Scalar> struct get_factor<Scalar,typename NumTraits<Scalar>::Real> {
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE typename NumTraits<Scalar>::Real run(const Scalar& x) { return real(x); }
+ EIGEN_DEVICE_FUNC
+ static EIGEN_STRONG_INLINE typename NumTraits<Scalar>::Real run(const Scalar& x) { return numext::real(x); }
};
// Lightweight helper class to access matrix coefficients.
diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h
index 90fee79c5..6e1f4df6c 100644
--- a/Eigen/src/Core/util/Macros.h
+++ b/Eigen/src/Core/util/Macros.h
@@ -12,8 +12,8 @@
#define EIGEN_MACROS_H
#define EIGEN_WORLD_VERSION 3
-#define EIGEN_MAJOR_VERSION 1
-#define EIGEN_MINOR_VERSION 91
+#define EIGEN_MAJOR_VERSION 2
+#define EIGEN_MINOR_VERSION 90
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
@@ -240,10 +240,12 @@
// Suppresses 'unused variable' warnings.
#define EIGEN_UNUSED_VARIABLE(var) (void)var;
-#if !defined(EIGEN_ASM_COMMENT) && (defined __GNUC__)
-#define EIGEN_ASM_COMMENT(X) asm("#" X)
-#else
-#define EIGEN_ASM_COMMENT(X)
+#if !defined(EIGEN_ASM_COMMENT)
+ #if (defined __GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
+ #define EIGEN_ASM_COMMENT(X) asm("#" X)
+ #else
+ #define EIGEN_ASM_COMMENT(X)
+ #endif
#endif
/* EIGEN_ALIGN_TO_BOUNDARY(n) forces data to be n-byte aligned. This is used to satisfy SIMD requirements.
diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h
index 3ca666fd9..451535a0c 100644
--- a/Eigen/src/Core/util/Memory.h
+++ b/Eigen/src/Core/util/Memory.h
@@ -58,10 +58,17 @@
#endif
-#if ((defined __QNXNTO__) || (defined _GNU_SOURCE) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) \
- && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0)
- #define EIGEN_HAS_POSIX_MEMALIGN 1
-#else
+// See bug 554 (http://eigen.tuxfamily.org/bz/show_bug.cgi?id=554)
+// It seems to be unsafe to check _POSIX_ADVISORY_INFO without including unistd.h first.
+// Currently, let's include it only on unix systems:
+#if defined(__unix__) || defined(__unix)
+ #include <unistd.h>
+ #if ((defined __QNXNTO__) || (defined _GNU_SOURCE) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0)
+ #define EIGEN_HAS_POSIX_MEMALIGN 1
+ #endif
+#endif
+
+#ifndef EIGEN_HAS_POSIX_MEMALIGN
#define EIGEN_HAS_POSIX_MEMALIGN 0
#endif
@@ -215,7 +222,7 @@ inline void* aligned_malloc(size_t size)
if(posix_memalign(&result, 16, size)) result = 0;
#elif EIGEN_HAS_MM_MALLOC
result = _mm_malloc(size, 16);
-#elif defined(_MSC_VER) && (!defined(_WIN32_WCE))
+ #elif defined(_MSC_VER) && (!defined(_WIN32_WCE))
result = _aligned_malloc(size, 16);
#else
result = handmade_aligned_malloc(size);
diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h
index f115d3779..6a3884922 100644
--- a/Eigen/src/Core/util/XprHelper.h
+++ b/Eigen/src/Core/util/XprHelper.h
@@ -91,7 +91,8 @@ template<typename T> struct functor_traits
enum
{
Cost = 10,
- PacketAccess = false
+ PacketAccess = false,
+ IsRepeatable = false
};
};
diff --git a/Eigen/src/Eigen2Support/Geometry/AlignedBox.h b/Eigen/src/Eigen2Support/Geometry/AlignedBox.h
index 7b2b865eb..2e4309dd9 100644
--- a/Eigen/src/Eigen2Support/Geometry/AlignedBox.h
+++ b/Eigen/src/Eigen2Support/Geometry/AlignedBox.h
@@ -34,7 +34,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim==
typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType;
/** Default constructor initializing a null box. */
- inline explicit AlignedBox()
+ inline AlignedBox()
{ if (AmbientDimAtCompileTime!=Dynamic) setNull(); }
/** Constructs a null box with \a _dim the dimension of the ambient space. */
diff --git a/Eigen/src/Eigen2Support/Geometry/Hyperplane.h b/Eigen/src/Eigen2Support/Geometry/Hyperplane.h
index 49e37392d..b95bf00ec 100644
--- a/Eigen/src/Eigen2Support/Geometry/Hyperplane.h
+++ b/Eigen/src/Eigen2Support/Geometry/Hyperplane.h
@@ -44,7 +44,7 @@ public:
typedef Block<Coefficients,AmbientDimAtCompileTime,1> NormalReturnType;
/** Default constructor without initialization */
- inline explicit Hyperplane() {}
+ inline Hyperplane() {}
/** Constructs a dynamic-size hyperplane with \a _dim the dimension
* of the ambient space */
diff --git a/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h b/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h
index 3523611ee..9b57b7e0b 100644
--- a/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h
+++ b/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h
@@ -36,7 +36,7 @@ public:
typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType;
/** Default constructor without initialization */
- inline explicit ParametrizedLine() {}
+ inline ParametrizedLine() {}
/** Constructs a dynamic-size line with \a _dim the dimension
* of the ambient space */
diff --git a/Eigen/src/Eigen2Support/MathFunctions.h b/Eigen/src/Eigen2Support/MathFunctions.h
index bde5dd441..3544af253 100644
--- a/Eigen/src/Eigen2Support/MathFunctions.h
+++ b/Eigen/src/Eigen2Support/MathFunctions.h
@@ -12,18 +12,18 @@
namespace Eigen {
-template<typename T> inline typename NumTraits<T>::Real ei_real(const T& x) { return internal::real(x); }
-template<typename T> inline typename NumTraits<T>::Real ei_imag(const T& x) { return internal::imag(x); }
-template<typename T> inline T ei_conj(const T& x) { return internal::conj(x); }
+template<typename T> inline typename NumTraits<T>::Real ei_real(const T& x) { return numext::real(x); }
+template<typename T> inline typename NumTraits<T>::Real ei_imag(const T& x) { return numext::imag(x); }
+template<typename T> inline T ei_conj(const T& x) { return numext::conj(x); }
template<typename T> inline typename NumTraits<T>::Real ei_abs (const T& x) { using std::abs; return abs(x); }
-template<typename T> inline typename NumTraits<T>::Real ei_abs2(const T& x) { return internal::abs2(x); }
+template<typename T> inline typename NumTraits<T>::Real ei_abs2(const T& x) { return numext::abs2(x); }
template<typename T> inline T ei_sqrt(const T& x) { using std::sqrt; return sqrt(x); }
template<typename T> inline T ei_exp (const T& x) { using std::exp; return exp(x); }
template<typename T> inline T ei_log (const T& x) { using std::log; return log(x); }
template<typename T> inline T ei_sin (const T& x) { using std::sin; return sin(x); }
template<typename T> inline T ei_cos (const T& x) { using std::cos; return cos(x); }
template<typename T> inline T ei_atan2(const T& x,const T& y) { using std::atan2; return atan2(x,y); }
-template<typename T> inline T ei_pow (const T& x,const T& y) { return internal::pow(x,y); }
+template<typename T> inline T ei_pow (const T& x,const T& y) { return numext::pow(x,y); }
template<typename T> inline T ei_random () { return internal::random<T>(); }
template<typename T> inline T ei_random (const T& x, const T& y) { return internal::random(x, y); }
diff --git a/Eigen/src/Eigen2Support/SVD.h b/Eigen/src/Eigen2Support/SVD.h
index a08b695a4..077d26d54 100644
--- a/Eigen/src/Eigen2Support/SVD.h
+++ b/Eigen/src/Eigen2Support/SVD.h
@@ -315,7 +315,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
e[p-2] = 0.0;
for (j = p-2; j >= k; --j)
{
- Scalar t(internal::hypot(m_sigma[j],f));
+ Scalar t(numext::hypot(m_sigma[j],f));
Scalar cs(m_sigma[j]/t);
Scalar sn(f/t);
m_sigma[j] = t;
@@ -344,7 +344,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
e[k-1] = 0.0;
for (j = k; j < p; ++j)
{
- Scalar t(internal::hypot(m_sigma[j],f));
+ Scalar t(numext::hypot(m_sigma[j],f));
Scalar cs( m_sigma[j]/t);
Scalar sn(f/t);
m_sigma[j] = t;
@@ -392,7 +392,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
for (j = k; j < p-1; ++j)
{
- Scalar t = internal::hypot(f,g);
+ Scalar t = numext::hypot(f,g);
Scalar cs = f/t;
Scalar sn = g/t;
if (j != k)
@@ -410,7 +410,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
m_matV(i,j) = t;
}
}
- t = internal::hypot(f,g);
+ t = numext::hypot(f,g);
cs = f/t;
sn = g/t;
m_sigma[j] = t;
diff --git a/Eigen/src/Eigenvalues/ComplexEigenSolver.h b/Eigen/src/Eigenvalues/ComplexEigenSolver.h
index bd41bf7ed..af434bc9b 100644
--- a/Eigen/src/Eigenvalues/ComplexEigenSolver.h
+++ b/Eigen/src/Eigenvalues/ComplexEigenSolver.h
@@ -294,7 +294,7 @@ void ComplexEigenSolver<MatrixType>::doComputeEigenvectors(const RealScalar& mat
{
// If the i-th and k-th eigenvalue are equal, then z equals 0.
// Use a small value instead, to prevent division by zero.
- internal::real_ref(z) = NumTraits<RealScalar>::epsilon() * matrixnorm;
+ numext::real_ref(z) = NumTraits<RealScalar>::epsilon() * matrixnorm;
}
m_matX.coeffRef(i,k) = m_matX.coeff(i,k) / z;
}
diff --git a/Eigen/src/Eigenvalues/ComplexSchur.h b/Eigen/src/Eigenvalues/ComplexSchur.h
index 62b57ff66..89e6cade3 100644
--- a/Eigen/src/Eigenvalues/ComplexSchur.h
+++ b/Eigen/src/Eigenvalues/ComplexSchur.h
@@ -263,8 +263,8 @@ template<typename _MatrixType> class ComplexSchur
template<typename MatrixType>
inline bool ComplexSchur<MatrixType>::subdiagonalEntryIsNeglegible(Index i)
{
- RealScalar d = internal::norm1(m_matT.coeff(i,i)) + internal::norm1(m_matT.coeff(i+1,i+1));
- RealScalar sd = internal::norm1(m_matT.coeff(i+1,i));
+ RealScalar d = numext::norm1(m_matT.coeff(i,i)) + numext::norm1(m_matT.coeff(i+1,i+1));
+ RealScalar sd = numext::norm1(m_matT.coeff(i+1,i));
if (internal::isMuchSmallerThan(sd, d, NumTraits<RealScalar>::epsilon()))
{
m_matT.coeffRef(i+1,i) = ComplexScalar(0);
@@ -282,7 +282,7 @@ typename ComplexSchur<MatrixType>::ComplexScalar ComplexSchur<MatrixType>::compu
if (iter == 10 || iter == 20)
{
// exceptional shift, taken from http://www.netlib.org/eispack/comqr.f
- return abs(internal::real(m_matT.coeff(iu,iu-1))) + abs(internal::real(m_matT.coeff(iu-1,iu-2)));
+ return abs(numext::real(m_matT.coeff(iu,iu-1))) + abs(numext::real(m_matT.coeff(iu-1,iu-2)));
}
// compute the shift as one of the eigenvalues of t, the 2x2
@@ -299,13 +299,13 @@ typename ComplexSchur<MatrixType>::ComplexScalar ComplexSchur<MatrixType>::compu
ComplexScalar eival1 = (trace + disc) / RealScalar(2);
ComplexScalar eival2 = (trace - disc) / RealScalar(2);
- if(internal::norm1(eival1) > internal::norm1(eival2))
+ if(numext::norm1(eival1) > numext::norm1(eival2))
eival2 = det / eival1;
else
eival1 = det / eival2;
// choose the eigenvalue closest to the bottom entry of the diagonal
- if(internal::norm1(eival1-t.coeff(1,1)) < internal::norm1(eival2-t.coeff(1,1)))
+ if(numext::norm1(eival1-t.coeff(1,1)) < numext::norm1(eival2-t.coeff(1,1)))
return normt * eival1;
else
return normt * eival2;
diff --git a/Eigen/src/Eigenvalues/EigenSolver.h b/Eigen/src/Eigenvalues/EigenSolver.h
index 594ec6576..bf20e03ef 100644
--- a/Eigen/src/Eigenvalues/EigenSolver.h
+++ b/Eigen/src/Eigenvalues/EigenSolver.h
@@ -317,12 +317,12 @@ MatrixType EigenSolver<MatrixType>::pseudoEigenvalueMatrix() const
MatrixType matD = MatrixType::Zero(n,n);
for (Index i=0; i<n; ++i)
{
- if (internal::isMuchSmallerThan(internal::imag(m_eivalues.coeff(i)), internal::real(m_eivalues.coeff(i))))
- matD.coeffRef(i,i) = internal::real(m_eivalues.coeff(i));
+ if (internal::isMuchSmallerThan(numext::imag(m_eivalues.coeff(i)), numext::real(m_eivalues.coeff(i))))
+ matD.coeffRef(i,i) = numext::real(m_eivalues.coeff(i));
else
{
- matD.template block<2,2>(i,i) << internal::real(m_eivalues.coeff(i)), internal::imag(m_eivalues.coeff(i)),
- -internal::imag(m_eivalues.coeff(i)), internal::real(m_eivalues.coeff(i));
+ matD.template block<2,2>(i,i) << numext::real(m_eivalues.coeff(i)), numext::imag(m_eivalues.coeff(i)),
+ -numext::imag(m_eivalues.coeff(i)), numext::real(m_eivalues.coeff(i));
++i;
}
}
@@ -338,7 +338,7 @@ typename EigenSolver<MatrixType>::EigenvectorsType EigenSolver<MatrixType>::eige
EigenvectorsType matV(n,n);
for (Index j=0; j<n; ++j)
{
- if (internal::isMuchSmallerThan(internal::imag(m_eivalues.coeff(j)), internal::real(m_eivalues.coeff(j))) || j+1==n)
+ if (internal::isMuchSmallerThan(numext::imag(m_eivalues.coeff(j)), numext::real(m_eivalues.coeff(j))) || j+1==n)
{
// we have a real eigen value
matV.col(j) = m_eivec.col(j).template cast<ComplexScalar>();
@@ -515,8 +515,8 @@ void EigenSolver<MatrixType>::doComputeEigenvectors()
else
{
std::complex<Scalar> cc = cdiv<Scalar>(0.0,-m_matT.coeff(n-1,n),m_matT.coeff(n-1,n-1)-p,q);
- m_matT.coeffRef(n-1,n-1) = internal::real(cc);
- m_matT.coeffRef(n-1,n) = internal::imag(cc);
+ m_matT.coeffRef(n-1,n-1) = numext::real(cc);
+ m_matT.coeffRef(n-1,n) = numext::imag(cc);
}
m_matT.coeffRef(n,n-1) = 0.0;
m_matT.coeffRef(n,n) = 1.0;
@@ -538,8 +538,8 @@ void EigenSolver<MatrixType>::doComputeEigenvectors()
if (m_eivalues.coeff(i).imag() == RealScalar(0))
{
std::complex<Scalar> cc = cdiv(-ra,-sa,w,q);
- m_matT.coeffRef(i,n-1) = internal::real(cc);
- m_matT.coeffRef(i,n) = internal::imag(cc);
+ m_matT.coeffRef(i,n-1) = numext::real(cc);
+ m_matT.coeffRef(i,n) = numext::imag(cc);
}
else
{
@@ -552,8 +552,8 @@ void EigenSolver<MatrixType>::doComputeEigenvectors()
vr = eps * norm * (abs(w) + abs(q) + abs(x) + abs(y) + abs(lastw));
std::complex<Scalar> cc = cdiv(x*lastra-lastw*ra+q*sa,x*lastsa-lastw*sa-q*ra,vr,vi);
- m_matT.coeffRef(i,n-1) = internal::real(cc);
- m_matT.coeffRef(i,n) = internal::imag(cc);
+ m_matT.coeffRef(i,n-1) = numext::real(cc);
+ m_matT.coeffRef(i,n) = numext::imag(cc);
if (abs(x) > (abs(lastw) + abs(q)))
{
m_matT.coeffRef(i+1,n-1) = (-ra - w * m_matT.coeff(i,n-1) + q * m_matT.coeff(i,n)) / x;
@@ -562,8 +562,8 @@ void EigenSolver<MatrixType>::doComputeEigenvectors()
else
{
cc = cdiv(-lastra-y*m_matT.coeff(i,n-1),-lastsa-y*m_matT.coeff(i,n),lastw,q);
- m_matT.coeffRef(i+1,n-1) = internal::real(cc);
- m_matT.coeffRef(i+1,n) = internal::imag(cc);
+ m_matT.coeffRef(i+1,n-1) = numext::real(cc);
+ m_matT.coeffRef(i+1,n) = numext::imag(cc);
}
}
diff --git a/Eigen/src/Eigenvalues/HessenbergDecomposition.h b/Eigen/src/Eigenvalues/HessenbergDecomposition.h
index ebd8ae908..3db0c0106 100644
--- a/Eigen/src/Eigenvalues/HessenbergDecomposition.h
+++ b/Eigen/src/Eigenvalues/HessenbergDecomposition.h
@@ -82,7 +82,7 @@ template<typename _MatrixType> class HessenbergDecomposition
typedef Matrix<Scalar, SizeMinusOne, 1, Options & ~RowMajor, MaxSizeMinusOne, 1> CoeffVectorType;
/** \brief Return type of matrixQ() */
- typedef typename HouseholderSequence<MatrixType,CoeffVectorType>::ConjugateReturnType HouseholderSequenceType;
+ typedef HouseholderSequence<MatrixType,typename internal::remove_all<typename CoeffVectorType::ConjugateReturnType>::type> HouseholderSequenceType;
typedef internal::HessenbergDecompositionMatrixHReturnType<MatrixType> MatrixHReturnType;
@@ -313,7 +313,7 @@ void HessenbergDecomposition<MatrixType>::_compute(MatrixType& matA, CoeffVector
// A = A H'
matA.rightCols(remainingSize)
- .applyHouseholderOnTheRight(matA.col(i).tail(remainingSize-1).conjugate(), internal::conj(h), &temp.coeffRef(0));
+ .applyHouseholderOnTheRight(matA.col(i).tail(remainingSize-1).conjugate(), numext::conj(h), &temp.coeffRef(0));
}
}
diff --git a/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h b/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
index 03c024927..3993046a8 100644
--- a/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
+++ b/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
@@ -395,7 +395,7 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
if(n==1)
{
- m_eivalues.coeffRef(0,0) = internal::real(matrix.coeff(0,0));
+ m_eivalues.coeffRef(0,0) = numext::real(matrix.coeff(0,0));
if(computeEigenvectors)
m_eivec.setOnes(n,n);
m_info = Success;
@@ -669,7 +669,7 @@ template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,2
static inline void computeRoots(const MatrixType& m, VectorType& roots)
{
using std::sqrt;
- const Scalar t0 = Scalar(0.5) * sqrt( abs2(m(0,0)-m(1,1)) + Scalar(4)*m(1,0)*m(1,0));
+ const Scalar t0 = Scalar(0.5) * sqrt( numext::abs2(m(0,0)-m(1,1)) + Scalar(4)*m(1,0)*m(1,0));
const Scalar t1 = Scalar(0.5) * (m(0,0) + m(1,1));
roots(0) = t1 - t0;
roots(1) = t1 + t0;
@@ -699,9 +699,9 @@ template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,2
if(computeEigenvectors)
{
scaledMat.diagonal().array () -= eivals(1);
- Scalar a2 = abs2(scaledMat(0,0));
- Scalar c2 = abs2(scaledMat(1,1));
- Scalar b2 = abs2(scaledMat(1,0));
+ Scalar a2 = numext::abs2(scaledMat(0,0));
+ Scalar c2 = numext::abs2(scaledMat(1,1));
+ Scalar b2 = numext::abs2(scaledMat(1,0));
if(a2>c2)
{
eivecs.col(1) << -scaledMat(1,0), scaledMat(0,0);
@@ -744,7 +744,7 @@ static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index sta
RealScalar e = subdiag[end-1];
// Note that thanks to scaling, e^2 or td^2 cannot overflow, however they can still
// underflow thus leading to inf/NaN values when using the following commented code:
-// RealScalar e2 = abs2(subdiag[end-1]);
+// RealScalar e2 = numext::abs2(subdiag[end-1]);
// RealScalar mu = diag[end] - e2 / (td + (td>0 ? 1 : -1) * sqrt(td*td + e2));
// This explain the following, somewhat more complicated, version:
RealScalar mu = diag[end];
@@ -752,8 +752,8 @@ static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index sta
mu -= abs(e);
else
{
- RealScalar e2 = abs2(subdiag[end-1]);
- RealScalar h = hypot(td,e);
+ RealScalar e2 = numext::abs2(subdiag[end-1]);
+ RealScalar h = numext::hypot(td,e);
if(e2==0) mu -= (e / (td + (td>0 ? 1 : -1))) * (e / h);
else mu -= e2 / (td + (td>0 ? h : -h));
}
diff --git a/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h b/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h
index 5de5f15d6..17c0dadd2 100644
--- a/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h
+++ b/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h
@@ -56,7 +56,7 @@ SelfAdjointEigenSolver<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >::compute(c
\
if(n==1) \
{ \
- m_eivalues.coeffRef(0,0) = internal::real(matrix.coeff(0,0)); \
+ m_eivalues.coeffRef(0,0) = numext::real(matrix.coeff(0,0)); \
if(computeEigenvectors) m_eivec.setOnes(n,n); \
m_info = Success; \
m_isInitialized = true; \
diff --git a/Eigen/src/Eigenvalues/Tridiagonalization.h b/Eigen/src/Eigenvalues/Tridiagonalization.h
index e8408761d..192278d68 100644
--- a/Eigen/src/Eigenvalues/Tridiagonalization.h
+++ b/Eigen/src/Eigenvalues/Tridiagonalization.h
@@ -96,7 +96,7 @@ template<typename _MatrixType> class Tridiagonalization
>::type SubDiagonalReturnType;
/** \brief Return type of matrixQ() */
- typedef typename HouseholderSequence<MatrixType,CoeffVectorType>::ConjugateReturnType HouseholderSequenceType;
+ typedef HouseholderSequence<MatrixType,typename internal::remove_all<typename CoeffVectorType::ConjugateReturnType>::type> HouseholderSequenceType;
/** \brief Default constructor.
*
@@ -345,7 +345,7 @@ namespace internal {
template<typename MatrixType, typename CoeffVectorType>
void tridiagonalization_inplace(MatrixType& matA, CoeffVectorType& hCoeffs)
{
- using internal::conj;
+ using numext::conj;
typedef typename MatrixType::Index Index;
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar;
@@ -468,7 +468,7 @@ struct tridiagonalization_inplace_selector<MatrixType,3,false>
{
using std::sqrt;
diag[0] = mat(0,0);
- RealScalar v1norm2 = abs2(mat(2,0));
+ RealScalar v1norm2 = numext::abs2(mat(2,0));
if(v1norm2 == RealScalar(0))
{
diag[1] = mat(1,1);
@@ -480,7 +480,7 @@ struct tridiagonalization_inplace_selector<MatrixType,3,false>
}
else
{
- RealScalar beta = sqrt(abs2(mat(1,0)) + v1norm2);
+ RealScalar beta = sqrt(numext::abs2(mat(1,0)) + v1norm2);
RealScalar invBeta = RealScalar(1)/beta;
Scalar m01 = mat(1,0) * invBeta;
Scalar m02 = mat(2,0) * invBeta;
@@ -510,7 +510,7 @@ struct tridiagonalization_inplace_selector<MatrixType,1,IsComplex>
template<typename DiagonalType, typename SubDiagonalType>
static void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType&, bool extractQ)
{
- diag(0,0) = real(mat(0,0));
+ diag(0,0) = numext::real(mat(0,0));
if(extractQ)
mat(0,0) = Scalar(1);
}
diff --git a/Eigen/src/Geometry/AlignedBox.h b/Eigen/src/Geometry/AlignedBox.h
index 538a5afb7..8e186d57a 100644
--- a/Eigen/src/Geometry/AlignedBox.h
+++ b/Eigen/src/Geometry/AlignedBox.h
@@ -56,7 +56,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
/** Default constructor initializing a null box. */
- inline explicit AlignedBox()
+ inline AlignedBox()
{ if (AmbientDimAtCompileTime!=Dynamic) setEmpty(); }
/** Constructs a null box with \a _dim the dimension of the ambient space. */
diff --git a/Eigen/src/Geometry/EulerAngles.h b/Eigen/src/Geometry/EulerAngles.h
index 216307706..97984d590 100644
--- a/Eigen/src/Geometry/EulerAngles.h
+++ b/Eigen/src/Geometry/EulerAngles.h
@@ -27,56 +27,75 @@ namespace Eigen {
* * AngleAxisf(ea[1], Vector3f::UnitX())
* * AngleAxisf(ea[2], Vector3f::UnitZ()); \endcode
* This corresponds to the right-multiply conventions (with right hand side frames).
+ *
+ * The returned angles are in the ranges [0:pi]x[0:pi]x[-pi:pi].
+ *
+ * \sa class AngleAxis
*/
template<typename Derived>
inline Matrix<typename MatrixBase<Derived>::Scalar,3,1>
MatrixBase<Derived>::eulerAngles(Index a0, Index a1, Index a2) const
{
using std::atan2;
+ using std::sin;
+ using std::cos;
/* Implemented from Graphics Gems IV */
EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived,3,3)
Matrix<Scalar,3,1> res;
typedef Matrix<typename Derived::Scalar,2,1> Vector2;
- const Scalar epsilon = NumTraits<Scalar>::dummy_precision();
const Index odd = ((a0+1)%3 == a1) ? 0 : 1;
const Index i = a0;
const Index j = (a0 + 1 + odd)%3;
const Index k = (a0 + 2 - odd)%3;
-
+
if (a0==a2)
{
- Scalar s = Vector2(coeff(j,i) , coeff(k,i)).norm();
- res[1] = atan2(s, coeff(i,i));
- if (s > epsilon)
+ res[0] = atan2(coeff(j,i), coeff(k,i));
+ if((odd && res[0]<Scalar(0)) || ((!odd) && res[0]>Scalar(0)))
{
- res[0] = atan2(coeff(j,i), coeff(k,i));
- res[2] = atan2(coeff(i,j),-coeff(i,k));
+ res[0] = (res[0] > Scalar(0)) ? res[0] - Scalar(M_PI) : res[0] + Scalar(M_PI);
+ Scalar s2 = Vector2(coeff(j,i), coeff(k,i)).norm();
+ res[1] = -atan2(s2, coeff(i,i));
}
else
{
- res[0] = Scalar(0);
- res[2] = (coeff(i,i)>0?1:-1)*atan2(-coeff(k,j), coeff(j,j));
+ Scalar s2 = Vector2(coeff(j,i), coeff(k,i)).norm();
+ res[1] = atan2(s2, coeff(i,i));
}
- }
+
+ // With a=(0,1,0), we have i=0; j=1; k=2, and after computing the first two angles,
+ // we can compute their respective rotation, and apply its inverse to M. Since the result must
+ // be a rotation around x, we have:
+ //
+ // c2 s1.s2 c1.s2 1 0 0
+ // 0 c1 -s1 * M = 0 c3 s3
+ // -s2 s1.c2 c1.c2 0 -s3 c3
+ //
+ // Thus: m11.c1 - m21.s1 = c3 & m12.c1 - m22.s1 = s3
+
+ Scalar s1 = sin(res[0]);
+ Scalar c1 = cos(res[0]);
+ res[2] = atan2(c1*coeff(j,k)-s1*coeff(k,k), c1*coeff(j,j) - s1 * coeff(k,j));
+ }
else
{
- Scalar c = Vector2(coeff(i,i) , coeff(i,j)).norm();
- res[1] = atan2(-coeff(i,k), c);
- if (c > epsilon)
- {
- res[0] = atan2(coeff(j,k), coeff(k,k));
- res[2] = atan2(coeff(i,j), coeff(i,i));
+ res[0] = atan2(coeff(j,k), coeff(k,k));
+ Scalar c2 = Vector2(coeff(i,i), coeff(i,j)).norm();
+ if((odd && res[0]<Scalar(0)) || ((!odd) && res[0]>Scalar(0))) {
+ res[0] = (res[0] > Scalar(0)) ? res[0] - Scalar(M_PI) : res[0] + Scalar(M_PI);
+ res[1] = atan2(-coeff(i,k), -c2);
}
else
- {
- res[0] = Scalar(0);
- res[2] = (coeff(i,k)>0?1:-1)*atan2(-coeff(k,j), coeff(j,j));
- }
+ res[1] = atan2(-coeff(i,k), c2);
+ Scalar s1 = sin(res[0]);
+ Scalar c1 = cos(res[0]);
+ res[2] = atan2(s1*coeff(k,i)-c1*coeff(j,i), c1*coeff(j,j) - s1 * coeff(k,j));
}
if (!odd)
res = -res;
+
return res;
}
diff --git a/Eigen/src/Geometry/Homogeneous.h b/Eigen/src/Geometry/Homogeneous.h
index df03feb55..00e71d190 100644
--- a/Eigen/src/Geometry/Homogeneous.h
+++ b/Eigen/src/Geometry/Homogeneous.h
@@ -59,7 +59,7 @@ template<typename MatrixType,typename Rhs> struct homogeneous_right_product_impl
} // end namespace internal
template<typename MatrixType,int _Direction> class Homogeneous
- : public MatrixBase<Homogeneous<MatrixType,_Direction> >
+ : internal::no_assignment_operator, public MatrixBase<Homogeneous<MatrixType,_Direction> >
{
public:
diff --git a/Eigen/src/Geometry/Hyperplane.h b/Eigen/src/Geometry/Hyperplane.h
index 6b31efde9..aeff43fef 100644
--- a/Eigen/src/Geometry/Hyperplane.h
+++ b/Eigen/src/Geometry/Hyperplane.h
@@ -50,7 +50,7 @@ public:
typedef const Block<const Coefficients,AmbientDimAtCompileTime,1> ConstNormalReturnType;
/** Default constructor without initialization */
- inline explicit Hyperplane() {}
+ inline Hyperplane() {}
template<int OtherOptions>
Hyperplane(const Hyperplane<Scalar,AmbientDimAtCompileTime,OtherOptions>& other)
diff --git a/Eigen/src/Geometry/OrthoMethods.h b/Eigen/src/Geometry/OrthoMethods.h
index 4c1bf5fcd..556bc8160 100644
--- a/Eigen/src/Geometry/OrthoMethods.h
+++ b/Eigen/src/Geometry/OrthoMethods.h
@@ -33,9 +33,9 @@ MatrixBase<Derived>::cross(const MatrixBase<OtherDerived>& other) const
typename internal::nested<Derived,2>::type lhs(derived());
typename internal::nested<OtherDerived,2>::type rhs(other.derived());
return typename cross_product_return_type<OtherDerived>::type(
- internal::conj(lhs.coeff(1) * rhs.coeff(2) - lhs.coeff(2) * rhs.coeff(1)),
- internal::conj(lhs.coeff(2) * rhs.coeff(0) - lhs.coeff(0) * rhs.coeff(2)),
- internal::conj(lhs.coeff(0) * rhs.coeff(1) - lhs.coeff(1) * rhs.coeff(0))
+ numext::conj(lhs.coeff(1) * rhs.coeff(2) - lhs.coeff(2) * rhs.coeff(1)),
+ numext::conj(lhs.coeff(2) * rhs.coeff(0) - lhs.coeff(0) * rhs.coeff(2)),
+ numext::conj(lhs.coeff(0) * rhs.coeff(1) - lhs.coeff(1) * rhs.coeff(0))
);
}
@@ -49,9 +49,9 @@ struct cross3_impl {
run(const VectorLhs& lhs, const VectorRhs& rhs)
{
return typename internal::plain_matrix_type<VectorLhs>::type(
- internal::conj(lhs.coeff(1) * rhs.coeff(2) - lhs.coeff(2) * rhs.coeff(1)),
- internal::conj(lhs.coeff(2) * rhs.coeff(0) - lhs.coeff(0) * rhs.coeff(2)),
- internal::conj(lhs.coeff(0) * rhs.coeff(1) - lhs.coeff(1) * rhs.coeff(0)),
+ numext::conj(lhs.coeff(1) * rhs.coeff(2) - lhs.coeff(2) * rhs.coeff(1)),
+ numext::conj(lhs.coeff(2) * rhs.coeff(0) - lhs.coeff(0) * rhs.coeff(2)),
+ numext::conj(lhs.coeff(0) * rhs.coeff(1) - lhs.coeff(1) * rhs.coeff(0)),
0
);
}
@@ -141,8 +141,8 @@ struct unitOrthogonal_selector
if (maxi==0)
sndi = 1;
RealScalar invnm = RealScalar(1)/(Vector2() << src.coeff(sndi),src.coeff(maxi)).finished().norm();
- perp.coeffRef(maxi) = -conj(src.coeff(sndi)) * invnm;
- perp.coeffRef(sndi) = conj(src.coeff(maxi)) * invnm;
+ perp.coeffRef(maxi) = -numext::conj(src.coeff(sndi)) * invnm;
+ perp.coeffRef(sndi) = numext::conj(src.coeff(maxi)) * invnm;
return perp;
}
@@ -168,8 +168,8 @@ struct unitOrthogonal_selector<Derived,3>
|| (!isMuchSmallerThan(src.y(), src.z())))
{
RealScalar invnm = RealScalar(1)/src.template head<2>().norm();
- perp.coeffRef(0) = -conj(src.y())*invnm;
- perp.coeffRef(1) = conj(src.x())*invnm;
+ perp.coeffRef(0) = -numext::conj(src.y())*invnm;
+ perp.coeffRef(1) = numext::conj(src.x())*invnm;
perp.coeffRef(2) = 0;
}
/* if both x and y are close to zero, then the vector is close
@@ -180,8 +180,8 @@ struct unitOrthogonal_selector<Derived,3>
{
RealScalar invnm = RealScalar(1)/src.template tail<2>().norm();
perp.coeffRef(0) = 0;
- perp.coeffRef(1) = -conj(src.z())*invnm;
- perp.coeffRef(2) = conj(src.y())*invnm;
+ perp.coeffRef(1) = -numext::conj(src.z())*invnm;
+ perp.coeffRef(2) = numext::conj(src.y())*invnm;
}
return perp;
@@ -193,7 +193,7 @@ struct unitOrthogonal_selector<Derived,2>
{
typedef typename plain_matrix_type<Derived>::type VectorType;
static inline VectorType run(const Derived& src)
- { return VectorType(-conj(src.y()), conj(src.x())).normalized(); }
+ { return VectorType(-numext::conj(src.y()), numext::conj(src.x())).normalized(); }
};
} // end namespace internal
diff --git a/Eigen/src/Geometry/ParametrizedLine.h b/Eigen/src/Geometry/ParametrizedLine.h
index 98dd0f0d1..77fa228e6 100644
--- a/Eigen/src/Geometry/ParametrizedLine.h
+++ b/Eigen/src/Geometry/ParametrizedLine.h
@@ -41,7 +41,7 @@ public:
typedef Matrix<Scalar,AmbientDimAtCompileTime,1,Options> VectorType;
/** Default constructor without initialization */
- inline explicit ParametrizedLine() {}
+ inline ParametrizedLine() {}
template<int OtherOptions>
ParametrizedLine(const ParametrizedLine<Scalar,AmbientDimAtCompileTime,OtherOptions>& other)
diff --git a/Eigen/src/Householder/Householder.h b/Eigen/src/Householder/Householder.h
index b7cfa9b2b..32112af9b 100644
--- a/Eigen/src/Householder/Householder.h
+++ b/Eigen/src/Householder/Householder.h
@@ -68,7 +68,7 @@ void MatrixBase<Derived>::makeHouseholder(
RealScalar& beta) const
{
using std::sqrt;
- using internal::conj;
+ using numext::conj;
EIGEN_STATIC_ASSERT_VECTOR_ONLY(EssentialPart)
VectorBlock<const Derived, EssentialPart::SizeAtCompileTime> tail(derived(), 1, size()-1);
@@ -76,16 +76,16 @@ void MatrixBase<Derived>::makeHouseholder(
RealScalar tailSqNorm = size()==1 ? RealScalar(0) : tail.squaredNorm();
Scalar c0 = coeff(0);
- if(tailSqNorm == RealScalar(0) && internal::imag(c0)==RealScalar(0))
+ if(tailSqNorm == RealScalar(0) && numext::imag(c0)==RealScalar(0))
{
tau = RealScalar(0);
- beta = internal::real(c0);
+ beta = numext::real(c0);
essential.setZero();
}
else
{
- beta = sqrt(internal::abs2(c0) + tailSqNorm);
- if (internal::real(c0)>=RealScalar(0))
+ beta = sqrt(numext::abs2(c0) + tailSqNorm);
+ if (numext::real(c0)>=RealScalar(0))
beta = -beta;
essential = tail / (c0 - beta);
tau = conj((beta - c0) / beta);
diff --git a/Eigen/src/Householder/HouseholderSequence.h b/Eigen/src/Householder/HouseholderSequence.h
index 1e71e16a7..d800ca1fa 100644
--- a/Eigen/src/Householder/HouseholderSequence.h
+++ b/Eigen/src/Householder/HouseholderSequence.h
@@ -112,6 +112,9 @@ template<typename OtherScalarType, typename MatrixType> struct matrix_type_times
template<typename VectorsType, typename CoeffsType, int Side> class HouseholderSequence
: public EigenBase<HouseholderSequence<VectorsType,CoeffsType,Side> >
{
+ typedef typename internal::hseq_side_dependent_impl<VectorsType,CoeffsType,Side>::EssentialVectorType EssentialVectorType;
+
+ public:
enum {
RowsAtCompileTime = internal::traits<HouseholderSequence>::RowsAtCompileTime,
ColsAtCompileTime = internal::traits<HouseholderSequence>::ColsAtCompileTime,
@@ -121,13 +124,10 @@ template<typename VectorsType, typename CoeffsType, int Side> class HouseholderS
typedef typename internal::traits<HouseholderSequence>::Scalar Scalar;
typedef typename VectorsType::Index Index;
- typedef typename internal::hseq_side_dependent_impl<VectorsType,CoeffsType,Side>::EssentialVectorType
- EssentialVectorType;
-
- public:
-
typedef HouseholderSequence<
- VectorsType,
+ typename internal::conditional<NumTraits<Scalar>::IsComplex,
+ typename internal::remove_all<typename VectorsType::ConjugateReturnType>::type,
+ VectorsType>::type,
typename internal::conditional<NumTraits<Scalar>::IsComplex,
typename internal::remove_all<typename CoeffsType::ConjugateReturnType>::type,
CoeffsType>::type,
@@ -208,7 +208,7 @@ template<typename VectorsType, typename CoeffsType, int Side> class HouseholderS
/** \brief Complex conjugate of the Householder sequence. */
ConjugateReturnType conjugate() const
{
- return ConjugateReturnType(m_vectors, m_coeffs.conjugate())
+ return ConjugateReturnType(m_vectors.conjugate(), m_coeffs.conjugate())
.setTrans(m_trans)
.setLength(m_length)
.setShift(m_shift);
diff --git a/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h b/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h
index fbefb696f..6fc6ab852 100644
--- a/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h
+++ b/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h
@@ -43,8 +43,9 @@ bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x,
VectorType r = rhs - mat * x;
VectorType r0 = r;
- RealScalar r0_sqnorm = rhs.squaredNorm();
- if(r0_sqnorm == 0)
+ RealScalar r0_sqnorm = r0.squaredNorm();
+ RealScalar rhs_sqnorm = rhs.squaredNorm();
+ if(rhs_sqnorm == 0)
{
x.setZero();
return true;
@@ -61,13 +62,22 @@ bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x,
RealScalar tol2 = tol*tol;
int i = 0;
+ int restarts = 0;
- while ( r.squaredNorm()/r0_sqnorm > tol2 && i<maxIters )
+ while ( r.squaredNorm()/rhs_sqnorm > tol2 && i<maxIters )
{
Scalar rho_old = rho;
rho = r0.dot(r);
- if (rho == Scalar(0)) return false; /* New search directions cannot be found */
+ if (internal::isMuchSmallerThan(rho,r0_sqnorm))
+ {
+ // The new residual vector became too orthogonal to the arbitrarily choosen direction r0
+ // Let's restart with a new r0:
+ r0 = r;
+ rho = r0_sqnorm = r.squaredNorm();
+ if(restarts++ == 0)
+ i = 0;
+ }
Scalar beta = (rho/rho_old) * (alpha / w);
p = r + beta * (p - w * v);
@@ -81,12 +91,16 @@ bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x,
z = precond.solve(s);
t.noalias() = mat * z;
- w = t.dot(s) / t.squaredNorm();
+ RealScalar tmp = t.squaredNorm();
+ if(tmp>RealScalar(0))
+ w = t.dot(s) / tmp;
+ else
+ w = Scalar(0);
x += alpha * y + w * z;
r = s - w * t;
++i;
}
- tol_error = sqrt(r.squaredNorm()/r0_sqnorm);
+ tol_error = sqrt(r.squaredNorm()/rhs_sqnorm);
iters = i;
return true;
}
diff --git a/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h b/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h
index 00b5647c6..a74a8155e 100644
--- a/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h
+++ b/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h
@@ -63,7 +63,7 @@ void conjugate_gradient(const MatrixType& mat, const Rhs& rhs, Dest& x,
p = precond.solve(residual); //initial search direction
VectorType z(n), tmp(n);
- RealScalar absNew = internal::real(residual.dot(p)); // the square of the absolute value of r scaled by invM
+ RealScalar absNew = numext::real(residual.dot(p)); // the square of the absolute value of r scaled by invM
int i = 0;
while(i < maxIters)
{
@@ -80,7 +80,7 @@ void conjugate_gradient(const MatrixType& mat, const Rhs& rhs, Dest& x,
z = precond.solve(residual); // approximately solve for "A z = residual"
RealScalar absOld = absNew;
- absNew = internal::real(residual.dot(z)); // update the absolute value of r
+ absNew = numext::real(residual.dot(z)); // update the absolute value of r
RealScalar beta = absNew / absOld; // calculate the Gram-Schmidt value used to create the new search direction
p = z + beta * p; // update search direction
i++;
diff --git a/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h b/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h
index 17d18ef58..b55afc136 100644
--- a/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h
+++ b/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h
@@ -150,8 +150,7 @@ class IncompleteLUT : internal::noncopyable
{
analyzePattern(amat);
factorize(amat);
- eigen_assert(m_factorizationIsOk == true);
- m_isInitialized = true;
+ m_isInitialized = m_factorizationIsOk;
return *this;
}
@@ -310,7 +309,7 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
jr(k) = jpos;
++sizeu;
}
- rownorm += internal::abs2(j_it.value());
+ rownorm += numext::abs2(j_it.value());
}
// 2 - detect possible zero row
diff --git a/Eigen/src/Jacobi/Jacobi.h b/Eigen/src/Jacobi/Jacobi.h
index d9d75196c..956f72d57 100644
--- a/Eigen/src/Jacobi/Jacobi.h
+++ b/Eigen/src/Jacobi/Jacobi.h
@@ -50,16 +50,16 @@ template<typename Scalar> class JacobiRotation
/** Concatenates two planar rotation */
JacobiRotation operator*(const JacobiRotation& other)
{
- using internal::conj;
+ using numext::conj;
return JacobiRotation(m_c * other.m_c - conj(m_s) * other.m_s,
conj(m_c * conj(other.m_s) + conj(m_s) * conj(other.m_c)));
}
/** Returns the transposed transformation */
- JacobiRotation transpose() const { using internal::conj; return JacobiRotation(m_c, -conj(m_s)); }
+ JacobiRotation transpose() const { using numext::conj; return JacobiRotation(m_c, -conj(m_s)); }
/** Returns the adjoint transformation */
- JacobiRotation adjoint() const { using internal::conj; return JacobiRotation(conj(m_c), -m_s); }
+ JacobiRotation adjoint() const { using numext::conj; return JacobiRotation(conj(m_c), -m_s); }
template<typename Derived>
bool makeJacobi(const MatrixBase<Derived>&, typename Derived::Index p, typename Derived::Index q);
@@ -94,7 +94,7 @@ bool JacobiRotation<Scalar>::makeJacobi(const RealScalar& x, const Scalar& y, co
else
{
RealScalar tau = (x-z)/(RealScalar(2)*abs(y));
- RealScalar w = sqrt(internal::abs2(tau) + RealScalar(1));
+ RealScalar w = sqrt(numext::abs2(tau) + RealScalar(1));
RealScalar t;
if(tau>RealScalar(0))
{
@@ -105,8 +105,8 @@ bool JacobiRotation<Scalar>::makeJacobi(const RealScalar& x, const Scalar& y, co
t = RealScalar(1) / (tau - w);
}
RealScalar sign_t = t > RealScalar(0) ? RealScalar(1) : RealScalar(-1);
- RealScalar n = RealScalar(1) / sqrt(internal::abs2(t)+RealScalar(1));
- m_s = - sign_t * (internal::conj(y) / abs(y)) * abs(t) * n;
+ RealScalar n = RealScalar(1) / sqrt(numext::abs2(t)+RealScalar(1));
+ m_s = - sign_t * (numext::conj(y) / abs(y)) * abs(t) * n;
m_c = n;
return true;
}
@@ -125,7 +125,7 @@ template<typename Scalar>
template<typename Derived>
inline bool JacobiRotation<Scalar>::makeJacobi(const MatrixBase<Derived>& m, typename Derived::Index p, typename Derived::Index q)
{
- return makeJacobi(internal::real(m.coeff(p,p)), m.coeff(p,q), internal::real(m.coeff(q,q)));
+ return makeJacobi(numext::real(m.coeff(p,p)), m.coeff(p,q), numext::real(m.coeff(q,q)));
}
/** Makes \c *this as a Givens rotation \c G such that applying \f$ G^* \f$ to the left of the vector
@@ -157,11 +157,11 @@ void JacobiRotation<Scalar>::makeGivens(const Scalar& p, const Scalar& q, Scalar
{
using std::sqrt;
using std::abs;
- using internal::conj;
+ using numext::conj;
if(q==Scalar(0))
{
- m_c = internal::real(p)<0 ? Scalar(-1) : Scalar(1);
+ m_c = numext::real(p)<0 ? Scalar(-1) : Scalar(1);
m_s = 0;
if(r) *r = m_c * p;
}
@@ -173,17 +173,17 @@ void JacobiRotation<Scalar>::makeGivens(const Scalar& p, const Scalar& q, Scalar
}
else
{
- RealScalar p1 = internal::norm1(p);
- RealScalar q1 = internal::norm1(q);
+ RealScalar p1 = numext::norm1(p);
+ RealScalar q1 = numext::norm1(q);
if(p1>=q1)
{
Scalar ps = p / p1;
- RealScalar p2 = internal::abs2(ps);
+ RealScalar p2 = numext::abs2(ps);
Scalar qs = q / p1;
- RealScalar q2 = internal::abs2(qs);
+ RealScalar q2 = numext::abs2(qs);
RealScalar u = sqrt(RealScalar(1) + q2/p2);
- if(internal::real(p)<RealScalar(0))
+ if(numext::real(p)<RealScalar(0))
u = -u;
m_c = Scalar(1)/u;
@@ -193,12 +193,12 @@ void JacobiRotation<Scalar>::makeGivens(const Scalar& p, const Scalar& q, Scalar
else
{
Scalar ps = p / q1;
- RealScalar p2 = internal::abs2(ps);
+ RealScalar p2 = numext::abs2(ps);
Scalar qs = q / q1;
- RealScalar q2 = internal::abs2(qs);
+ RealScalar q2 = numext::abs2(qs);
RealScalar u = q1 * sqrt(p2 + q2);
- if(internal::real(p)<RealScalar(0))
+ if(numext::real(p)<RealScalar(0))
u = -u;
p1 = abs(p);
@@ -231,7 +231,7 @@ void JacobiRotation<Scalar>::makeGivens(const Scalar& p, const Scalar& q, Scalar
else if(abs(p) > abs(q))
{
Scalar t = q/p;
- Scalar u = sqrt(Scalar(1) + internal::abs2(t));
+ Scalar u = sqrt(Scalar(1) + numext::abs2(t));
if(p<Scalar(0))
u = -u;
m_c = Scalar(1)/u;
@@ -241,7 +241,7 @@ void JacobiRotation<Scalar>::makeGivens(const Scalar& p, const Scalar& q, Scalar
else
{
Scalar t = p/q;
- Scalar u = sqrt(Scalar(1) + internal::abs2(t));
+ Scalar u = sqrt(Scalar(1) + numext::abs2(t));
if(q<Scalar(0))
u = -u;
m_s = -Scalar(1)/u;
@@ -337,8 +337,8 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(VectorX& _x, VectorY& _y,
{
Scalar xi = x[i];
Scalar yi = y[i];
- x[i] = c * xi + conj(s) * yi;
- y[i] = -s * xi + conj(c) * yi;
+ x[i] = c * xi + numext::conj(s) * yi;
+ y[i] = -s * xi + numext::conj(c) * yi;
}
Scalar* EIGEN_RESTRICT px = x + alignedStart;
@@ -385,8 +385,8 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(VectorX& _x, VectorY& _y,
{
Scalar xi = x[i];
Scalar yi = y[i];
- x[i] = c * xi + conj(s) * yi;
- y[i] = -s * xi + conj(c) * yi;
+ x[i] = c * xi + numext::conj(s) * yi;
+ y[i] = -s * xi + numext::conj(c) * yi;
}
}
@@ -418,8 +418,8 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(VectorX& _x, VectorY& _y,
{
Scalar xi = *x;
Scalar yi = *y;
- *x = c * xi + conj(s) * yi;
- *y = -s * xi + conj(c) * yi;
+ *x = c * xi + numext::conj(s) * yi;
+ *y = -s * xi + numext::conj(c) * yi;
x += incrx;
y += incry;
}
diff --git a/Eigen/src/LU/Inverse.h b/Eigen/src/LU/Inverse.h
index 57f9f686c..8d1364e0a 100644
--- a/Eigen/src/LU/Inverse.h
+++ b/Eigen/src/LU/Inverse.h
@@ -348,7 +348,7 @@ inline const internal::inverse_impl<Derived> MatrixBase<Derived>::inverse() cons
* This is only for fixed-size square matrices of size up to 4x4.
*
* \param inverse Reference to the matrix in which to store the inverse.
- * \param determinant Reference to the variable in which to store the inverse.
+ * \param determinant Reference to the variable in which to store the determinant.
* \param invertible Reference to the bool variable in which to store whether the matrix is invertible.
* \param absDeterminantThreshold Optional parameter controlling the invertibility check.
* The matrix will be declared invertible if the absolute value of its
diff --git a/Eigen/src/MetisSupport/MetisSupport.h b/Eigen/src/MetisSupport/MetisSupport.h
index 818355e79..f2bbef20c 100644
--- a/Eigen/src/MetisSupport/MetisSupport.h
+++ b/Eigen/src/MetisSupport/MetisSupport.h
@@ -134,4 +134,4 @@ public:
};
}// end namespace eigen
-#endif \ No newline at end of file
+#endif
diff --git a/Eigen/src/QR/ColPivHouseholderQR.h b/Eigen/src/QR/ColPivHouseholderQR.h
index 9ec8a65e4..8b01f8179 100644
--- a/Eigen/src/QR/ColPivHouseholderQR.h
+++ b/Eigen/src/QR/ColPivHouseholderQR.h
@@ -55,7 +55,7 @@ template<typename _MatrixType> class ColPivHouseholderQR
typedef typename internal::plain_row_type<MatrixType, Index>::type IntRowVectorType;
typedef typename internal::plain_row_type<MatrixType>::type RowVectorType;
typedef typename internal::plain_row_type<MatrixType, RealScalar>::type RealRowVectorType;
- typedef typename HouseholderSequence<MatrixType,HCoeffsType>::ConjugateReturnType HouseholderSequenceType;
+ typedef HouseholderSequence<MatrixType,typename internal::remove_all<typename HCoeffsType::ConjugateReturnType>::type> HouseholderSequenceType;
private:
@@ -94,6 +94,18 @@ template<typename _MatrixType> class ColPivHouseholderQR
m_isInitialized(false),
m_usePrescribedThreshold(false) {}
+ /** \brief Constructs a QR factorization from a given matrix
+ *
+ * This constructor computes the QR factorization of the matrix \a matrix by calling
+ * the method compute(). It is a short cut for:
+ *
+ * \code
+ * ColPivHouseholderQR<MatrixType> qr(matrix.rows(), matrix.cols());
+ * qr.compute(matrix);
+ * \endcode
+ *
+ * \sa compute()
+ */
ColPivHouseholderQR(const MatrixType& matrix)
: m_qr(matrix.rows(), matrix.cols()),
m_hCoeffs((std::min)(matrix.rows(),matrix.cols())),
@@ -163,6 +175,7 @@ template<typename _MatrixType> class ColPivHouseholderQR
ColPivHouseholderQR& compute(const MatrixType& matrix);
+ /** \returns a const reference to the column permutation matrix */
const PermutationType& colsPermutation() const
{
eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
@@ -281,6 +294,11 @@ template<typename _MatrixType> class ColPivHouseholderQR
inline Index rows() const { return m_qr.rows(); }
inline Index cols() const { return m_qr.cols(); }
+
+ /** \returns a const reference to the vector of Householder coefficients used to represent the factor \c Q.
+ *
+ * For advanced uses only.
+ */
const HCoeffsType& hCoeffs() const { return m_hCoeffs; }
/** Allows to prescribe a threshold to be used by certain methods, such as rank(),
@@ -394,6 +412,12 @@ typename MatrixType::RealScalar ColPivHouseholderQR<MatrixType>::logAbsDetermina
return m_qr.diagonal().cwiseAbs().array().log().sum();
}
+/** Performs the QR factorization of the given matrix \a matrix. The result of
+ * the factorization is stored into \c *this, and a reference to \c *this
+ * is returned.
+ *
+ * \sa class ColPivHouseholderQR, ColPivHouseholderQR(const MatrixType&)
+ */
template<typename MatrixType>
ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const MatrixType& matrix)
{
@@ -417,7 +441,7 @@ ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const
for(Index k = 0; k < cols; ++k)
m_colSqNorms.coeffRef(k) = m_qr.col(k).squaredNorm();
- RealScalar threshold_helper = m_colSqNorms.maxCoeff() * internal::abs2(NumTraits<Scalar>::epsilon()) / RealScalar(rows);
+ RealScalar threshold_helper = m_colSqNorms.maxCoeff() * numext::abs2(NumTraits<Scalar>::epsilon()) / RealScalar(rows);
m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
m_maxpivot = RealScalar(0);
@@ -501,8 +525,8 @@ struct solve_retval<ColPivHouseholderQR<_MatrixType>, Rhs>
{
eigen_assert(rhs().rows() == dec().rows());
- const int cols = dec().cols(),
- nonzero_pivots = dec().nonzeroPivots();
+ const Index cols = dec().cols(),
+ nonzero_pivots = dec().nonzeroPivots();
if(nonzero_pivots == 0)
{
diff --git a/Eigen/src/QR/FullPivHouseholderQR.h b/Eigen/src/QR/FullPivHouseholderQR.h
index 613c29e57..0dd5ad347 100644
--- a/Eigen/src/QR/FullPivHouseholderQR.h
+++ b/Eigen/src/QR/FullPivHouseholderQR.h
@@ -100,6 +100,18 @@ template<typename _MatrixType> class FullPivHouseholderQR
m_isInitialized(false),
m_usePrescribedThreshold(false) {}
+ /** \brief Constructs a QR factorization from a given matrix
+ *
+ * This constructor computes the QR factorization of the matrix \a matrix by calling
+ * the method compute(). It is a short cut for:
+ *
+ * \code
+ * FullPivHouseholderQR<MatrixType> qr(matrix.rows(), matrix.cols());
+ * qr.compute(matrix);
+ * \endcode
+ *
+ * \sa compute()
+ */
FullPivHouseholderQR(const MatrixType& matrix)
: m_qr(matrix.rows(), matrix.cols()),
m_hCoeffs((std::min)(matrix.rows(), matrix.cols())),
@@ -152,12 +164,14 @@ template<typename _MatrixType> class FullPivHouseholderQR
FullPivHouseholderQR& compute(const MatrixType& matrix);
+ /** \returns a const reference to the column permutation matrix */
const PermutationType& colsPermutation() const
{
eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
return m_cols_permutation;
}
+ /** \returns a const reference to the vector of indices representing the rows transpositions */
const IntColVectorType& rowsTranspositions() const
{
eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
@@ -275,6 +289,11 @@ template<typename _MatrixType> class FullPivHouseholderQR
inline Index rows() const { return m_qr.rows(); }
inline Index cols() const { return m_qr.cols(); }
+
+ /** \returns a const reference to the vector of Householder coefficients used to represent the factor \c Q.
+ *
+ * For advanced uses only.
+ */
const HCoeffsType& hCoeffs() const { return m_hCoeffs; }
/** Allows to prescribe a threshold to be used by certain methods, such as rank(),
@@ -377,6 +396,12 @@ typename MatrixType::RealScalar FullPivHouseholderQR<MatrixType>::logAbsDetermin
return m_qr.diagonal().cwiseAbs().array().log().sum();
}
+/** Performs the QR factorization of the given matrix \a matrix. The result of
+ * the factorization is stored into \c *this, and a reference to \c *this
+ * is returned.
+ *
+ * \sa class FullPivHouseholderQR, FullPivHouseholderQR(const MatrixType&)
+ */
template<typename MatrixType>
FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(const MatrixType& matrix)
{
@@ -547,7 +572,7 @@ public:
template <typename ResultType>
void evalTo(ResultType& result, WorkVectorType& workspace) const
{
- using internal::conj;
+ using numext::conj;
// compute the product H'_0 H'_1 ... H'_n-1,
// where H_k is the k-th Householder transformation I - h_k v_k v_k'
// and v_k is the k-th Householder vector [1,m_qr(k+1,k), m_qr(k+2,k), ...]
diff --git a/Eigen/src/QR/HouseholderQR.h b/Eigen/src/QR/HouseholderQR.h
index 0314d5259..abc61bcbb 100644
--- a/Eigen/src/QR/HouseholderQR.h
+++ b/Eigen/src/QR/HouseholderQR.h
@@ -57,14 +57,14 @@ template<typename _MatrixType> class HouseholderQR
typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime, (MatrixType::Flags&RowMajorBit) ? RowMajor : ColMajor, MaxRowsAtCompileTime, MaxRowsAtCompileTime> MatrixQType;
typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
typedef typename internal::plain_row_type<MatrixType>::type RowVectorType;
- typedef typename HouseholderSequence<MatrixType,HCoeffsType>::ConjugateReturnType HouseholderSequenceType;
+ typedef HouseholderSequence<MatrixType,typename internal::remove_all<typename HCoeffsType::ConjugateReturnType>::type> HouseholderSequenceType;
/**
- * \brief Default Constructor.
- *
- * The default constructor is useful in cases in which the user intends to
- * perform decompositions via HouseholderQR::compute(const MatrixType&).
- */
+ * \brief Default Constructor.
+ *
+ * The default constructor is useful in cases in which the user intends to
+ * perform decompositions via HouseholderQR::compute(const MatrixType&).
+ */
HouseholderQR() : m_qr(), m_hCoeffs(), m_temp(), m_isInitialized(false) {}
/** \brief Default Constructor with memory preallocation
@@ -79,6 +79,18 @@ template<typename _MatrixType> class HouseholderQR
m_temp(cols),
m_isInitialized(false) {}
+ /** \brief Constructs a QR factorization from a given matrix
+ *
+ * This constructor computes the QR factorization of the matrix \a matrix by calling
+ * the method compute(). It is a short cut for:
+ *
+ * \code
+ * HouseholderQR<MatrixType> qr(matrix.rows(), matrix.cols());
+ * qr.compute(matrix);
+ * \endcode
+ *
+ * \sa compute()
+ */
HouseholderQR(const MatrixType& matrix)
: m_qr(matrix.rows(), matrix.cols()),
m_hCoeffs((std::min)(matrix.rows(),matrix.cols())),
@@ -169,6 +181,11 @@ template<typename _MatrixType> class HouseholderQR
inline Index rows() const { return m_qr.rows(); }
inline Index cols() const { return m_qr.cols(); }
+
+ /** \returns a const reference to the vector of Householder coefficients used to represent the factor \c Q.
+ *
+ * For advanced uses only.
+ */
const HCoeffsType& hCoeffs() const { return m_hCoeffs; }
protected:
@@ -317,6 +334,12 @@ struct solve_retval<HouseholderQR<_MatrixType>, Rhs>
} // end namespace internal
+/** Performs the QR factorization of the given matrix \a matrix. The result of
+ * the factorization is stored into \c *this, and a reference to \c *this
+ * is returned.
+ *
+ * \sa class HouseholderQR, HouseholderQR(const MatrixType&)
+ */
template<typename MatrixType>
HouseholderQR<MatrixType>& HouseholderQR<MatrixType>::compute(const MatrixType& matrix)
{
diff --git a/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h b/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h
index 0ffb894f6..aa41f434c 100644
--- a/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h
+++ b/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h
@@ -83,10 +83,12 @@ class SPQR
~SPQR()
{
// Calls SuiteSparseQR_free()
- cholmod_free_sparse(&m_H, &m_cc);
- cholmod_free_dense(&m_HTau, &m_cc);
- delete[] m_E;
- delete[] m_HPinv;
+ cholmod_l_free_sparse(&m_H, &m_cc);
+ cholmod_l_free_sparse(&m_cR, &m_cc);
+ cholmod_l_free_dense(&m_HTau, &m_cc);
+ std::free(m_E);
+ std::free(m_HPinv);
+ cholmod_l_finish(&m_cc);
}
void compute(const _MatrixType& matrix)
{
@@ -244,7 +246,7 @@ struct SPQR_QProduct : ReturnByValue<SPQR_QProduct<SPQRType,Derived> >
y_cd = viewAsCholmod(m_other.const_cast_derived());
x_cd = SuiteSparseQR_qmult<Scalar>(method, m_spqr.m_H, m_spqr.m_HTau, m_spqr.m_HPinv, &y_cd, cc);
res = Matrix<Scalar,ResType::RowsAtCompileTime,ResType::ColsAtCompileTime>::Map(reinterpret_cast<Scalar*>(x_cd->x), x_cd->nrow, x_cd->ncol);
- cholmod_free_dense(&x_cd, cc);
+ cholmod_l_free_dense(&x_cd, cc);
}
const SPQRType& m_spqr;
const Derived& m_other;
@@ -301,4 +303,4 @@ struct solve_retval<SPQR<_MatrixType>, Rhs>
} // end namespace internal
}// End namespace Eigen
-#endif \ No newline at end of file
+#endif
diff --git a/Eigen/src/SVD/JacobiSVD.h b/Eigen/src/SVD/JacobiSVD.h
index 2ab4fc05e..9fd9de669 100644
--- a/Eigen/src/SVD/JacobiSVD.h
+++ b/Eigen/src/SVD/JacobiSVD.h
@@ -374,7 +374,7 @@ struct svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, true>
using std::sqrt;
Scalar z;
JacobiRotation<Scalar> rot;
- RealScalar n = sqrt(abs2(work_matrix.coeff(p,p)) + abs2(work_matrix.coeff(q,p)));
+ RealScalar n = sqrt(numext::abs2(work_matrix.coeff(p,p)) + numext::abs2(work_matrix.coeff(q,p)));
if(n==0)
{
z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
@@ -413,8 +413,8 @@ void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q,
{
using std::sqrt;
Matrix<RealScalar,2,2> m;
- m << real(matrix.coeff(p,p)), real(matrix.coeff(p,q)),
- real(matrix.coeff(q,p)), real(matrix.coeff(q,q));
+ m << numext::real(matrix.coeff(p,p)), numext::real(matrix.coeff(p,q)),
+ numext::real(matrix.coeff(q,p)), numext::real(matrix.coeff(q,q));
JacobiRotation<RealScalar> rot1;
RealScalar t = m.coeff(0,0) + m.coeff(1,1);
RealScalar d = m.coeff(1,0) - m.coeff(0,1);
@@ -426,7 +426,7 @@ void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q,
else
{
RealScalar u = d / t;
- rot1.c() = RealScalar(1) / sqrt(RealScalar(1) + abs2(u));
+ rot1.c() = RealScalar(1) / sqrt(RealScalar(1) + numext::abs2(u));
rot1.s() = rot1.c() * u;
}
m.applyOnTheLeft(0,1,rot1);
@@ -850,17 +850,12 @@ struct solve_retval<JacobiSVD<_MatrixType, QRPreconditioner>, Rhs>
// A = U S V^*
// So A^{-1} = V S^{-1} U^*
- Index diagSize = (std::min)(dec().rows(), dec().cols());
- typename JacobiSVDType::SingularValuesType invertedSingVals(diagSize);
-
+ Matrix<Scalar, Dynamic, Rhs::ColsAtCompileTime, 0, _MatrixType::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime> tmp;
Index nonzeroSingVals = dec().nonzeroSingularValues();
- invertedSingVals.head(nonzeroSingVals) = dec().singularValues().head(nonzeroSingVals).array().inverse();
- invertedSingVals.tail(diagSize - nonzeroSingVals).setZero();
-
- dst = dec().matrixV().leftCols(diagSize)
- * invertedSingVals.asDiagonal()
- * dec().matrixU().leftCols(diagSize).adjoint()
- * rhs();
+
+ tmp.noalias() = dec().matrixU().leftCols(nonzeroSingVals).adjoint() * rhs();
+ tmp = dec().singularValues().head(nonzeroSingVals).asDiagonal().inverse() * tmp;
+ dst = dec().matrixV().leftCols(nonzeroSingVals) * tmp;
}
};
} // end namespace internal
diff --git a/Eigen/src/SVD/UpperBidiagonalization.h b/Eigen/src/SVD/UpperBidiagonalization.h
index 213b3100d..587de37a5 100644
--- a/Eigen/src/SVD/UpperBidiagonalization.h
+++ b/Eigen/src/SVD/UpperBidiagonalization.h
@@ -39,7 +39,7 @@ template<typename _MatrixType> class UpperBidiagonalization
CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, const Diagonal<const MatrixType,0> >
> HouseholderUSequenceType;
typedef HouseholderSequence<
- const MatrixType,
+ const typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type,
Diagonal<const MatrixType,1>,
OnTheRight
> HouseholderVSequenceType;
@@ -74,7 +74,7 @@ template<typename _MatrixType> class UpperBidiagonalization
const HouseholderVSequenceType householderV() // const here gives nasty errors and i'm lazy
{
eigen_assert(m_isInitialized && "UpperBidiagonalization is not initialized.");
- return HouseholderVSequenceType(m_householder, m_householder.const_derived().template diagonal<1>())
+ return HouseholderVSequenceType(m_householder.conjugate(), m_householder.const_derived().template diagonal<1>())
.setLength(m_householder.cols()-1)
.setShift(1);
}
diff --git a/Eigen/src/SparseCholesky/SimplicialCholesky.h b/Eigen/src/SparseCholesky/SimplicialCholesky.h
index 62747279d..f41d7e010 100644
--- a/Eigen/src/SparseCholesky/SimplicialCholesky.h
+++ b/Eigen/src/SparseCholesky/SimplicialCholesky.h
@@ -364,7 +364,7 @@ public:
Scalar determinant() const
{
Scalar detL = Base::m_matrix.diagonal().prod();
- return internal::abs2(detL);
+ return numext::abs2(detL);
}
};
@@ -599,7 +599,7 @@ public:
else
{
Scalar detL = Diagonal<const CholMatrixType>(Base::m_matrix).prod();
- return internal::abs2(detL);
+ return numext::abs2(detL);
}
}
diff --git a/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h b/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h
index 4b249868f..7aaf702be 100644
--- a/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h
+++ b/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h
@@ -131,7 +131,7 @@ void SimplicialCholeskyBase<Derived>::factorize_preordered(const CholMatrixType&
Index i = it.index();
if(i <= k)
{
- y[i] += internal::conj(it.value()); /* scatter A(i,k) into Y (sum duplicates) */
+ y[i] += numext::conj(it.value()); /* scatter A(i,k) into Y (sum duplicates) */
Index len;
for(len = 0; tags[i] != k; i = m_parent[i])
{
@@ -145,7 +145,7 @@ void SimplicialCholeskyBase<Derived>::factorize_preordered(const CholMatrixType&
/* compute numerical values kth row of L (a sparse triangular solve) */
- RealScalar d = internal::real(y[k]) * m_shiftScale + m_shiftOffset; // get D(k,k), apply the shift function, and clear Y(k)
+ RealScalar d = numext::real(y[k]) * m_shiftScale + m_shiftOffset; // get D(k,k), apply the shift function, and clear Y(k)
y[k] = 0.0;
for(; top < size; ++top)
{
@@ -163,8 +163,8 @@ void SimplicialCholeskyBase<Derived>::factorize_preordered(const CholMatrixType&
Index p2 = Lp[i] + m_nonZerosPerCol[i];
Index p;
for(p = Lp[i] + (DoLDLT ? 0 : 1); p < p2; ++p)
- y[Li[p]] -= internal::conj(Lx[p]) * yi;
- d -= internal::real(l_ki * internal::conj(yi));
+ y[Li[p]] -= numext::conj(Lx[p]) * yi;
+ d -= numext::real(l_ki * numext::conj(yi));
Li[p] = k; /* store L(k,i) in column form of L */
Lx[p] = l_ki;
++m_nonZerosPerCol[i]; /* increment count of nonzeros in col i */
diff --git a/Eigen/src/SparseCore/SparseBlock.h b/Eigen/src/SparseCore/SparseBlock.h
index e025e4d40..0b3e193db 100644
--- a/Eigen/src/SparseCore/SparseBlock.h
+++ b/Eigen/src/SparseCore/SparseBlock.h
@@ -27,6 +27,7 @@ public:
class InnerIterator: public XprType::InnerIterator
{
+ typedef typename BlockImpl::Index Index;
public:
inline InnerIterator(const BlockType& xpr, Index outer)
: XprType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
@@ -38,6 +39,7 @@ public:
};
class ReverseInnerIterator: public XprType::ReverseInnerIterator
{
+ typedef typename BlockImpl::Index Index;
public:
inline ReverseInnerIterator(const BlockType& xpr, Index outer)
: XprType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
diff --git a/Eigen/src/SparseCore/SparseCwiseBinaryOp.h b/Eigen/src/SparseCore/SparseCwiseBinaryOp.h
index d5f97f78f..ec86ca933 100644
--- a/Eigen/src/SparseCore/SparseCwiseBinaryOp.h
+++ b/Eigen/src/SparseCore/SparseCwiseBinaryOp.h
@@ -73,7 +73,7 @@ class CwiseBinaryOpImpl<BinaryOp,Lhs,Rhs,Sparse>::InnerIterator
typedef internal::sparse_cwise_binary_op_inner_iterator_selector<
BinaryOp,Lhs,Rhs, InnerIterator> Base;
- EIGEN_STRONG_INLINE InnerIterator(const CwiseBinaryOpImpl& binOp, typename CwiseBinaryOpImpl::Index outer)
+ EIGEN_STRONG_INLINE InnerIterator(const CwiseBinaryOpImpl& binOp, Index outer)
: Base(binOp.derived(),outer)
{}
};
@@ -300,7 +300,7 @@ template<typename OtherDerived>
EIGEN_STRONG_INLINE Derived &
SparseMatrixBase<Derived>::operator-=(const SparseMatrixBase<OtherDerived> &other)
{
- return *this = derived() - other.derived();
+ return derived() = derived() - other.derived();
}
template<typename Derived>
@@ -308,7 +308,7 @@ template<typename OtherDerived>
EIGEN_STRONG_INLINE Derived &
SparseMatrixBase<Derived>::operator+=(const SparseMatrixBase<OtherDerived>& other)
{
- return *this = derived() + other.derived();
+ return derived() = derived() + other.derived();
}
template<typename Derived>
diff --git a/Eigen/src/SparseCore/SparseDenseProduct.h b/Eigen/src/SparseCore/SparseDenseProduct.h
index 8c608a622..30975c29c 100644
--- a/Eigen/src/SparseCore/SparseDenseProduct.h
+++ b/Eigen/src/SparseCore/SparseDenseProduct.h
@@ -111,6 +111,7 @@ template<typename Lhs, typename Rhs, bool Transpose>
class SparseDenseOuterProduct<Lhs,Rhs,Transpose>::InnerIterator : public _LhsNested::InnerIterator
{
typedef typename _LhsNested::InnerIterator Base;
+ typedef typename SparseDenseOuterProduct::Index Index;
public:
EIGEN_STRONG_INLINE InnerIterator(const SparseDenseOuterProduct& prod, Index outer)
: Base(prod.lhs(), 0), m_outer(outer), m_factor(prod.rhs().coeff(outer))
diff --git a/Eigen/src/SparseCore/SparseDiagonalProduct.h b/Eigen/src/SparseCore/SparseDiagonalProduct.h
index 5ec4018e6..1bb590e64 100644
--- a/Eigen/src/SparseCore/SparseDiagonalProduct.h
+++ b/Eigen/src/SparseCore/SparseDiagonalProduct.h
@@ -78,7 +78,11 @@ class SparseDiagonalProduct
EIGEN_SPARSE_PUBLIC_INTERFACE(SparseDiagonalProduct)
typedef internal::sparse_diagonal_product_inner_iterator_selector
- <_LhsNested,_RhsNested,SparseDiagonalProduct,LhsMode,RhsMode> InnerIterator;
+ <_LhsNested,_RhsNested,SparseDiagonalProduct,LhsMode,RhsMode> InnerIterator;
+
+ // We do not want ReverseInnerIterator for diagonal-sparse products,
+ // but this dummy declaration is needed to make diag * sparse * diag compile.
+ class ReverseInnerIterator;
EIGEN_STRONG_INLINE SparseDiagonalProduct(const Lhs& lhs, const Rhs& rhs)
: m_lhs(lhs), m_rhs(rhs)
@@ -118,13 +122,13 @@ class sparse_diagonal_product_inner_iterator_selector
<Lhs,Rhs,SparseDiagonalProductType,SDP_IsDiagonal,SDP_IsSparseColMajor>
: public CwiseBinaryOp<
scalar_product_op<typename Lhs::Scalar>,
- typename Rhs::ConstInnerVectorReturnType,
- typename Lhs::DiagonalVectorType>::InnerIterator
+ const typename Rhs::ConstInnerVectorReturnType,
+ const typename Lhs::DiagonalVectorType>::InnerIterator
{
typedef typename CwiseBinaryOp<
scalar_product_op<typename Lhs::Scalar>,
- typename Rhs::ConstInnerVectorReturnType,
- typename Lhs::DiagonalVectorType>::InnerIterator Base;
+ const typename Rhs::ConstInnerVectorReturnType,
+ const typename Lhs::DiagonalVectorType>::InnerIterator Base;
typedef typename Lhs::Index Index;
Index m_outer;
public:
@@ -156,13 +160,13 @@ class sparse_diagonal_product_inner_iterator_selector
<Lhs,Rhs,SparseDiagonalProductType,SDP_IsSparseRowMajor,SDP_IsDiagonal>
: public CwiseBinaryOp<
scalar_product_op<typename Rhs::Scalar>,
- typename Lhs::ConstInnerVectorReturnType,
- Transpose<const typename Rhs::DiagonalVectorType> >::InnerIterator
+ const typename Lhs::ConstInnerVectorReturnType,
+ const Transpose<const typename Rhs::DiagonalVectorType> >::InnerIterator
{
typedef typename CwiseBinaryOp<
scalar_product_op<typename Rhs::Scalar>,
- typename Lhs::ConstInnerVectorReturnType,
- Transpose<const typename Rhs::DiagonalVectorType> >::InnerIterator Base;
+ const typename Lhs::ConstInnerVectorReturnType,
+ const Transpose<const typename Rhs::DiagonalVectorType> >::InnerIterator Base;
typedef typename Lhs::Index Index;
Index m_outer;
public:
diff --git a/Eigen/src/SparseCore/SparseDot.h b/Eigen/src/SparseCore/SparseDot.h
index dfeb3a8df..db39c9aec 100644
--- a/Eigen/src/SparseCore/SparseDot.h
+++ b/Eigen/src/SparseCore/SparseDot.h
@@ -30,7 +30,7 @@ SparseMatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
Scalar res(0);
while (i)
{
- res += internal::conj(i.value()) * other.coeff(i.index());
+ res += numext::conj(i.value()) * other.coeff(i.index());
++i;
}
return res;
@@ -64,7 +64,7 @@ SparseMatrixBase<Derived>::dot(const SparseMatrixBase<OtherDerived>& other) cons
{
if (i.index()==j.index())
{
- res += internal::conj(i.value()) * j.value();
+ res += numext::conj(i.value()) * j.value();
++i; ++j;
}
else if (i.index()<j.index())
@@ -79,7 +79,7 @@ template<typename Derived>
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
SparseMatrixBase<Derived>::squaredNorm() const
{
- return internal::real((*this).cwiseAbs2().sum());
+ return numext::real((*this).cwiseAbs2().sum());
}
template<typename Derived>
diff --git a/Eigen/src/SparseCore/SparseMatrix.h b/Eigen/src/SparseCore/SparseMatrix.h
index dc57f77fc..adceafe18 100644
--- a/Eigen/src/SparseCore/SparseMatrix.h
+++ b/Eigen/src/SparseCore/SparseMatrix.h
@@ -31,7 +31,7 @@ namespace Eigen {
*
* \tparam _Scalar the scalar type, i.e. the type of the coefficients
* \tparam _Options Union of bit flags controlling the storage scheme. Currently the only possibility
- * is RowMajor. The default is 0 which means column-major.
+ * is ColMajor or RowMajor. The default is 0 which means column-major.
* \tparam _Index the type of the indices. It has to be a \b signed type (e.g., short, int, std::ptrdiff_t). Default is \c int.
*
* This class can be extended with the help of the plugin mechanism described on the page
@@ -170,6 +170,8 @@ class SparseMatrix
* This function returns Scalar(0) if the element is an explicit \em zero */
inline Scalar coeff(Index row, Index col) const
{
+ eigen_assert(row>=0 && row<rows() && col>=0 && col<cols());
+
const Index outer = IsRowMajor ? row : col;
const Index inner = IsRowMajor ? col : row;
Index end = m_innerNonZeros ? m_outerIndex[outer] + m_innerNonZeros[outer] : m_outerIndex[outer+1];
@@ -186,6 +188,8 @@ class SparseMatrix
*/
inline Scalar& coeffRef(Index row, Index col)
{
+ eigen_assert(row>=0 && row<rows() && col>=0 && col<cols());
+
const Index outer = IsRowMajor ? row : col;
const Index inner = IsRowMajor ? col : row;
@@ -215,6 +219,8 @@ class SparseMatrix
*/
Scalar& insert(Index row, Index col)
{
+ eigen_assert(row>=0 && row<rows() && col>=0 && col<cols());
+
if(isCompressed())
{
reserve(VectorXi::Constant(outerSize(), 2));
@@ -281,7 +287,6 @@ class SparseMatrix
template<class SizesType>
inline void reserveInnerVectors(const SizesType& reserveSizes)
{
-
if(isCompressed())
{
std::size_t totalReserveSize = 0;
@@ -526,59 +531,63 @@ class SparseMatrix
*/
void conservativeResize(Index rows, Index cols)
{
- // No change
- if (this->rows() == rows && this->cols() == cols) return;
+ // No change
+ if (this->rows() == rows && this->cols() == cols) return;
+
+ // If one dimension is null, then there is nothing to be preserved
+ if(rows==0 || cols==0) return resize(rows,cols);
- Index innerChange = IsRowMajor ? cols - this->cols() : rows - this->rows();
- Index outerChange = IsRowMajor ? rows - this->rows() : cols - this->cols();
- Index newInnerSize = IsRowMajor ? cols : rows;
+ Index innerChange = IsRowMajor ? cols - this->cols() : rows - this->rows();
+ Index outerChange = IsRowMajor ? rows - this->rows() : cols - this->cols();
+ Index newInnerSize = IsRowMajor ? cols : rows;
- // Deals with inner non zeros
- if (m_innerNonZeros)
- {
- // Resize m_innerNonZeros
- Index *newInnerNonZeros = static_cast<Index*>(std::realloc(m_innerNonZeros, (m_outerSize + outerChange) * sizeof(Index)));
- if (!newInnerNonZeros) internal::throw_std_bad_alloc();
- m_innerNonZeros = newInnerNonZeros;
-
- for(Index i=m_outerSize; i<m_outerSize+outerChange; i++)
- m_innerNonZeros[i] = 0;
- }
- else if (innerChange < 0)
- {
- // Inner size decreased: allocate a new m_innerNonZeros
- m_innerNonZeros = static_cast<Index*>(std::malloc((m_outerSize+outerChange+1) * sizeof(Index)));
- if (!m_innerNonZeros) internal::throw_std_bad_alloc();
- for(Index i = 0; i < m_outerSize; i++)
- m_innerNonZeros[i] = m_outerIndex[i+1] - m_outerIndex[i];
- }
+ // Deals with inner non zeros
+ if (m_innerNonZeros)
+ {
+ // Resize m_innerNonZeros
+ Index *newInnerNonZeros = static_cast<Index*>(std::realloc(m_innerNonZeros, (m_outerSize + outerChange) * sizeof(Index)));
+ if (!newInnerNonZeros) internal::throw_std_bad_alloc();
+ m_innerNonZeros = newInnerNonZeros;
- // Change the m_innerNonZeros in case of a decrease of inner size
- if (m_innerNonZeros && innerChange < 0) {
- for(Index i = 0; i < m_outerSize + (std::min)(outerChange, Index(0)); i++)
- {
- Index &n = m_innerNonZeros[i];
- Index start = m_outerIndex[i];
- while (n > 0 && m_data.index(start+n-1) >= newInnerSize) --n;
- }
+ for(Index i=m_outerSize; i<m_outerSize+outerChange; i++)
+ m_innerNonZeros[i] = 0;
+ }
+ else if (innerChange < 0)
+ {
+ // Inner size decreased: allocate a new m_innerNonZeros
+ m_innerNonZeros = static_cast<Index*>(std::malloc((m_outerSize+outerChange+1) * sizeof(Index)));
+ if (!m_innerNonZeros) internal::throw_std_bad_alloc();
+ for(Index i = 0; i < m_outerSize; i++)
+ m_innerNonZeros[i] = m_outerIndex[i+1] - m_outerIndex[i];
+ }
+
+ // Change the m_innerNonZeros in case of a decrease of inner size
+ if (m_innerNonZeros && innerChange < 0)
+ {
+ for(Index i = 0; i < m_outerSize + (std::min)(outerChange, Index(0)); i++)
+ {
+ Index &n = m_innerNonZeros[i];
+ Index start = m_outerIndex[i];
+ while (n > 0 && m_data.index(start+n-1) >= newInnerSize) --n;
}
-
- m_innerSize = newInnerSize;
+ }
+
+ m_innerSize = newInnerSize;
- // Re-allocate outer index structure if necessary
- if (outerChange == 0)
- return;
-
- Index *newOuterIndex = static_cast<Index*>(std::realloc(m_outerIndex, (m_outerSize + outerChange + 1) * sizeof(Index)));
- if (!newOuterIndex) internal::throw_std_bad_alloc();
- m_outerIndex = newOuterIndex;
- if (outerChange > 0) {
- Index last = m_outerSize == 0 ? 0 : m_outerIndex[m_outerSize];
- for(Index i=m_outerSize; i<m_outerSize+outerChange+1; i++)
- m_outerIndex[i] = last;
- }
- m_outerSize += outerChange;
-
+ // Re-allocate outer index structure if necessary
+ if (outerChange == 0)
+ return;
+
+ Index *newOuterIndex = static_cast<Index*>(std::realloc(m_outerIndex, (m_outerSize + outerChange + 1) * sizeof(Index)));
+ if (!newOuterIndex) internal::throw_std_bad_alloc();
+ m_outerIndex = newOuterIndex;
+ if (outerChange > 0)
+ {
+ Index last = m_outerSize == 0 ? 0 : m_outerIndex[m_outerSize];
+ for(Index i=m_outerSize; i<m_outerSize+outerChange+1; i++)
+ m_outerIndex[i] = last;
+ }
+ m_outerSize += outerChange;
}
/** Resizes the matrix to a \a rows x \a cols matrix and initializes it to zero.
@@ -637,9 +646,20 @@ class SparseMatrix
inline SparseMatrix(const SparseMatrixBase<OtherDerived>& other)
: m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0)
{
+ EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
+ YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
check_template_parameters();
*this = other.derived();
}
+
+ /** Constructs a sparse matrix from the sparse selfadjoint view \a other */
+ template<typename OtherDerived, unsigned int UpLo>
+ inline SparseMatrix(const SparseSelfAdjointView<OtherDerived, UpLo>& other)
+ : m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0)
+ {
+ check_template_parameters();
+ *this = other;
+ }
/** Copy constructor (it performs a deep copy) */
inline SparseMatrix(const SparseMatrix& other)
@@ -671,13 +691,22 @@ class SparseMatrix
m_data.swap(other.m_data);
}
+ /** Sets *this to the identity matrix */
+ inline void setIdentity()
+ {
+ eigen_assert(rows() == cols() && "ONLY FOR SQUARED MATRICES");
+ this->m_data.resize(rows());
+ Eigen::Map<Matrix<Index, Dynamic, 1> >(&this->m_data.index(0), rows()).setLinSpaced(0, rows()-1);
+ Eigen::Map<Matrix<Scalar, Dynamic, 1> >(&this->m_data.value(0), rows()).setOnes();
+ Eigen::Map<Matrix<Index, Dynamic, 1> >(this->m_outerIndex, rows()+1).setLinSpaced(0, rows());
+ }
inline SparseMatrix& operator=(const SparseMatrix& other)
{
if (other.isRValue())
{
swap(other.const_cast_derived());
}
- else
+ else if(this!=&other)
{
initAssignment(other);
if(other.isCompressed())
@@ -822,6 +851,7 @@ private:
static void check_template_parameters()
{
EIGEN_STATIC_ASSERT(NumTraits<Index>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
+ EIGEN_STATIC_ASSERT((Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS);
}
struct default_prunning_func {
@@ -911,19 +941,25 @@ void set_from_triplets(const InputIterator& begin, const InputIterator& end, Spa
typedef typename SparseMatrixType::Scalar Scalar;
SparseMatrix<Scalar,IsRowMajor?ColMajor:RowMajor> trMat(mat.rows(),mat.cols());
- // pass 1: count the nnz per inner-vector
- VectorXi wi(trMat.outerSize());
- wi.setZero();
- for(InputIterator it(begin); it!=end; ++it)
- wi(IsRowMajor ? it->col() : it->row())++;
+ if(begin<end)
+ {
+ // pass 1: count the nnz per inner-vector
+ VectorXi wi(trMat.outerSize());
+ wi.setZero();
+ for(InputIterator it(begin); it!=end; ++it)
+ {
+ eigen_assert(it->row()>=0 && it->row()<mat.rows() && it->col()>=0 && it->col()<mat.cols());
+ wi(IsRowMajor ? it->col() : it->row())++;
+ }
- // pass 2: insert all the elements into trMat
- trMat.reserve(wi);
- for(InputIterator it(begin); it!=end; ++it)
- trMat.insertBackUncompressed(it->row(),it->col()) = it->value();
+ // pass 2: insert all the elements into trMat
+ trMat.reserve(wi);
+ for(InputIterator it(begin); it!=end; ++it)
+ trMat.insertBackUncompressed(it->row(),it->col()) = it->value();
- // pass 3:
- trMat.sumupDuplicates();
+ // pass 3:
+ trMat.sumupDuplicates();
+ }
// pass 4: transposed copy -> implicit sorting
mat = trMat;
@@ -1020,6 +1056,9 @@ template<typename Scalar, int _Options, typename _Index>
template<typename OtherDerived>
EIGEN_DONT_INLINE SparseMatrix<Scalar,_Options,_Index>& SparseMatrix<Scalar,_Options,_Index>::operator=(const SparseMatrixBase<OtherDerived>& other)
{
+ EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
+ YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
+
const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
if (needToTranspose)
{
diff --git a/Eigen/src/SparseCore/SparseMatrixBase.h b/Eigen/src/SparseCore/SparseMatrixBase.h
index 590339663..89ace19e5 100644
--- a/Eigen/src/SparseCore/SparseMatrixBase.h
+++ b/Eigen/src/SparseCore/SparseMatrixBase.h
@@ -89,6 +89,9 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
*/
IsRowMajor = Flags&RowMajorBit ? 1 : 0,
+
+ InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
+ : int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
#ifndef EIGEN_PARSED_BY_DOXYGEN
_HasDirectAccess = (int(Flags)&DirectAccessBit) ? 1 : 0 // workaround sunCC
@@ -322,8 +325,8 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
typename internal::traits<OtherDerived>::Scalar \
>::ReturnType \
>, \
- Derived, \
- OtherDerived \
+ const Derived, \
+ const OtherDerived \
>
template<typename OtherDerived>
@@ -403,20 +406,20 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
Block<Derived,Dynamic,Dynamic,true> innerVectors(Index outerStart, Index outerSize);
const Block<const Derived,Dynamic,Dynamic,true> innerVectors(Index outerStart, Index outerSize) const;
- /** \internal use operator= */
- template<typename DenseDerived>
- void evalTo(MatrixBase<DenseDerived>& dst) const
- {
- dst.setZero();
- for (Index j=0; j<outerSize(); ++j)
- for (typename Derived::InnerIterator i(derived(),j); i; ++i)
- dst.coeffRef(i.row(),i.col()) = i.value();
- }
+ /** \internal use operator= */
+ template<typename DenseDerived>
+ void evalTo(MatrixBase<DenseDerived>& dst) const
+ {
+ dst.setZero();
+ for (Index j=0; j<outerSize(); ++j)
+ for (typename Derived::InnerIterator i(derived(),j); i; ++i)
+ dst.coeffRef(i.row(),i.col()) = i.value();
+ }
- Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> toDense() const
- {
- return derived();
- }
+ Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> toDense() const
+ {
+ return derived();
+ }
template<typename OtherDerived>
bool isApprox(const SparseMatrixBase<OtherDerived>& other,
diff --git a/Eigen/src/SparseCore/SparseSelfAdjointView.h b/Eigen/src/SparseCore/SparseSelfAdjointView.h
index 9630b60f5..80e794411 100644
--- a/Eigen/src/SparseCore/SparseSelfAdjointView.h
+++ b/Eigen/src/SparseCore/SparseSelfAdjointView.h
@@ -69,6 +69,30 @@ template<typename MatrixType, unsigned int UpLo> class SparseSelfAdjointView
const _MatrixTypeNested& matrix() const { return m_matrix; }
_MatrixTypeNested& matrix() { return m_matrix.const_cast_derived(); }
+ /** \returns an expression of the matrix product between a sparse self-adjoint matrix \c *this and a sparse matrix \a rhs.
+ *
+ * Note that there is no algorithmic advantage of performing such a product compared to a general sparse-sparse matrix product.
+ * Indeed, the SparseSelfadjointView operand is first copied into a temporary SparseMatrix before computing the product.
+ */
+ template<typename OtherDerived>
+ SparseSparseProduct<SparseMatrix<Scalar, ((internal::traits<OtherDerived>::Flags&RowMajorBit) ? RowMajor : ColMajor),Index>, OtherDerived>
+ operator*(const SparseMatrixBase<OtherDerived>& rhs) const
+ {
+ return SparseSparseProduct<SparseMatrix<Scalar, (internal::traits<OtherDerived>::Flags&RowMajorBit) ? RowMajor : ColMajor, Index>, OtherDerived>(*this, rhs.derived());
+ }
+
+ /** \returns an expression of the matrix product between a sparse matrix \a lhs and a sparse self-adjoint matrix \a rhs.
+ *
+ * Note that there is no algorithmic advantage of performing such a product compared to a general sparse-sparse matrix product.
+ * Indeed, the SparseSelfadjointView operand is first copied into a temporary SparseMatrix before computing the product.
+ */
+ template<typename OtherDerived> friend
+ SparseSparseProduct<OtherDerived, SparseMatrix<Scalar, ((internal::traits<OtherDerived>::Flags&RowMajorBit) ? RowMajor : ColMajor),Index> >
+ operator*(const SparseMatrixBase<OtherDerived>& lhs, const SparseSelfAdjointView& rhs)
+ {
+ return SparseSparseProduct< OtherDerived, SparseMatrix<Scalar, (internal::traits<OtherDerived>::Flags&RowMajorBit) ? RowMajor : ColMajor, Index> >(lhs.derived(), rhs.derived());
+ }
+
/** Efficient sparse self-adjoint matrix times dense vector/matrix product */
template<typename OtherDerived>
SparseSelfAdjointTimeDenseProduct<MatrixType,OtherDerived,UpLo>
@@ -240,7 +264,7 @@ class SparseSelfAdjointTimeDenseProduct
Index b = LhsIsRowMajor ? i.index() : j;
typename Lhs::Scalar v = i.value();
dest.row(a) += (v) * m_rhs.row(b);
- dest.row(b) += internal::conj(v) * m_rhs.row(a);
+ dest.row(b) += numext::conj(v) * m_rhs.row(a);
}
if (ProcessFirstHalf && i && (i.index()==j))
dest.row(j) += i.value() * m_rhs.row(j);
@@ -367,7 +391,7 @@ void permute_symm_to_fullsymm(const MatrixType& mat, SparseMatrix<typename Matri
dest.valuePtr()[k] = it.value();
k = count[ip]++;
dest.innerIndexPtr()[k] = jp;
- dest.valuePtr()[k] = internal::conj(it.value());
+ dest.valuePtr()[k] = numext::conj(it.value());
}
}
}
@@ -428,7 +452,7 @@ void permute_symm_to_symm(const MatrixType& mat, SparseMatrix<typename MatrixTyp
if(!StorageOrderMatch) std::swap(ip,jp);
if( ((int(DstUpLo)==int(Lower) && ip<jp) || (int(DstUpLo)==int(Upper) && ip>jp)))
- dest.valuePtr()[k] = conj(it.value());
+ dest.valuePtr()[k] = numext::conj(it.value());
else
dest.valuePtr()[k] = it.value();
}
@@ -461,7 +485,10 @@ class SparseSymmetricPermutationProduct
template<typename DestScalar, int Options, typename DstIndex>
void evalTo(SparseMatrix<DestScalar,Options,DstIndex>& _dest) const
{
- internal::permute_symm_to_fullsymm<UpLo>(m_matrix,_dest,m_perm.indices().data());
+// internal::permute_symm_to_fullsymm<UpLo>(m_matrix,_dest,m_perm.indices().data());
+ SparseMatrix<DestScalar,(Options&RowMajor)==RowMajor ? ColMajor : RowMajor, DstIndex> tmp;
+ internal::permute_symm_to_fullsymm<UpLo>(m_matrix,tmp,m_perm.indices().data());
+ _dest = tmp;
}
template<typename DestType,unsigned int DestUpLo> void evalTo(SparseSelfAdjointView<DestType,DestUpLo>& dest) const
diff --git a/Eigen/src/SparseCore/SparseTranspose.h b/Eigen/src/SparseCore/SparseTranspose.h
index c78c20a2f..7c300ee8d 100644
--- a/Eigen/src/SparseCore/SparseTranspose.h
+++ b/Eigen/src/SparseCore/SparseTranspose.h
@@ -34,26 +34,28 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Sparse>::InnerItera
: public _MatrixTypeNested::InnerIterator
{
typedef typename _MatrixTypeNested::InnerIterator Base;
+ typedef typename TransposeImpl::Index Index;
public:
EIGEN_STRONG_INLINE InnerIterator(const TransposeImpl& trans, typename TransposeImpl<MatrixType,Sparse>::Index outer)
: Base(trans.derived().nestedExpression(), outer)
{}
- inline typename TransposeImpl<MatrixType,Sparse>::Index row() const { return Base::col(); }
- inline typename TransposeImpl<MatrixType,Sparse>::Index col() const { return Base::row(); }
+ Index row() const { return Base::col(); }
+ Index col() const { return Base::row(); }
};
template<typename MatrixType> class TransposeImpl<MatrixType,Sparse>::ReverseInnerIterator
: public _MatrixTypeNested::ReverseInnerIterator
{
typedef typename _MatrixTypeNested::ReverseInnerIterator Base;
+ typedef typename TransposeImpl::Index Index;
public:
EIGEN_STRONG_INLINE ReverseInnerIterator(const TransposeImpl& xpr, typename TransposeImpl<MatrixType,Sparse>::Index outer)
: Base(xpr.derived().nestedExpression(), outer)
{}
- inline typename TransposeImpl<MatrixType,Sparse>::Index row() const { return Base::col(); }
- inline typename TransposeImpl<MatrixType,Sparse>::Index col() const { return Base::row(); }
+ Index row() const { return Base::col(); }
+ Index col() const { return Base::row(); }
};
} // end namespace Eigen
diff --git a/Eigen/src/SparseCore/SparseTriangularView.h b/Eigen/src/SparseCore/SparseTriangularView.h
index 477e4bd94..333127b78 100644
--- a/Eigen/src/SparseCore/SparseTriangularView.h
+++ b/Eigen/src/SparseCore/SparseTriangularView.h
@@ -2,6 +2,7 @@
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
@@ -27,6 +28,7 @@ template<typename MatrixType, int Mode> class SparseTriangularView
enum { SkipFirst = ((Mode&Lower) && !(MatrixType::Flags&RowMajorBit))
|| ((Mode&Upper) && (MatrixType::Flags&RowMajorBit)),
SkipLast = !SkipFirst,
+ SkipDiag = (Mode&ZeroDiag) ? 1 : 0,
HasUnitDiag = (Mode&UnitDiag) ? 1 : 0
};
@@ -64,6 +66,7 @@ template<typename MatrixType, int Mode>
class SparseTriangularView<MatrixType,Mode>::InnerIterator : public MatrixTypeNestedCleaned::InnerIterator
{
typedef typename MatrixTypeNestedCleaned::InnerIterator Base;
+ typedef typename SparseTriangularView::Index Index;
public:
EIGEN_STRONG_INLINE InnerIterator(const SparseTriangularView& view, Index outer)
@@ -71,7 +74,7 @@ class SparseTriangularView<MatrixType,Mode>::InnerIterator : public MatrixTypeNe
{
if(SkipFirst)
{
- while((*this) && (HasUnitDiag ? this->index()<=outer : this->index()<outer))
+ while((*this) && ((HasUnitDiag||SkipDiag) ? this->index()<=outer : this->index()<outer))
Base::operator++();
if(HasUnitDiag)
m_returnOne = true;
@@ -101,8 +104,8 @@ class SparseTriangularView<MatrixType,Mode>::InnerIterator : public MatrixTypeNe
return *this;
}
- inline Index row() const { return Base::row(); }
- inline Index col() const { return Base::col(); }
+ inline Index row() const { return (MatrixType::Flags&RowMajorBit ? Base::outer() : this->index()); }
+ inline Index col() const { return (MatrixType::Flags&RowMajorBit ? this->index() : Base::outer()); }
inline Index index() const
{
if(HasUnitDiag && m_returnOne) return Base::outer();
@@ -118,7 +121,12 @@ class SparseTriangularView<MatrixType,Mode>::InnerIterator : public MatrixTypeNe
{
if(HasUnitDiag && m_returnOne)
return true;
- return (SkipFirst ? Base::operator bool() : (Base::operator bool() && this->index() <= this->outer()));
+ if(SkipFirst) return Base::operator bool();
+ else
+ {
+ if (SkipDiag) return (Base::operator bool() && this->index() < this->outer());
+ else return (Base::operator bool() && this->index() <= this->outer());
+ }
}
protected:
bool m_returnOne;
@@ -128,18 +136,20 @@ template<typename MatrixType, int Mode>
class SparseTriangularView<MatrixType,Mode>::ReverseInnerIterator : public MatrixTypeNestedCleaned::ReverseInnerIterator
{
typedef typename MatrixTypeNestedCleaned::ReverseInnerIterator Base;
+ typedef typename SparseTriangularView::Index Index;
public:
EIGEN_STRONG_INLINE ReverseInnerIterator(const SparseTriangularView& view, Index outer)
: Base(view.nestedExpression(), outer)
{
eigen_assert((!HasUnitDiag) && "ReverseInnerIterator does not support yet triangular views with a unit diagonal");
- if(SkipLast)
- while((*this) && this->index()>outer)
+ if(SkipLast) {
+ while((*this) && (SkipDiag ? this->index()>=outer : this->index()>outer))
--(*this);
+ }
}
- EIGEN_STRONG_INLINE InnerIterator& operator--()
+ EIGEN_STRONG_INLINE ReverseInnerIterator& operator--()
{ Base::operator--(); return *this; }
inline Index row() const { return Base::row(); }
@@ -147,7 +157,12 @@ class SparseTriangularView<MatrixType,Mode>::ReverseInnerIterator : public Matri
EIGEN_STRONG_INLINE operator bool() const
{
- return SkipLast ? Base::operator bool() : (Base::operator bool() && this->index() >= this->outer());
+ if (SkipLast) return Base::operator bool() ;
+ else
+ {
+ if(SkipDiag) return (Base::operator bool() && this->index() > this->outer());
+ else return (Base::operator bool() && this->index() >= this->outer());
+ }
}
};
diff --git a/Eigen/src/SparseCore/SparseUtil.h b/Eigen/src/SparseCore/SparseUtil.h
index d58b51356..064a40707 100644
--- a/Eigen/src/SparseCore/SparseUtil.h
+++ b/Eigen/src/SparseCore/SparseUtil.h
@@ -98,16 +98,16 @@ template<typename T> struct eval<T,Sparse>
template<typename T,int Cols> struct sparse_eval<T,1,Cols> {
typedef typename traits<T>::Scalar _Scalar;
- enum { _Flags = traits<T>::Flags| RowMajorBit };
+ typedef typename traits<T>::Index _Index;
public:
- typedef SparseVector<_Scalar, _Flags> type;
+ typedef SparseVector<_Scalar, RowMajor, _Index> type;
};
template<typename T,int Rows> struct sparse_eval<T,Rows,1> {
typedef typename traits<T>::Scalar _Scalar;
- enum { _Flags = traits<T>::Flags & (~RowMajorBit) };
+ typedef typename traits<T>::Index _Index;
public:
- typedef SparseVector<_Scalar, _Flags> type;
+ typedef SparseVector<_Scalar, ColMajor, _Index> type;
};
template<typename T,int Rows,int Cols> struct sparse_eval {
@@ -127,12 +127,10 @@ template<typename T> struct sparse_eval<T,1,1> {
template<typename T> struct plain_matrix_type<T,Sparse>
{
typedef typename traits<T>::Scalar _Scalar;
- enum {
- _Flags = traits<T>::Flags
- };
-
+ typedef typename traits<T>::Index _Index;
+ enum { _Options = ((traits<T>::Flags&RowMajorBit)==RowMajorBit) ? RowMajor : ColMajor };
public:
- typedef SparseMatrix<_Scalar, _Flags> type;
+ typedef SparseMatrix<_Scalar, _Options, _Index> type;
};
} // end namespace internal
diff --git a/Eigen/src/SparseCore/SparseVector.h b/Eigen/src/SparseCore/SparseVector.h
index cd1e76070..7e15c814b 100644
--- a/Eigen/src/SparseCore/SparseVector.h
+++ b/Eigen/src/SparseCore/SparseVector.h
@@ -45,6 +45,20 @@ struct traits<SparseVector<_Scalar, _Options, _Index> >
SupportedAccessPatterns = InnerRandomAccessPattern
};
};
+
+// Sparse-Vector-Assignment kinds:
+enum {
+ SVA_RuntimeSwitch,
+ SVA_Inner,
+ SVA_Outer
+};
+
+template< typename Dest, typename Src,
+ int AssignmentKind = !bool(Src::IsVectorAtCompileTime) ? SVA_RuntimeSwitch
+ : Src::InnerSizeAtCompileTime==1 ? SVA_Outer
+ : SVA_Inner>
+struct sparse_vector_assign_selector;
+
}
template<typename _Scalar, int _Options, typename _Index>
@@ -83,14 +97,18 @@ class SparseVector
inline Scalar coeff(Index row, Index col) const
{
- eigen_assert((IsColVector ? col : row)==0);
+ eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
return coeff(IsColVector ? row : col);
}
- inline Scalar coeff(Index i) const { return m_data.at(i); }
+ inline Scalar coeff(Index i) const
+ {
+ eigen_assert(i>=0 && i<m_size);
+ return m_data.at(i);
+ }
inline Scalar& coeffRef(Index row, Index col)
{
- eigen_assert((IsColVector ? col : row)==0);
+ eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
return coeff(IsColVector ? row : col);
}
@@ -102,6 +120,7 @@ class SparseVector
*/
inline Scalar& coeffRef(Index i)
{
+ eigen_assert(i>=0 && i<m_size);
return m_data.atWithInsertion(i);
}
@@ -135,6 +154,8 @@ class SparseVector
inline Scalar& insert(Index row, Index col)
{
+ eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
+
Index inner = IsColVector ? row : col;
Index outer = IsColVector ? col : row;
eigen_assert(outer==0);
@@ -142,6 +163,8 @@ class SparseVector
}
Scalar& insert(Index i)
{
+ eigen_assert(i>=0 && i<m_size);
+
Index startId = 0;
Index p = Index(m_data.size()) - 1;
// TODO smart realloc
@@ -184,22 +207,24 @@ class SparseVector
void resizeNonZeros(Index size) { m_data.resize(size); }
- inline SparseVector() : m_size(0) { resize(0); }
+ inline SparseVector() : m_size(0) { check_template_parameters(); resize(0); }
- inline SparseVector(Index size) : m_size(0) { resize(size); }
+ inline SparseVector(Index size) : m_size(0) { check_template_parameters(); resize(size); }
- inline SparseVector(Index rows, Index cols) : m_size(0) { resize(rows,cols); }
+ inline SparseVector(Index rows, Index cols) : m_size(0) { check_template_parameters(); resize(rows,cols); }
template<typename OtherDerived>
inline SparseVector(const SparseMatrixBase<OtherDerived>& other)
: m_size(0)
{
+ check_template_parameters();
*this = other.derived();
}
inline SparseVector(const SparseVector& other)
: SparseBase(other), m_size(0)
{
+ check_template_parameters();
*this = other.derived();
}
@@ -230,11 +255,10 @@ class SparseVector
template<typename OtherDerived>
inline SparseVector& operator=(const SparseMatrixBase<OtherDerived>& other)
{
- if ( (bool(OtherDerived::IsVectorAtCompileTime) && int(RowsAtCompileTime)!=int(OtherDerived::RowsAtCompileTime))
- || ((!bool(OtherDerived::IsVectorAtCompileTime)) && ( bool(IsColVector) ? other.cols()>1 : other.rows()>1 )))
- return assign(other.transpose());
- else
- return assign(other);
+ SparseVector tmp(other.size());
+ internal::sparse_vector_assign_selector<SparseVector,OtherDerived>::run(tmp,other.derived());
+ this->swap(tmp);
+ return *this;
}
#ifndef EIGEN_PARSED_BY_DOXYGEN
@@ -309,8 +333,12 @@ class SparseVector
# endif
protected:
- template<typename OtherDerived>
- EIGEN_DONT_INLINE SparseVector& assign(const SparseMatrixBase<OtherDerived>& _other);
+
+ static void check_template_parameters()
+ {
+ EIGEN_STATIC_ASSERT(NumTraits<Index>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
+ EIGEN_STATIC_ASSERT((_Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS);
+ }
Storage m_data;
Index m_size;
@@ -380,33 +408,40 @@ class SparseVector<Scalar,_Options,_Index>::ReverseInnerIterator
const Index m_start;
};
-template<typename Scalar, int _Options, typename _Index>
-template<typename OtherDerived>
-EIGEN_DONT_INLINE SparseVector<Scalar,_Options,_Index>& SparseVector<Scalar,_Options,_Index>::assign(const SparseMatrixBase<OtherDerived>& _other)
-{
- const OtherDerived& other(_other.derived());
- const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
- if(needToTranspose)
- {
- Index size = other.size();
- Index nnz = other.nonZeros();
- resize(size);
- reserve(nnz);
- for(Index i=0; i<size; ++i)
+namespace internal {
+
+template< typename Dest, typename Src>
+struct sparse_vector_assign_selector<Dest,Src,SVA_Inner> {
+ static void run(Dest& dst, const Src& src) {
+ eigen_internal_assert(src.innerSize()==src.size());
+ for(typename Src::InnerIterator it(src, 0); it; ++it)
+ dst.insert(it.index()) = it.value();
+ }
+};
+
+template< typename Dest, typename Src>
+struct sparse_vector_assign_selector<Dest,Src,SVA_Outer> {
+ static void run(Dest& dst, const Src& src) {
+ eigen_internal_assert(src.outerSize()==src.size());
+ for(typename Dest::Index i=0; i<src.size(); ++i)
{
- typename OtherDerived::InnerIterator it(other, i);
+ typename Src::InnerIterator it(src, i);
if(it)
- insert(i) = it.value();
+ dst.insert(i) = it.value();
}
- return *this;
}
- else
- {
- // there is no special optimization
- return Base::operator=(other);
+};
+
+template< typename Dest, typename Src>
+struct sparse_vector_assign_selector<Dest,Src,SVA_RuntimeSwitch> {
+ static void run(Dest& dst, const Src& src) {
+ if(src.outerSize()==1) sparse_vector_assign_selector<Dest,Src,SVA_Inner>::run(dst, src);
+ else sparse_vector_assign_selector<Dest,Src,SVA_Outer>::run(dst, src);
}
+};
+
}
-
+
} // end namespace Eigen
#endif // EIGEN_SPARSEVECTOR_H
diff --git a/Eigen/src/SparseCore/SparseView.h b/Eigen/src/SparseCore/SparseView.h
index 4fd0cb3d8..fd8450463 100644
--- a/Eigen/src/SparseCore/SparseView.h
+++ b/Eigen/src/SparseCore/SparseView.h
@@ -18,7 +18,7 @@ namespace internal {
template<typename MatrixType>
struct traits<SparseView<MatrixType> > : traits<MatrixType>
{
- typedef int Index;
+ typedef typename MatrixType::Index Index;
typedef Sparse StorageKind;
enum {
Flags = int(traits<MatrixType>::Flags) & (RowMajorBit)
@@ -56,6 +56,7 @@ protected:
template<typename MatrixType>
class SparseView<MatrixType>::InnerIterator : public _MatrixTypeNested::InnerIterator
{
+ typedef typename SparseView::Index Index;
public:
typedef typename _MatrixTypeNested::InnerIterator IterBase;
InnerIterator(const SparseView& view, Index outer) :
diff --git a/Eigen/src/SparseLU/SparseLU.h b/Eigen/src/SparseLU/SparseLU.h
index e78250084..dd9eab2c2 100644
--- a/Eigen/src/SparseLU/SparseLU.h
+++ b/Eigen/src/SparseLU/SparseLU.h
@@ -14,8 +14,10 @@
namespace Eigen {
-template <typename _MatrixType, typename _OrderingType> class SparseLU;
-template <typename MappedSparseMatrixType> struct SparseLUMatrixLReturnType;
+template <typename _MatrixType, typename _OrderingType = COLAMDOrdering<typename _MatrixType::Index> > class SparseLU;
+template <typename MappedSparseMatrixType> struct SparseLUMatrixLReturnType;
+template <typename MatrixLType, typename MatrixUType> struct SparseLUMatrixUReturnType;
+
/** \ingroup SparseLU_Module
* \class SparseLU
*
@@ -61,7 +63,7 @@ template <typename MappedSparseMatrixType> struct SparseLUMatrixLReturnType;
* "unsupported/Eigen/src/IterativeSolvers/Scaling.h"
*
* \tparam _MatrixType The type of the sparse matrix. It must be a column-major SparseMatrix<>
- * \tparam _OrderingType The ordering method to use, either AMD, COLAMD or METIS
+ * \tparam _OrderingType The ordering method to use, either AMD, COLAMD or METIS. Default is COLMAD
*
*
* \sa \ref TutorialSparseDirectSolvers
@@ -84,11 +86,11 @@ class SparseLU : public internal::SparseLUImpl<typename _MatrixType::Scalar, typ
typedef internal::SparseLUImpl<Scalar, Index> Base;
public:
- SparseLU():m_isInitialized(true),m_lastError(""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1.0)
+ SparseLU():m_isInitialized(true),m_lastError(""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1.0),m_detPermR(1)
{
initperfvalues();
}
- SparseLU(const MatrixType& matrix):m_isInitialized(true),m_lastError(""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1.0)
+ SparseLU(const MatrixType& matrix):m_isInitialized(true),m_lastError(""),m_Ustore(0,0,0,0,0,0),m_symmetricmode(false),m_diagpivotthresh(1.0),m_detPermR(1)
{
initperfvalues();
compute(matrix);
@@ -104,9 +106,9 @@ class SparseLU : public internal::SparseLUImpl<typename _MatrixType::Scalar, typ
void simplicialfactorize(const MatrixType& matrix);
/**
- * Compute the symbolic and numeric factorization of the input sparse matrix.
- * The input matrix should be in column-major storage.
- */
+ * Compute the symbolic and numeric factorization of the input sparse matrix.
+ * The input matrix should be in column-major storage.
+ */
void compute (const MatrixType& matrix)
{
// Analyze
@@ -123,16 +125,43 @@ class SparseLU : public internal::SparseLUImpl<typename _MatrixType::Scalar, typ
m_symmetricmode = sym;
}
- /** Returns an expression of the matrix L, internally stored as supernodes
- * For a triangular solve with this matrix, use
- * \code
- * y = b; matrixL().solveInPlace(y);
- * \endcode
- */
+ /** \returns an expression of the matrix L, internally stored as supernodes
+ * The only operation available with this expression is the triangular solve
+ * \code
+ * y = b; matrixL().solveInPlace(y);
+ * \endcode
+ */
SparseLUMatrixLReturnType<SCMatrix> matrixL() const
{
return SparseLUMatrixLReturnType<SCMatrix>(m_Lstore);
}
+ /** \returns an expression of the matrix U,
+ * The only operation available with this expression is the triangular solve
+ * \code
+ * y = b; matrixU().solveInPlace(y);
+ * \endcode
+ */
+ SparseLUMatrixUReturnType<SCMatrix,MappedSparseMatrix<Scalar,ColMajor,Index> > matrixU() const
+ {
+ return SparseLUMatrixUReturnType<SCMatrix, MappedSparseMatrix<Scalar,ColMajor,Index> >(m_Lstore, m_Ustore);
+ }
+
+ /**
+ * \returns a reference to the row matrix permutation \f$ P_r \f$ such that \f$P_r A P_c^T = L U\f$
+ * \sa colsPermutation()
+ */
+ inline const PermutationType& rowsPermutation() const
+ {
+ return m_perm_r;
+ }
+ /**
+ * \returns a reference to the column matrix permutation\f$ P_c^T \f$ such that \f$P_r A P_c^T = L U\f$
+ * \sa rowsPermutation()
+ */
+ inline const PermutationType& colsPermutation() const
+ {
+ return m_perm_c;
+ }
/** Set the threshold used for a diagonal entry to be an acceptable pivot. */
void setPivotThreshold(const RealScalar& thresh)
{
@@ -154,7 +183,7 @@ class SparseLU : public internal::SparseLUImpl<typename _MatrixType::Scalar, typ
return internal::solve_retval<SparseLU, Rhs>(*this, B.derived());
}
- /** \returns the solution X of \f$ A X = B \f$ using the current decomposition of A.
+ /** \returns the solution X of \f$ A X = B \f$ using the current decomposition of A.
*
* \sa compute()
*/
@@ -167,7 +196,7 @@ class SparseLU : public internal::SparseLUImpl<typename _MatrixType::Scalar, typ
return internal::sparse_solve_retval<SparseLU, Rhs>(*this, B.derived());
}
- /** \brief Reports whether previous computation was successful.
+ /** \brief Reports whether previous computation was successful.
*
* \returns \c Success if computation was succesful,
* \c NumericalIssue if the LU factorization reports a problem, zero diagonal for instance
@@ -180,13 +209,15 @@ class SparseLU : public internal::SparseLUImpl<typename _MatrixType::Scalar, typ
eigen_assert(m_isInitialized && "Decomposition is not initialized.");
return m_info;
}
+
/**
- * \returns A string describing the type of error
- */
+ * \returns A string describing the type of error
+ */
std::string lastErrorMessage() const
{
return m_lastError;
}
+
template<typename Rhs, typename Dest>
bool _solve(const MatrixBase<Rhs> &B, MatrixBase<Dest> &_X) const
{
@@ -195,68 +226,97 @@ class SparseLU : public internal::SparseLUImpl<typename _MatrixType::Scalar, typ
EIGEN_STATIC_ASSERT((Dest::Flags&RowMajorBit)==0,
THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
-
- Index nrhs = B.cols();
- Index n = B.rows();
-
// Permute the right hand side to form X = Pr*B
// on return, X is overwritten by the computed solution
- X.resize(n,nrhs);
- for(Index j = 0; j < nrhs; ++j)
- X.col(j) = m_perm_r * B.col(j);
+ X.resize(B.rows(),B.cols());
+ for(Index j = 0; j < B.cols(); ++j)
+ X.col(j) = rowsPermutation() * B.col(j);
- //Forward substitution with L
-// m_Lstore.solveInPlace(X);
- this->matrixL().solveInPlace(X);
+ //Forward substitution with L
+ this->matrixL().solveInPlace(X);
+ this->matrixU().solveInPlace(X);
+
+ // Permute back the solution
+ for (Index j = 0; j < B.cols(); ++j)
+ X.col(j) = colsPermutation().inverse() * X.col(j);
- // Backward solve with U
- for (Index k = m_Lstore.nsuper(); k >= 0; k--)
+ return true;
+ }
+
+ /**
+ * \returns the absolute value of the determinant of the matrix of which
+ * *this is the QR decomposition.
+ *
+ * \warning a determinant can be very big or small, so for matrices
+ * of large enough dimension, there is a risk of overflow/underflow.
+ * One way to work around that is to use logAbsDeterminant() instead.
+ *
+ * \sa logAbsDeterminant(), signDeterminant()
+ */
+ Scalar absDeterminant()
+ {
+ eigen_assert(m_factorizationIsOk && "The matrix should be factorized first.");
+ // Initialize with the determinant of the row matrix
+ Scalar det = Scalar(1.);
+ //Note that the diagonal blocks of U are stored in supernodes,
+ // which are available in the L part :)
+ for (Index j = 0; j < this->cols(); ++j)
{
- Index fsupc = m_Lstore.supToCol()[k];
- Index lda = m_Lstore.colIndexPtr()[fsupc+1] - m_Lstore.colIndexPtr()[fsupc]; // leading dimension
- Index nsupc = m_Lstore.supToCol()[k+1] - fsupc;
- Index luptr = m_Lstore.colIndexPtr()[fsupc];
-
- if (nsupc == 1)
- {
- for (Index j = 0; j < nrhs; j++)
- {
- X(fsupc, j) /= m_Lstore.valuePtr()[luptr];
- }
- }
- else
- {
- Map<const Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > A( &(m_Lstore.valuePtr()[luptr]), nsupc, nsupc, OuterStride<>(lda) );
- Map< Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) );
- U = A.template triangularView<Upper>().solve(U);
- }
-
- for (Index j = 0; j < nrhs; ++j)
+ for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it)
{
- for (Index jcol = fsupc; jcol < fsupc + nsupc; jcol++)
+ if(it.row() < j) continue;
+ if(it.row() == j)
{
- typename MappedSparseMatrix<Scalar,ColMajor, Index>::InnerIterator it(m_Ustore, jcol);
- for ( ; it; ++it)
- {
- Index irow = it.index();
- X(irow, j) -= X(jcol, j) * it.value();
- }
+ det *= (std::abs)(it.value());
+ break;
}
}
- } // End For U-solve
-
- // Permute back the solution
- for (Index j = 0; j < nrhs; ++j)
- X.col(j) = m_perm_c.inverse() * X.col(j);
-
- return true;
- }
+ }
+ return det;
+ }
+
+ /** \returns the natural log of the absolute value of the determinant of the matrix
+ * of which **this is the QR decomposition
+ *
+ * \note This method is useful to work around the risk of overflow/underflow that's
+ * inherent to the determinant computation.
+ *
+ * \sa absDeterminant(), signDeterminant()
+ */
+ Scalar logAbsDeterminant() const
+ {
+ eigen_assert(m_factorizationIsOk && "The matrix should be factorized first.");
+ Scalar det = Scalar(0.);
+ for (Index j = 0; j < this->cols(); ++j)
+ {
+ for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it)
+ {
+ if(it.row() < j) continue;
+ if(it.row() == j)
+ {
+ det += (std::log)((std::abs)(it.value()));
+ break;
+ }
+ }
+ }
+ return det;
+ }
+
+ /** \returns A number representing the sign of the determinant
+ *
+ * \sa absDeterminant(), logAbsDeterminant()
+ */
+ Scalar signDeterminant()
+ {
+ eigen_assert(m_factorizationIsOk && "The matrix should be factorized first.");
+ return Scalar(m_detPermR);
+ }
protected:
// Functions
void initperfvalues()
{
- m_perfv.panel_size = 12;
+ m_perfv.panel_size = 1;
m_perfv.relax = 1;
m_perfv.maxsuper = 128;
m_perfv.rowblk = 16;
@@ -285,25 +345,26 @@ class SparseLU : public internal::SparseLUImpl<typename _MatrixType::Scalar, typ
internal::perfvalues<Index> m_perfv;
RealScalar m_diagpivotthresh; // Specifies the threshold used for a diagonal entry to be an acceptable pivot
Index m_nnzL, m_nnzU; // Nonzeros in L and U factors
-
+ Index m_detPermR; // Determinant of the coefficient matrix
private:
- // Copy constructor
- SparseLU (SparseLU& ) {}
+ // Disable copy constructor
+ SparseLU (const SparseLU& );
}; // End class SparseLU
+
// Functions needed by the anaysis phase
/**
- * Compute the column permutation to minimize the fill-in
- *
- * - Apply this permutation to the input matrix -
- *
- * - Compute the column elimination tree on the permuted matrix
- *
- * - Postorder the elimination tree and the column permutation
- *
- */
+ * Compute the column permutation to minimize the fill-in
+ *
+ * - Apply this permutation to the input matrix -
+ *
+ * - Compute the column elimination tree on the permuted matrix
+ *
+ * - Postorder the elimination tree and the column permutation
+ *
+ */
template <typename MatrixType, typename OrderingType>
void SparseLU<MatrixType, OrderingType>::analyzePattern(const MatrixType& mat)
{
@@ -319,11 +380,20 @@ void SparseLU<MatrixType, OrderingType>::analyzePattern(const MatrixType& mat)
if (m_perm_c.size()) {
m_mat.uncompress(); //NOTE: The effect of this command is only to create the InnerNonzeros pointers. FIXME : This vector is filled but not subsequently used.
//Then, permute only the column pointers
+ const Index * outerIndexPtr;
+ if (mat.isCompressed()) outerIndexPtr = mat.outerIndexPtr();
+ else
+ {
+ Index *outerIndexPtr_t = new Index[mat.cols()+1];
+ for(Index i = 0; i <= mat.cols(); i++) outerIndexPtr_t[i] = m_mat.outerIndexPtr()[i];
+ outerIndexPtr = outerIndexPtr_t;
+ }
for (Index i = 0; i < mat.cols(); i++)
{
- m_mat.outerIndexPtr()[m_perm_c.indices()(i)] = mat.outerIndexPtr()[i];
- m_mat.innerNonZeroPtr()[m_perm_c.indices()(i)] = mat.outerIndexPtr()[i+1] - mat.outerIndexPtr()[i];
+ m_mat.outerIndexPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i];
+ m_mat.innerNonZeroPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i+1] - outerIndexPtr[i];
}
+ if(!mat.isCompressed()) delete[] outerIndexPtr;
}
// Compute the column elimination tree of the permuted matrix
IndexVector firstRowElt;
@@ -361,23 +431,23 @@ void SparseLU<MatrixType, OrderingType>::analyzePattern(const MatrixType& mat)
/**
- * - Numerical factorization
- * - Interleaved with the symbolic factorization
- * On exit, info is
- *
- * = 0: successful factorization
- *
- * > 0: if info = i, and i is
- *
- * <= A->ncol: U(i,i) is exactly zero. The factorization has
- * been completed, but the factor U is exactly singular,
- * and division by zero will occur if it is used to solve a
- * system of equations.
- *
- * > A->ncol: number of bytes allocated when memory allocation
- * failure occurred, plus A->ncol. If lwork = -1, it is
- * the estimated amount of space needed, plus A->ncol.
- */
+ * - Numerical factorization
+ * - Interleaved with the symbolic factorization
+ * On exit, info is
+ *
+ * = 0: successful factorization
+ *
+ * > 0: if info = i, and i is
+ *
+ * <= A->ncol: U(i,i) is exactly zero. The factorization has
+ * been completed, but the factor U is exactly singular,
+ * and division by zero will occur if it is used to solve a
+ * system of equations.
+ *
+ * > A->ncol: number of bytes allocated when memory allocation
+ * failure occurred, plus A->ncol. If lwork = -1, it is
+ * the estimated amount of space needed, plus A->ncol.
+ */
template <typename MatrixType, typename OrderingType>
void SparseLU<MatrixType, OrderingType>::factorize(const MatrixType& matrix)
{
@@ -395,11 +465,20 @@ void SparseLU<MatrixType, OrderingType>::factorize(const MatrixType& matrix)
{
m_mat.uncompress(); //NOTE: The effect of this command is only to create the InnerNonzeros pointers.
//Then, permute only the column pointers
+ const Index * outerIndexPtr;
+ if (matrix.isCompressed()) outerIndexPtr = matrix.outerIndexPtr();
+ else
+ {
+ Index* outerIndexPtr_t = new Index[matrix.cols()+1];
+ for(Index i = 0; i <= matrix.cols(); i++) outerIndexPtr_t[i] = m_mat.outerIndexPtr()[i];
+ outerIndexPtr = outerIndexPtr_t;
+ }
for (Index i = 0; i < matrix.cols(); i++)
{
- m_mat.outerIndexPtr()[m_perm_c.indices()(i)] = matrix.outerIndexPtr()[i];
- m_mat.innerNonZeroPtr()[m_perm_c.indices()(i)] = matrix.outerIndexPtr()[i+1] - matrix.outerIndexPtr()[i];
+ m_mat.outerIndexPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i];
+ m_mat.innerNonZeroPtr()[m_perm_c.indices()(i)] = outerIndexPtr[i+1] - outerIndexPtr[i];
}
+ if(!matrix.isCompressed()) delete[] outerIndexPtr;
}
else
{ //FIXME This should not be needed if the empty permutation is handled transparently
@@ -453,6 +532,7 @@ void SparseLU<MatrixType, OrderingType>::factorize(const MatrixType& matrix)
m_perm_r.resize(m);
m_perm_r.indices().setConstant(-1);
marker.setConstant(-1);
+ m_detPermR = 1; // Record the determinant of the row permutation
m_glu.supno(0) = emptyIdxLU; m_glu.xsup.setConstant(0);
m_glu.xsup(0) = m_glu.xlsub(0) = m_glu.xusub(0) = m_glu.xlusup(0) = Index(0);
@@ -540,6 +620,9 @@ void SparseLU<MatrixType, OrderingType>::factorize(const MatrixType& matrix)
return;
}
+ // Update the determinant of the row permutation matrix
+ if (pivrow != jj) m_detPermR *= -1;
+
// Prune columns (0:jj-1) using column jj
Base::pruneL(jj, m_perm_r.indices(), pivrow, nseg, segrep, repfnz_k, xprune, m_glu);
@@ -568,7 +651,7 @@ void SparseLU<MatrixType, OrderingType>::factorize(const MatrixType& matrix)
}
template<typename MappedSupernodalType>
-struct SparseLUMatrixLReturnType
+struct SparseLUMatrixLReturnType : internal::no_assignment_operator
{
typedef typename MappedSupernodalType::Index Index;
typedef typename MappedSupernodalType::Scalar Scalar;
@@ -584,6 +667,61 @@ struct SparseLUMatrixLReturnType
const MappedSupernodalType& m_mapL;
};
+template<typename MatrixLType, typename MatrixUType>
+struct SparseLUMatrixUReturnType : internal::no_assignment_operator
+{
+ typedef typename MatrixLType::Index Index;
+ typedef typename MatrixLType::Scalar Scalar;
+ SparseLUMatrixUReturnType(const MatrixLType& mapL, const MatrixUType& mapU)
+ : m_mapL(mapL),m_mapU(mapU)
+ { }
+ Index rows() { return m_mapL.rows(); }
+ Index cols() { return m_mapL.cols(); }
+
+ template<typename Dest> void solveInPlace(MatrixBase<Dest> &X) const
+ {
+ Index nrhs = X.cols();
+ Index n = X.rows();
+ // Backward solve with U
+ for (Index k = m_mapL.nsuper(); k >= 0; k--)
+ {
+ Index fsupc = m_mapL.supToCol()[k];
+ Index lda = m_mapL.colIndexPtr()[fsupc+1] - m_mapL.colIndexPtr()[fsupc]; // leading dimension
+ Index nsupc = m_mapL.supToCol()[k+1] - fsupc;
+ Index luptr = m_mapL.colIndexPtr()[fsupc];
+
+ if (nsupc == 1)
+ {
+ for (Index j = 0; j < nrhs; j++)
+ {
+ X(fsupc, j) /= m_mapL.valuePtr()[luptr];
+ }
+ }
+ else
+ {
+ Map<const Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > A( &(m_mapL.valuePtr()[luptr]), nsupc, nsupc, OuterStride<>(lda) );
+ Map< Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) );
+ U = A.template triangularView<Upper>().solve(U);
+ }
+
+ for (Index j = 0; j < nrhs; ++j)
+ {
+ for (Index jcol = fsupc; jcol < fsupc + nsupc; jcol++)
+ {
+ typename MatrixUType::InnerIterator it(m_mapU, jcol);
+ for ( ; it; ++it)
+ {
+ Index irow = it.index();
+ X(irow, j) -= X(jcol, j) * it.value();
+ }
+ }
+ }
+ } // End For U-solve
+ }
+ const MatrixLType& m_mapL;
+ const MatrixUType& m_mapU;
+};
+
namespace internal {
template<typename _MatrixType, typename Derived, typename Rhs>
diff --git a/Eigen/src/SparseLU/SparseLU_Memory.h b/Eigen/src/SparseLU/SparseLU_Memory.h
index 6d9570d19..a5158025c 100644
--- a/Eigen/src/SparseLU/SparseLU_Memory.h
+++ b/Eigen/src/SparseLU/SparseLU_Memory.h
@@ -70,7 +70,7 @@ Index SparseLUImpl<Scalar,Index>::expand(VectorType& vec, Index& length, Index
if(num_expansions == 0 || keep_prev)
new_len = length ; // First time allocate requested
else
- new_len = alpha * length ;
+ new_len = Index(alpha * length);
VectorType old_vec; // Temporary vector to hold the previous values
if (nbElts > 0 )
@@ -100,7 +100,7 @@ Index SparseLUImpl<Scalar,Index>::expand(VectorType& vec, Index& length, Index
do
{
alpha = (alpha + 1)/2;
- new_len = alpha * length ;
+ new_len = Index(alpha * length);
try
{
vec.resize(new_len);
@@ -141,7 +141,7 @@ Index SparseLUImpl<Scalar,Index>::memInit(Index m, Index n, Index annz, Index lw
Index& num_expansions = glu.num_expansions; //No memory expansions so far
num_expansions = 0;
glu.nzumax = glu.nzlumax = (std::max)(fillratio * annz, m*n); // estimated number of nonzeros in U
- glu.nzlmax = (std::max)(1., fillratio/4.) * annz; // estimated nnz in L factor
+ glu.nzlmax = (std::max)(Index(4), fillratio) * annz / 4; // estimated nnz in L factor
// Return the estimated size to the user if necessary
Index tempSpace;
diff --git a/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h b/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h
index 3eae95479..ad6f2183f 100644
--- a/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h
+++ b/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h
@@ -189,13 +189,14 @@ class MappedSuperNodalMatrix<Scalar,Index>::InnerIterator
m_idval(mat.colIndexPtr()[outer]),
m_startidval(m_idval),
m_endidval(mat.colIndexPtr()[outer+1]),
- m_idrow(mat.rowIndexPtr()[outer])
+ m_idrow(mat.rowIndexPtr()[outer]),
+ m_endidrow(mat.rowIndexPtr()[outer+1])
{}
inline InnerIterator& operator++()
{
m_idval++;
m_idrow++;
- return *this;
+ return *this;
}
inline Scalar value() const { return m_matrix.valuePtr()[m_idval]; }
@@ -209,17 +210,19 @@ class MappedSuperNodalMatrix<Scalar,Index>::InnerIterator
inline operator bool() const
{
- return ( (m_idval < m_endidval) && (m_idval >= m_startidval) );
+ return ( (m_idval < m_endidval) && (m_idval >= m_startidval)
+ && (m_idrow < m_endidrow) );
}
protected:
const MappedSuperNodalMatrix& m_matrix; // Supernodal lower triangular matrix
- const Index m_outer; // Current column
- const Index m_supno; // Current SuperNode number
- Index m_idval; //Index to browse the values in the current column
- const Index m_startidval; // Start of the column value
- const Index m_endidval; // End of the column value
- Index m_idrow; //Index to browse the row indices
+ const Index m_outer; // Current column
+ const Index m_supno; // Current SuperNode number
+ Index m_idval; // Index to browse the values in the current column
+ const Index m_startidval; // Start of the column value
+ const Index m_endidval; // End of the column value
+ Index m_idrow; // Index to browse the row indices
+ Index m_endidrow; // End index of row indices of the current column
};
/**
@@ -232,32 +235,32 @@ void MappedSuperNodalMatrix<Scalar,Index>::solveInPlace( MatrixBase<Dest>&X) con
{
Index n = X.rows();
Index nrhs = X.cols();
- const Scalar * Lval = valuePtr(); // Nonzero values
- Matrix<Scalar,Dynamic,Dynamic> work(n, nrhs); // working vector
+ const Scalar * Lval = valuePtr(); // Nonzero values
+ Matrix<Scalar,Dynamic,Dynamic> work(n, nrhs); // working vector
work.setZero();
for (Index k = 0; k <= nsuper(); k ++)
{
- Index fsupc = supToCol()[k]; // First column of the current supernode
- Index istart = rowIndexPtr()[fsupc]; // Pointer index to the subscript of the current column
+ Index fsupc = supToCol()[k]; // First column of the current supernode
+ Index istart = rowIndexPtr()[fsupc]; // Pointer index to the subscript of the current column
Index nsupr = rowIndexPtr()[fsupc+1] - istart; // Number of rows in the current supernode
- Index nsupc = supToCol()[k+1] - fsupc; // Number of columns in the current supernode
- Index nrow = nsupr - nsupc; // Number of rows in the non-diagonal part of the supernode
- Index irow; //Current index row
+ Index nsupc = supToCol()[k+1] - fsupc; // Number of columns in the current supernode
+ Index nrow = nsupr - nsupc; // Number of rows in the non-diagonal part of the supernode
+ Index irow; //Current index row
if (nsupc == 1 )
{
for (Index j = 0; j < nrhs; j++)
{
- InnerIterator it(*this, fsupc);
+ InnerIterator it(*this, fsupc);
++it; // Skip the diagonal element
for (; it; ++it)
{
irow = it.row();
- X(irow, j) -= X(fsupc, j) * it.value();
+ X(irow, j) -= X(fsupc, j) * it.value();
}
}
}
- else
+ else
{
// The supernode has more than one column
Index luptr = colIndexPtr()[fsupc];
@@ -291,4 +294,5 @@ void MappedSuperNodalMatrix<Scalar,Index>::solveInPlace( MatrixBase<Dest>&X) con
} // end namespace internal
} // end namespace Eigen
+
#endif // EIGEN_SPARSELU_MATRIX_H
diff --git a/Eigen/src/SparseLU/SparseLU_column_dfs.h b/Eigen/src/SparseLU/SparseLU_column_dfs.h
index bd450ddc7..4c04b0e44 100644
--- a/Eigen/src/SparseLU/SparseLU_column_dfs.h
+++ b/Eigen/src/SparseLU/SparseLU_column_dfs.h
@@ -36,7 +36,7 @@ namespace Eigen {
namespace internal {
template<typename IndexVector, typename ScalarVector>
-struct column_dfs_traits
+struct column_dfs_traits : no_assignment_operator
{
typedef typename ScalarVector::Scalar Scalar;
typedef typename IndexVector::Scalar Index;
@@ -101,7 +101,7 @@ Index SparseLUImpl<Scalar,Index>::column_dfs(const Index m, const Index jcol, In
column_dfs_traits<IndexVector, ScalarVector> traits(jcol, jsuper, glu, *this);
// For each nonzero in A(*,jcol) do dfs
- for (Index k = 0; lsub_col[k] != emptyIdxLU; k++)
+ for (Index k = 0; ((k < m) ? lsub_col[k] != emptyIdxLU : false) ; k++)
{
Index krow = lsub_col(k);
lsub_col(k) = emptyIdxLU;
diff --git a/Eigen/src/SparseLU/SparseLU_pruneL.h b/Eigen/src/SparseLU/SparseLU_pruneL.h
index 5a855f82f..66460d168 100644
--- a/Eigen/src/SparseLU/SparseLU_pruneL.h
+++ b/Eigen/src/SparseLU/SparseLU_pruneL.h
@@ -56,7 +56,7 @@ void SparseLUImpl<Scalar,Index>::pruneL(const Index jcol, const IndexVector& per
Index jsupno = glu.supno(jcol);
Index i,irep,irep1;
bool movnum, do_prune = false;
- Index kmin, kmax, minloc, maxloc,krow;
+ Index kmin = 0, kmax = 0, minloc, maxloc,krow;
for (i = 0; i < nseg; i++)
{
irep = segrep(i);
diff --git a/Eigen/src/SparseQR/SparseQR.h b/Eigen/src/SparseQR/SparseQR.h
index b3d5cd208..07c46e4b9 100644
--- a/Eigen/src/SparseQR/SparseQR.h
+++ b/Eigen/src/SparseQR/SparseQR.h
@@ -21,6 +21,8 @@ namespace internal {
template <typename SparseQRType> struct traits<SparseQRMatrixQReturnType<SparseQRType> >
{
typedef typename SparseQRType::MatrixType ReturnType;
+ typedef typename ReturnType::Index Index;
+ typedef typename ReturnType::StorageKind StorageKind;
};
template <typename SparseQRType> struct traits<SparseQRMatrixQTransposeReturnType<SparseQRType> >
{
@@ -72,10 +74,10 @@ class SparseQR
typedef Matrix<Scalar, Dynamic, 1> ScalarVector;
typedef PermutationMatrix<Dynamic, Dynamic, Index> PermutationType;
public:
- SparseQR () : m_isInitialized(false), m_analysisIsok(false), m_lastError(""), m_useDefaultThreshold(true)
+ SparseQR () : m_isInitialized(false), m_analysisIsok(false), m_lastError(""), m_useDefaultThreshold(true),m_isQSorted(false)
{ }
- SparseQR(const MatrixType& mat) : m_isInitialized(false), m_analysisIsok(false), m_lastError(""), m_useDefaultThreshold(true)
+ SparseQR(const MatrixType& mat) : m_isInitialized(false), m_analysisIsok(false), m_lastError(""), m_useDefaultThreshold(true),m_isQSorted(false)
{
compute(mat);
}
@@ -110,11 +112,23 @@ class SparseQR
}
/** \returns an expression of the matrix Q as products of sparse Householder reflectors.
- * You can do the following to get an actual SparseMatrix representation of Q:
- * \code
- * SparseMatrix<double> Q = SparseQR<SparseMatrix<double> >(A).matrixQ();
- * \endcode
- */
+ * The common usage of this function is to apply it to a dense matrix or vector
+ * \code
+ * VectorXd B1, B2;
+ * // Initialize B1
+ * B2 = matrixQ() * B1;
+ * \endcode
+ *
+ * To get a plain SparseMatrix representation of Q:
+ * \code
+ * SparseMatrix<double> Q;
+ * Q = SparseQR<SparseMatrix<double> >(A).matrixQ();
+ * \endcode
+ * Internally, this call simply performs a sparse product between the matrix Q
+ * and a sparse identity matrix. However, due to the fact that the sparse
+ * reflectors are stored unsorted, two transpositions are needed to sort
+ * them before performing the product.
+ */
SparseQRMatrixQReturnType<SparseQR> matrixQ() const
{ return SparseQRMatrixQReturnType<SparseQR>(*this); }
@@ -158,6 +172,7 @@ class SparseQR
return true;
}
+
/** Sets the threshold that is used to determine linearly dependent columns during the factorization.
*
* In practice, if during the factorization the norm of the column that has to be eliminated is below
@@ -180,6 +195,13 @@ class SparseQR
eigen_assert(this->rows() == B.rows() && "SparseQR::solve() : invalid number of rows in the right hand side matrix");
return internal::solve_retval<SparseQR, Rhs>(*this, B.derived());
}
+ template<typename Rhs>
+ inline const internal::sparse_solve_retval<SparseQR, Rhs> solve(const SparseMatrixBase<Rhs>& B) const
+ {
+ eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
+ eigen_assert(this->rows() == B.rows() && "SparseQR::solve() : invalid number of rows in the right hand side matrix");
+ return internal::sparse_solve_retval<SparseQR, Rhs>(*this, B.derived());
+ }
/** \brief Reports whether previous computation was successful.
*
@@ -194,6 +216,17 @@ class SparseQR
eigen_assert(m_isInitialized && "Decomposition is not initialized.");
return m_info;
}
+
+ protected:
+ inline void sort_matrix_Q()
+ {
+ if(this->m_isQSorted) return;
+ // The matrix Q is sorted during the transposition
+ SparseMatrix<Scalar, RowMajor, Index> mQrm(this->m_Q);
+ this->m_Q = mQrm;
+ this->m_isQSorted = true;
+ }
+
protected:
bool m_isInitialized;
@@ -213,8 +246,10 @@ class SparseQR
Index m_nonzeropivots; // Number of non zero pivots found
IndexVector m_etree; // Column elimination tree
IndexVector m_firstRowElt; // First element in each row
+ bool m_isQSorted; // whether Q is sorted or not
template <typename, typename > friend struct SparseQR_QProduct;
+ template <typename > friend struct SparseQRMatrixQReturnType;
};
@@ -400,23 +435,23 @@ void SparseQR<MatrixType,OrderingType>::factorize(const MatrixType& mat)
// First, the squared norm of Q((col+1):m, col)
RealScalar sqrNorm = 0.;
- for (Index itq = 1; itq < nzcolQ; ++itq) sqrNorm += internal::abs2(tval(Qidx(itq)));
+ for (Index itq = 1; itq < nzcolQ; ++itq) sqrNorm += numext::abs2(tval(Qidx(itq)));
- if(sqrNorm == RealScalar(0) && internal::imag(c0) == RealScalar(0))
+ if(sqrNorm == RealScalar(0) && numext::imag(c0) == RealScalar(0))
{
tau = RealScalar(0);
- beta = internal::real(c0);
+ beta = numext::real(c0);
tval(Qidx(0)) = 1;
}
else
{
- beta = std::sqrt(internal::abs2(c0) + sqrNorm);
- if(internal::real(c0) >= RealScalar(0))
+ beta = std::sqrt(numext::abs2(c0) + sqrNorm);
+ if(numext::real(c0) >= RealScalar(0))
beta = -beta;
tval(Qidx(0)) = 1;
for (Index itq = 1; itq < nzcolQ; ++itq)
tval(Qidx(itq)) /= (c0 - beta);
- tau = internal::conj((beta-c0) / beta);
+ tau = numext::conj((beta-c0) / beta);
}
@@ -462,6 +497,7 @@ void SparseQR<MatrixType,OrderingType>::factorize(const MatrixType& mat)
m_Q.makeCompressed();
m_R.finalize();
m_R.makeCompressed();
+ m_isQSorted = false;
m_nonzeropivots = nonzeroCol;
@@ -494,7 +530,18 @@ struct solve_retval<SparseQR<_MatrixType,OrderingType>, Rhs>
dec()._solve(rhs(),dst);
}
};
+template<typename _MatrixType, typename OrderingType, typename Rhs>
+struct sparse_solve_retval<SparseQR<_MatrixType, OrderingType>, Rhs>
+ : sparse_solve_retval_base<SparseQR<_MatrixType, OrderingType>, Rhs>
+{
+ typedef SparseQR<_MatrixType, OrderingType> Dec;
+ EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec, Rhs)
+ template<typename Dest> void evalTo(Dest& dst) const
+ {
+ this->defaultEvalTo(dst);
+ }
+};
} // end namespace internal
template <typename SparseQRType, typename Derived>
@@ -513,34 +560,35 @@ struct SparseQR_QProduct : ReturnByValue<SparseQR_QProduct<SparseQRType, Derived
template<typename DesType>
void evalTo(DesType& res) const
{
- Index n = m_qr.cols();
+ Index n = m_qr.cols();
+ res = m_other;
if (m_transpose)
{
eigen_assert(m_qr.m_Q.rows() == m_other.rows() && "Non conforming object sizes");
- // Compute res = Q' * other :
- res = m_other;
- for (Index k = 0; k < n; k++)
- {
- Scalar tau = Scalar(0);
- tau = m_qr.m_Q.col(k).dot(res);
- tau = tau * m_qr.m_hcoeffs(k);
- for (typename MatrixType::InnerIterator itq(m_qr.m_Q, k); itq; ++itq)
+ //Compute res = Q' * other column by column
+ for(Index j = 0; j < res.cols(); j++){
+ for (Index k = 0; k < n; k++)
{
- res(itq.row()) -= itq.value() * tau;
+ Scalar tau = Scalar(0);
+ tau = m_qr.m_Q.col(k).dot(res.col(j));
+ tau = tau * m_qr.m_hcoeffs(k);
+ res.col(j) -= tau * m_qr.m_Q.col(k);
}
}
}
else
{
eigen_assert(m_qr.m_Q.cols() == m_other.rows() && "Non conforming object sizes");
- // Compute res = Q * other :
- res = m_other;
- for (Index k = n-1; k >=0; k--)
+ // Compute res = Q' * other column by column
+ for(Index j = 0; j < res.cols(); j++)
{
- Scalar tau = Scalar(0);
- tau = m_qr.m_Q.col(k).dot(res);
- tau = tau * m_qr.m_hcoeffs(k);
- res -= tau * m_qr.m_Q.col(k);
+ for (Index k = n-1; k >=0; k--)
+ {
+ Scalar tau = Scalar(0);
+ tau = m_qr.m_Q.col(k).dot(res.col(j));
+ tau = tau * m_qr.m_hcoeffs(k);
+ res.col(j) -= tau * m_qr.m_Q.col(k);
+ }
}
}
}
@@ -551,8 +599,11 @@ struct SparseQR_QProduct : ReturnByValue<SparseQR_QProduct<SparseQRType, Derived
};
template<typename SparseQRType>
-struct SparseQRMatrixQReturnType
+struct SparseQRMatrixQReturnType : public EigenBase<SparseQRMatrixQReturnType<SparseQRType> >
{
+ typedef typename SparseQRType::Index Index;
+ typedef typename SparseQRType::Scalar Scalar;
+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;
SparseQRMatrixQReturnType(const SparseQRType& qr) : m_qr(qr) {}
template<typename Derived>
SparseQR_QProduct<SparseQRType, Derived> operator*(const MatrixBase<Derived>& other)
@@ -563,11 +614,26 @@ struct SparseQRMatrixQReturnType
{
return SparseQRMatrixQTransposeReturnType<SparseQRType>(m_qr);
}
+ inline Index rows() const { return m_qr.rows(); }
+ inline Index cols() const { return m_qr.cols(); }
// To use for operations with the transpose of Q
SparseQRMatrixQTransposeReturnType<SparseQRType> transpose() const
{
return SparseQRMatrixQTransposeReturnType<SparseQRType>(m_qr);
}
+ template<typename Dest> void evalTo(MatrixBase<Dest>& dest) const
+ {
+ dest.derived() = m_qr.matrixQ() * Dest::Identity(m_qr.rows(), m_qr.rows());
+ }
+ template<typename Dest> void evalTo(SparseMatrixBase<Dest>& dest) const
+ {
+ Dest idMat(m_qr.rows(), m_qr.rows());
+ idMat.setIdentity();
+ // Sort the sparse householder reflectors if needed
+ const_cast<SparseQRType *>(&m_qr)->sort_matrix_Q();
+ dest.derived() = SparseQR_QProduct<SparseQRType, Dest>(m_qr, idMat, false);
+ }
+
const SparseQRType& m_qr;
};
diff --git a/Eigen/src/SuperLUSupport/SuperLUSupport.h b/Eigen/src/SuperLUSupport/SuperLUSupport.h
index 3034c7af5..bcb355760 100644
--- a/Eigen/src/SuperLUSupport/SuperLUSupport.h
+++ b/Eigen/src/SuperLUSupport/SuperLUSupport.h
@@ -160,7 +160,7 @@ struct SluMatrix : SuperMatrix
res.ncol = mat.cols();
res.storage.lda = MatrixType::IsVectorAtCompileTime ? mat.size() : mat.outerStride();
- res.storage.values = mat.data();
+ res.storage.values = (void*)(mat.data());
return res;
}
@@ -377,7 +377,7 @@ class SuperLUBase : internal::noncopyable
}
template<typename Stream>
- void dumpMemory(Stream& s)
+ void dumpMemory(Stream& /*s*/)
{}
protected:
diff --git a/Eigen/src/UmfPackSupport/UmfPackSupport.h b/Eigen/src/UmfPackSupport/UmfPackSupport.h
index d85b8be85..3a48cecf7 100644
--- a/Eigen/src/UmfPackSupport/UmfPackSupport.h
+++ b/Eigen/src/UmfPackSupport/UmfPackSupport.h
@@ -39,7 +39,7 @@ inline int umfpack_symbolic(int n_row,int n_col,
const int Ap[], const int Ai[], const std::complex<double> Ax[], void **Symbolic,
const double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO])
{
- return umfpack_zi_symbolic(n_row,n_col,Ap,Ai,&internal::real_ref(Ax[0]),0,Symbolic,Control,Info);
+ return umfpack_zi_symbolic(n_row,n_col,Ap,Ai,&numext::real_ref(Ax[0]),0,Symbolic,Control,Info);
}
inline int umfpack_numeric( const int Ap[], const int Ai[], const double Ax[],
@@ -53,7 +53,7 @@ inline int umfpack_numeric( const int Ap[], const int Ai[], const std::complex<d
void *Symbolic, void **Numeric,
const double Control[UMFPACK_CONTROL],double Info [UMFPACK_INFO])
{
- return umfpack_zi_numeric(Ap,Ai,&internal::real_ref(Ax[0]),0,Symbolic,Numeric,Control,Info);
+ return umfpack_zi_numeric(Ap,Ai,&numext::real_ref(Ax[0]),0,Symbolic,Numeric,Control,Info);
}
inline int umfpack_solve( int sys, const int Ap[], const int Ai[], const double Ax[],
@@ -67,7 +67,7 @@ inline int umfpack_solve( int sys, const int Ap[], const int Ai[], const std::co
std::complex<double> X[], const std::complex<double> B[], void *Numeric,
const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO])
{
- return umfpack_zi_solve(sys,Ap,Ai,&internal::real_ref(Ax[0]),0,&internal::real_ref(X[0]),0,&internal::real_ref(B[0]),0,Numeric,Control,Info);
+ return umfpack_zi_solve(sys,Ap,Ai,&numext::real_ref(Ax[0]),0,&numext::real_ref(X[0]),0,&numext::real_ref(B[0]),0,Numeric,Control,Info);
}
inline int umfpack_get_lunz(int *lnz, int *unz, int *n_row, int *n_col, int *nz_udiag, void *Numeric, double)
@@ -89,9 +89,9 @@ inline int umfpack_get_numeric(int Lp[], int Lj[], double Lx[], int Up[], int Ui
inline int umfpack_get_numeric(int Lp[], int Lj[], std::complex<double> Lx[], int Up[], int Ui[], std::complex<double> Ux[],
int P[], int Q[], std::complex<double> Dx[], int *do_recip, double Rs[], void *Numeric)
{
- double& lx0_real = internal::real_ref(Lx[0]);
- double& ux0_real = internal::real_ref(Ux[0]);
- double& dx0_real = internal::real_ref(Dx[0]);
+ double& lx0_real = numext::real_ref(Lx[0]);
+ double& ux0_real = numext::real_ref(Ux[0]);
+ double& dx0_real = numext::real_ref(Dx[0]);
return umfpack_zi_get_numeric(Lp,Lj,Lx?&lx0_real:0,0,Up,Ui,Ux?&ux0_real:0,0,P,Q,
Dx?&dx0_real:0,0,do_recip,Rs,Numeric);
}
@@ -103,7 +103,7 @@ inline int umfpack_get_determinant(double *Mx, double *Ex, void *NumericHandle,
inline int umfpack_get_determinant(std::complex<double> *Mx, double *Ex, void *NumericHandle, double User_Info [UMFPACK_INFO])
{
- double& mx_real = internal::real_ref(*Mx);
+ double& mx_real = numext::real_ref(*Mx);
return umfpack_zi_get_determinant(&mx_real,0,Ex,NumericHandle,User_Info);
}
diff --git a/Eigen/src/plugins/BlockMethods.h b/Eigen/src/plugins/BlockMethods.h
index 5ef373a81..3bc345211 100644
--- a/Eigen/src/plugins/BlockMethods.h
+++ b/Eigen/src/plugins/BlockMethods.h
@@ -94,12 +94,13 @@ inline const Block<const Derived> topRightCorner(Index cRows, Index cCols) const
/** \returns an expression of a fixed-size top-right corner of *this.
*
- * The template parameters CRows and CCols are the number of rows and columns in the corner.
+ * \tparam CRows the number of rows in the corner
+ * \tparam CCols the number of columns in the corner
*
* Example: \include MatrixBase_template_int_int_topRightCorner.cpp
* Output: \verbinclude MatrixBase_template_int_int_topRightCorner.out
*
- * \sa class Block, block(Index,Index,Index,Index)
+ * \sa class Block, block<int,int>(Index,Index)
*/
template<int CRows, int CCols>
EIGEN_DEVICE_FUNC
@@ -116,6 +117,35 @@ inline const Block<const Derived, CRows, CCols> topRightCorner() const
return Block<const Derived, CRows, CCols>(derived(), 0, cols() - CCols);
}
+/** \returns an expression of a top-right corner of *this.
+ *
+ * \tparam CRows number of rows in corner as specified at compile time
+ * \tparam CCols number of columns in corner as specified at compile time
+ * \param cRows number of rows in corner as specified at run time
+ * \param cCols number of columns in corner as specified at run time
+ *
+ * This function is mainly useful for corners where the number of rows is specified at compile time
+ * and the number of columns is specified at run time, or vice versa. The compile-time and run-time
+ * information should not contradict. In other words, \a cRows should equal \a CRows unless
+ * \a CRows is \a Dynamic, and the same for the number of columns.
+ *
+ * Example: \include MatrixBase_template_int_int_topRightCorner_int_int.cpp
+ * Output: \verbinclude MatrixBase_template_int_int_topRightCorner_int_int.out
+ *
+ * \sa class Block
+ */
+template<int CRows, int CCols>
+inline Block<Derived, CRows, CCols> topRightCorner(Index cRows, Index cCols)
+{
+ return Block<Derived, CRows, CCols>(derived(), 0, cols() - cCols, cRows, cCols);
+}
+
+/** This is the const version of topRightCorner<int, int>(Index, Index).*/
+template<int CRows, int CCols>
+inline const Block<const Derived, CRows, CCols> topRightCorner(Index cRows, Index cCols) const
+{
+ return Block<const Derived, CRows, CCols>(derived(), 0, cols() - cCols, cRows, cCols);
+}
@@ -166,6 +196,36 @@ inline const Block<const Derived, CRows, CCols> topLeftCorner() const
return Block<const Derived, CRows, CCols>(derived(), 0, 0);
}
+/** \returns an expression of a top-left corner of *this.
+ *
+ * \tparam CRows number of rows in corner as specified at compile time
+ * \tparam CCols number of columns in corner as specified at compile time
+ * \param cRows number of rows in corner as specified at run time
+ * \param cCols number of columns in corner as specified at run time
+ *
+ * This function is mainly useful for corners where the number of rows is specified at compile time
+ * and the number of columns is specified at run time, or vice versa. The compile-time and run-time
+ * information should not contradict. In other words, \a cRows should equal \a CRows unless
+ * \a CRows is \a Dynamic, and the same for the number of columns.
+ *
+ * Example: \include MatrixBase_template_int_int_topLeftCorner_int_int.cpp
+ * Output: \verbinclude MatrixBase_template_int_int_topLeftCorner_int_int.out
+ *
+ * \sa class Block
+ */
+template<int CRows, int CCols>
+inline Block<Derived, CRows, CCols> topLeftCorner(Index cRows, Index cCols)
+{
+ return Block<Derived, CRows, CCols>(derived(), 0, 0, cRows, cCols);
+}
+
+/** This is the const version of topLeftCorner<int, int>(Index, Index).*/
+template<int CRows, int CCols>
+inline const Block<const Derived, CRows, CCols> topLeftCorner(Index cRows, Index cCols) const
+{
+ return Block<const Derived, CRows, CCols>(derived(), 0, 0, cRows, cCols);
+}
+
/** \returns a dynamic-size expression of a bottom-right corner of *this.
@@ -215,6 +275,36 @@ inline const Block<const Derived, CRows, CCols> bottomRightCorner() const
return Block<const Derived, CRows, CCols>(derived(), rows() - CRows, cols() - CCols);
}
+/** \returns an expression of a bottom-right corner of *this.
+ *
+ * \tparam CRows number of rows in corner as specified at compile time
+ * \tparam CCols number of columns in corner as specified at compile time
+ * \param cRows number of rows in corner as specified at run time
+ * \param cCols number of columns in corner as specified at run time
+ *
+ * This function is mainly useful for corners where the number of rows is specified at compile time
+ * and the number of columns is specified at run time, or vice versa. The compile-time and run-time
+ * information should not contradict. In other words, \a cRows should equal \a CRows unless
+ * \a CRows is \a Dynamic, and the same for the number of columns.
+ *
+ * Example: \include MatrixBase_template_int_int_bottomRightCorner_int_int.cpp
+ * Output: \verbinclude MatrixBase_template_int_int_bottomRightCorner_int_int.out
+ *
+ * \sa class Block
+ */
+template<int CRows, int CCols>
+inline Block<Derived, CRows, CCols> bottomRightCorner(Index cRows, Index cCols)
+{
+ return Block<Derived, CRows, CCols>(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
+}
+
+/** This is the const version of bottomRightCorner<int, int>(Index, Index).*/
+template<int CRows, int CCols>
+inline const Block<const Derived, CRows, CCols> bottomRightCorner(Index cRows, Index cCols) const
+{
+ return Block<const Derived, CRows, CCols>(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
+}
+
/** \returns a dynamic-size expression of a bottom-left corner of *this.
@@ -264,6 +354,36 @@ inline const Block<const Derived, CRows, CCols> bottomLeftCorner() const
return Block<const Derived, CRows, CCols>(derived(), rows() - CRows, 0);
}
+/** \returns an expression of a bottom-left corner of *this.
+ *
+ * \tparam CRows number of rows in corner as specified at compile time
+ * \tparam CCols number of columns in corner as specified at compile time
+ * \param cRows number of rows in corner as specified at run time
+ * \param cCols number of columns in corner as specified at run time
+ *
+ * This function is mainly useful for corners where the number of rows is specified at compile time
+ * and the number of columns is specified at run time, or vice versa. The compile-time and run-time
+ * information should not contradict. In other words, \a cRows should equal \a CRows unless
+ * \a CRows is \a Dynamic, and the same for the number of columns.
+ *
+ * Example: \include MatrixBase_template_int_int_bottomLeftCorner_int_int.cpp
+ * Output: \verbinclude MatrixBase_template_int_int_bottomLeftCorner_int_int.out
+ *
+ * \sa class Block
+ */
+template<int CRows, int CCols>
+inline Block<Derived, CRows, CCols> bottomLeftCorner(Index cRows, Index cCols)
+{
+ return Block<Derived, CRows, CCols>(derived(), rows() - cRows, 0, cRows, cCols);
+}
+
+/** This is the const version of bottomLeftCorner<int, int>(Index, Index).*/
+template<int CRows, int CCols>
+inline const Block<const Derived, CRows, CCols> bottomLeftCorner(Index cRows, Index cCols) const
+{
+ return Block<const Derived, CRows, CCols>(derived(), rows() - cRows, 0, cRows, cCols);
+}
+
/** \returns a block consisting of the top rows of *this.
@@ -589,6 +709,40 @@ inline const Block<const Derived, BlockRows, BlockCols> block(Index startRow, In
return Block<const Derived, BlockRows, BlockCols>(derived(), startRow, startCol);
}
+/** \returns an expression of a block in *this.
+ *
+ * \tparam BlockRows number of rows in block as specified at compile time
+ * \tparam BlockCols number of columns in block as specified at compile time
+ * \param startRow the first row in the block
+ * \param startCol the first column in the block
+ * \param blockRows number of rows in block as specified at run time
+ * \param blockCols number of columns in block as specified at run time
+ *
+ * This function is mainly useful for blocks where the number of rows is specified at compile time
+ * and the number of columns is specified at run time, or vice versa. The compile-time and run-time
+ * information should not contradict. In other words, \a blockRows should equal \a BlockRows unless
+ * \a BlockRows is \a Dynamic, and the same for the number of columns.
+ *
+ * Example: \include MatrixBase_template_int_int_block_int_int_int_int.cpp
+ * Output: \verbinclude MatrixBase_template_int_int_block_int_int_int_int.cpp
+ *
+ * \sa class Block, block(Index,Index,Index,Index)
+ */
+template<int BlockRows, int BlockCols>
+inline Block<Derived, BlockRows, BlockCols> block(Index startRow, Index startCol,
+ Index blockRows, Index blockCols)
+{
+ return Block<Derived, BlockRows, BlockCols>(derived(), startRow, startCol, blockRows, blockCols);
+}
+
+/** This is the const version of block<>(Index, Index, Index, Index). */
+template<int BlockRows, int BlockCols>
+inline const Block<const Derived, BlockRows, BlockCols> block(Index startRow, Index startCol,
+ Index blockRows, Index blockCols) const
+{
+ return Block<const Derived, BlockRows, BlockCols>(derived(), startRow, startCol, blockRows, blockCols);
+}
+
/** \returns an expression of the \a i-th column of *this. Note that the numbering starts at 0.
*
* Example: \include MatrixBase_col.cpp
diff --git a/bench/spmv.cpp b/bench/spmv.cpp
index f6326dbb1..959bab09b 100644
--- a/bench/spmv.cpp
+++ b/bench/spmv.cpp
@@ -99,7 +99,7 @@ int main(int argc, char *argv[])
SPMV_BENCH(res = dm * sm);
std::cout << "Dense " << t.value()/repeats << "\t";
- SPMV_BENCHres = dm.transpose() * sm);
+ SPMV_BENCH(res = dm.transpose() * sm);
std::cout << t.value()/repeats << endl;
}
#endif
diff --git a/blas/PackedSelfadjointProduct.h b/blas/PackedSelfadjointProduct.h
index f7c9b9341..07327a246 100644
--- a/blas/PackedSelfadjointProduct.h
+++ b/blas/PackedSelfadjointProduct.h
@@ -30,10 +30,9 @@ struct selfadjoint_packed_rank1_update<Scalar,Index,ColMajor,UpLo,ConjLhs,ConjRh
for (Index i=0; i<size; ++i)
{
- Map<Matrix<Scalar,Dynamic,1> >(mat, UpLo==Lower ? size-i : (i+1))
- += alpha * cj(vec[i]) * ConjRhsType(OtherMap(vec+(UpLo==Lower ? i : 0), UpLo==Lower ? size-i : (i+1)));
+ Map<Matrix<Scalar,Dynamic,1> >(mat, UpLo==Lower ? size-i : (i+1)) += alpha * cj(vec[i]) * ConjRhsType(OtherMap(vec+(UpLo==Lower ? i : 0), UpLo==Lower ? size-i : (i+1)));
//FIXME This should be handled outside.
- mat[UpLo==Lower ? 0 : i] = real(mat[UpLo==Lower ? 0 : i]);
+ mat[UpLo==Lower ? 0 : i] = numext::real(mat[UpLo==Lower ? 0 : i]);
mat += UpLo==Lower ? size-i : (i+1);
}
}
diff --git a/blas/Rank2Update.h b/blas/Rank2Update.h
index 8e1a676ee..138d70fd6 100644
--- a/blas/Rank2Update.h
+++ b/blas/Rank2Update.h
@@ -24,8 +24,8 @@ struct rank2_update_selector
for (Index i=0; i<size; ++i)
{
Map<Matrix<Scalar,Dynamic,1> >(mat+stride*i+(UpLo==Lower ? i : 0), UpLo==Lower ? size-i : (i+1)) +=
- conj(alpha) * conj(u[i]) * OtherMap(v+(UpLo==Lower ? i : 0), UpLo==Lower ? size-i : (i+1))
- + alpha * conj(v[i]) * OtherMap(u+(UpLo==Lower ? i : 0), UpLo==Lower ? size-i : (i+1));
+ numext::conj(alpha) * numext::conj(u[i]) * OtherMap(v+(UpLo==Lower ? i : 0), UpLo==Lower ? size-i : (i+1))
+ + alpha * numext::conj(v[i]) * OtherMap(u+(UpLo==Lower ? i : 0), UpLo==Lower ? size-i : (i+1));
}
}
};
@@ -43,10 +43,10 @@ struct packed_rank2_update_selector
for (Index i=0; i<size; ++i)
{
Map<Matrix<Scalar,Dynamic,1> >(mat+offset, UpLo==Lower ? size-i : (i+1)) +=
- conj(alpha) * conj(u[i]) * OtherMap(v+(UpLo==Lower ? i : 0), UpLo==Lower ? size-i : (i+1))
- + alpha * conj(v[i]) * OtherMap(u+(UpLo==Lower ? i : 0), UpLo==Lower ? size-i : (i+1));
+ numext::conj(alpha) * numext::conj(u[i]) * OtherMap(v+(UpLo==Lower ? i : 0), UpLo==Lower ? size-i : (i+1))
+ + alpha * numext::conj(v[i]) * OtherMap(u+(UpLo==Lower ? i : 0), UpLo==Lower ? size-i : (i+1));
//FIXME This should be handled outside.
- mat[offset+(UpLo==Lower ? 0 : i)] = real(mat[offset+(UpLo==Lower ? 0 : i)]);
+ mat[offset+(UpLo==Lower ? 0 : i)] = numext::real(mat[offset+(UpLo==Lower ? 0 : i)]);
offset += UpLo==Lower ? size-i : (i+1);
}
}
diff --git a/blas/level1_cplx_impl.h b/blas/level1_cplx_impl.h
index 8d6b92829..283b9f827 100644
--- a/blas/level1_cplx_impl.h
+++ b/blas/level1_cplx_impl.h
@@ -12,7 +12,7 @@
struct scalar_norm1_op {
typedef RealScalar result_type;
EIGEN_EMPTY_STRUCT_CTOR(scalar_norm1_op)
- inline RealScalar operator() (const Scalar& a) const { return internal::norm1(a); }
+ inline RealScalar operator() (const Scalar& a) const { return numext::norm1(a); }
};
namespace Eigen {
namespace internal {
diff --git a/blas/level1_impl.h b/blas/level1_impl.h
index c73f4d4f9..b08c2f6be 100644
--- a/blas/level1_impl.h
+++ b/blas/level1_impl.h
@@ -120,10 +120,10 @@ int EIGEN_BLAS_FUNC(rotg)(RealScalar *pa, RealScalar *pb, RealScalar *pc, RealSc
else
{
scale = abs(a) + abs(b);
- norm = scale*sqrt((internal::abs2(a/scale))+ (internal::abs2(b/scale)));
+ norm = scale*sqrt((numext::abs2(a/scale)) + (numext::abs2(b/scale)));
alpha = a/abs(a);
*c = abs(a)/norm;
- *s = alpha*internal::conj(b)/norm;
+ *s = alpha*numext::conj(b)/norm;
a = alpha*norm;
}
#endif
diff --git a/blas/level3_impl.h b/blas/level3_impl.h
index a57189f53..07dbc22ff 100644
--- a/blas/level3_impl.h
+++ b/blas/level3_impl.h
@@ -608,24 +608,24 @@ int EIGEN_BLAS_FUNC(her2k)(char *uplo, char *op, int *n, int *k, RealScalar *pal
if(UPLO(*uplo)==UP)
{
matrix(c, *n, *n, *ldc).triangularView<Upper>()
- += alpha *matrix(a, *n, *k, *lda)*matrix(b, *n, *k, *ldb).adjoint()
- + internal::conj(alpha)*matrix(b, *n, *k, *ldb)*matrix(a, *n, *k, *lda).adjoint();
+ += alpha *matrix(a, *n, *k, *lda)*matrix(b, *n, *k, *ldb).adjoint()
+ + numext::conj(alpha)*matrix(b, *n, *k, *ldb)*matrix(a, *n, *k, *lda).adjoint();
}
else if(UPLO(*uplo)==LO)
matrix(c, *n, *n, *ldc).triangularView<Lower>()
+= alpha*matrix(a, *n, *k, *lda)*matrix(b, *n, *k, *ldb).adjoint()
- + internal::conj(alpha)*matrix(b, *n, *k, *ldb)*matrix(a, *n, *k, *lda).adjoint();
+ + numext::conj(alpha)*matrix(b, *n, *k, *ldb)*matrix(a, *n, *k, *lda).adjoint();
}
else if(OP(*op)==ADJ)
{
if(UPLO(*uplo)==UP)
matrix(c, *n, *n, *ldc).triangularView<Upper>()
- += alpha*matrix(a, *k, *n, *lda).adjoint()*matrix(b, *k, *n, *ldb)
- + internal::conj(alpha)*matrix(b, *k, *n, *ldb).adjoint()*matrix(a, *k, *n, *lda);
+ += alpha*matrix(a, *k, *n, *lda).adjoint()*matrix(b, *k, *n, *ldb)
+ + numext::conj(alpha)*matrix(b, *k, *n, *ldb).adjoint()*matrix(a, *k, *n, *lda);
else if(UPLO(*uplo)==LO)
matrix(c, *n, *n, *ldc).triangularView<Lower>()
- += alpha*matrix(a, *k, *n, *lda).adjoint()*matrix(b, *k, *n, *ldb)
- + internal::conj(alpha)*matrix(b, *k, *n, *ldb).adjoint()*matrix(a, *k, *n, *lda);
+ += alpha*matrix(a, *k, *n, *lda).adjoint()*matrix(b, *k, *n, *ldb)
+ + numext::conj(alpha)*matrix(b, *k, *n, *ldb).adjoint()*matrix(a, *k, *n, *lda);
}
return 1;
diff --git a/cmake/EigenConfigureTesting.cmake b/cmake/EigenConfigureTesting.cmake
index 6216a9009..228d29e97 100644
--- a/cmake/EigenConfigureTesting.cmake
+++ b/cmake/EigenConfigureTesting.cmake
@@ -24,17 +24,19 @@ set(CMAKE_MAKE_PROGRAM "@EIGEN_MAKECOMMAND_PLACEHOLDER@")
# This call activates testing and generates the DartConfiguration.tcl
include(CTest)
+set(EIGEN_TEST_BUILD_FLAGS " " CACHE STRING "Options passed to the build command of unit tests")
+
# overwrite default DartConfiguration.tcl
# The worarounds are different for each version of the MSVC IDE
if(MSVC_IDE)
if(CMAKE_MAKE_PROGRAM_SAVE MATCHES "devenv") # devenv
- set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} Eigen.sln /build \"Release\" /project buildtests \n# ")
+ set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} Eigen.sln /build \"Release\" /project buildtests ${EIGEN_TEST_BUILD_FLAGS} \n# ")
else() # msbuild
- set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} buildtests.vcxproj /p:Configuration=\${CTEST_CONFIGURATION_TYPE} \n# ")
+ set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} buildtests.vcxproj /p:Configuration=\${CTEST_CONFIGURATION_TYPE} ${EIGEN_TEST_BUILD_FLAGS}\n# ")
endif()
else()
# for make and nmake
- set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} buildtests")
+ set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} buildtests ${EIGEN_TEST_BUILD_FLAGS}")
endif()
# copy ctest properties, which currently
diff --git a/cmake/EigenTesting.cmake b/cmake/EigenTesting.cmake
index 3780888af..d9e22ab1a 100644
--- a/cmake/EigenTesting.cmake
+++ b/cmake/EigenTesting.cmake
@@ -322,13 +322,21 @@ macro(ei_get_compilerver VAR)
endif()
else()
# on all other system we rely on ${CMAKE_CXX_COMPILER}
- # supporting a "--version" flag
- execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version
- COMMAND head -n 1
- OUTPUT_VARIABLE eigen_cxx_compiler_version_string OUTPUT_STRIP_TRAILING_WHITESPACE)
+ # supporting a "--version" flag
- ei_get_compilerver_from_cxx_version_string(${eigen_cxx_compiler_version_string} CNAME CVER)
+ # check whether the head command exists
+ find_program(HEAD_EXE head NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_PATH NO_CMAKE_SYSTEM_PATH)
+ if(HEAD_EXE)
+ execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version
+ COMMAND head -n 1
+ OUTPUT_VARIABLE eigen_cxx_compiler_version_string OUTPUT_STRIP_TRAILING_WHITESPACE)
+ else()
+ execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version
+ OUTPUT_VARIABLE eigen_cxx_compiler_version_string OUTPUT_STRIP_TRAILING_WHITESPACE)
+ string(REGEX REPLACE "[\n\r].*" "" eigen_cxx_compiler_version_string ${eigen_cxx_compiler_version_string})
+ endif()
+ ei_get_compilerver_from_cxx_version_string("${eigen_cxx_compiler_version_string}" CNAME CVER)
set(${VAR} "${CNAME}-${CVER}")
endif()
endmacro(ei_get_compilerver)
diff --git a/cmake/FindCholmod.cmake b/cmake/FindCholmod.cmake
index 9095bea31..7b3046d45 100644
--- a/cmake/FindCholmod.cmake
+++ b/cmake/FindCholmod.cmake
@@ -73,8 +73,17 @@ if(CHOLMOD_LIBRARIES)
endif(CHOLMOD_LIBRARIES)
+if(CHOLMOD_LIBRARIES)
+
+ find_library(SUITESPARSE_LIBRARY SuiteSparse PATHS ${CHOLMOD_LIBDIR} $ENV{CHOLMODDIR} ${LIB_INSTALL_DIR})
+ if (SUITESPARSE_LIBRARY)
+ set(CHOLMOD_LIBRARIES ${CHOLMOD_LIBRARIES} ${SUITESPARSE_LIBRARY})
+ endif (SUITESPARSE_LIBRARY)
+
+endif(CHOLMOD_LIBRARIES)
+
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CHOLMOD DEFAULT_MSG
CHOLMOD_INCLUDES CHOLMOD_LIBRARIES)
-mark_as_advanced(CHOLMOD_INCLUDES CHOLMOD_LIBRARIES AMD_LIBRARY COLAMD_LIBRARY)
+mark_as_advanced(CHOLMOD_INCLUDES CHOLMOD_LIBRARIES AMD_LIBRARY COLAMD_LIBRARY SUITESPARSE_LIBRARY)
diff --git a/cmake/FindSPQR.cmake b/cmake/FindSPQR.cmake
index 55c4d9f6e..794c212af 100644
--- a/cmake/FindSPQR.cmake
+++ b/cmake/FindSPQR.cmake
@@ -21,6 +21,15 @@ find_path(SPQR_INCLUDES
find_library(SPQR_LIBRARIES spqr $ENV{SPQRDIR} ${LIB_INSTALL_DIR})
+if(SPQR_LIBRARIES)
+
+ find_library(SUITESPARSE_LIBRARY SuiteSparse PATHS $ENV{SPQRDIR} ${LIB_INSTALL_DIR})
+ if (SUITESPARSE_LIBRARY)
+ set(SPQR_LIBRARIES ${SPQR_LIBRARIES} ${SUITESPARSE_LIBRARY})
+ endif (SUITESPARSE_LIBRARY)
+
+endif(SPQR_LIBRARIES)
+
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SPQR DEFAULT_MSG SPQR_INCLUDES SPQR_LIBRARIES)
diff --git a/cmake/FindUmfpack.cmake b/cmake/FindUmfpack.cmake
index ab58405bb..16b046cd6 100644
--- a/cmake/FindUmfpack.cmake
+++ b/cmake/FindUmfpack.cmake
@@ -16,31 +16,24 @@ find_path(UMFPACK_INCLUDES
ufsparse
)
-if(NOT UMFPACK_LIBRARIES)
-
find_library(UMFPACK_LIBRARIES umfpack PATHS $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR})
if(UMFPACK_LIBRARIES)
+
if (NOT UMFPACK_LIBDIR)
get_filename_component(UMFPACK_LIBDIR ${UMFPACK_LIBRARIES} PATH)
endif(NOT UMFPACK_LIBDIR)
- find_library(AMD_LIBRARY amd PATHS ${UMFPACK_LIBDIR} $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR})
- if (AMD_LIBRARY)
- set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${AMD_LIBRARY})
- #else (AMD_LIBRARY)
- # set(UMFPACK_LIBRARIES FALSE)
- endif (AMD_LIBRARY)
-
-endif(UMFPACK_LIBRARIES)
-
-if(UMFPACK_LIBRARIES)
-
find_library(COLAMD_LIBRARY colamd PATHS ${UMFPACK_LIBDIR} $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR})
if (COLAMD_LIBRARY)
set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${COLAMD_LIBRARY})
endif (COLAMD_LIBRARY)
+ find_library(AMD_LIBRARY amd PATHS ${UMFPACK_LIBDIR} $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR})
+ if (AMD_LIBRARY)
+ set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${AMD_LIBRARY})
+ endif (AMD_LIBRARY)
+
find_library(SUITESPARSE_LIBRARY SuiteSparse PATHS ${UMFPACK_LIBDIR} $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR})
if (SUITESPARSE_LIBRARY)
set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${SUITESPARSE_LIBRARY})
@@ -48,10 +41,8 @@ if(UMFPACK_LIBRARIES)
endif(UMFPACK_LIBRARIES)
-endif()
-
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(UMFPACK DEFAULT_MSG
UMFPACK_INCLUDES UMFPACK_LIBRARIES)
-mark_as_advanced(UMFPACK_INCLUDES UMFPACK_LIBRARIES AMD_LIBRARY COLAMD_LIBRARY)
+mark_as_advanced(UMFPACK_INCLUDES UMFPACK_LIBRARIES AMD_LIBRARY COLAMD_LIBRARY SUITESPARSE_LIBRARY)
diff --git a/doc/A05_PortingFrom2To3.dox b/doc/A05_PortingFrom2To3.dox
index 3750316c5..d885b4f6d 100644
--- a/doc/A05_PortingFrom2To3.dox
+++ b/doc/A05_PortingFrom2To3.dox
@@ -281,7 +281,7 @@ result = Vector4f::MapAligned(some_aligned_array);
\section StdContainers STL Containers
-In Eigen2, #include<Eigen/StdVector> tweaked std::vector to automatically align elements. The problem was that that was quite invasive. In Eigen3, we only override standard behavior if you use Eigen::aligned_allocator<T> as your allocator type. So for example, if you use std::vector<Matrix4f>, you need to do the following change (note that aligned_allocator is under namespace Eigen):
+In Eigen2, <tt>#include<Eigen/StdVector></tt> tweaked std::vector to automatically align elements. The problem was that that was quite invasive. In Eigen3, we only override standard behavior if you use Eigen::aligned_allocator<T> as your allocator type. So for example, if you use std::vector<Matrix4f>, you need to do the following change (note that aligned_allocator is under namespace Eigen):
<table class="manual">
<tr><th>Eigen 2</th><th>Eigen 3</th></tr>
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index dfe47b849..8a493031c 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -91,7 +91,7 @@ add_custom_target(doc ALL
COMMAND doxygen Doxyfile-unsupported
COMMAND ${CMAKE_COMMAND} -E rename html eigen-doc
COMMAND ${CMAKE_COMMAND} -E remove eigen-doc/eigen-doc.tgz
- COMMAND ${CMAKE_COMMAND} -E tar cvfz eigen-doc/eigen-doc.tgz eigen-doc
+ COMMAND ${CMAKE_COMMAND} -E tar cfz eigen-doc/eigen-doc.tgz eigen-doc
COMMAND ${CMAKE_COMMAND} -E rename eigen-doc html
WORKING_DIRECTORY ${Eigen_BINARY_DIR}/doc)
diff --git a/doc/FunctionsTakingEigenTypes.dox b/doc/FunctionsTakingEigenTypes.dox
index ad315edf0..152dda47d 100644
--- a/doc/FunctionsTakingEigenTypes.dox
+++ b/doc/FunctionsTakingEigenTypes.dox
@@ -1,18 +1,18 @@
namespace Eigen {
-/** \page TopicFunctionTakingEigenTypes Writing Functions Taking Eigen Types as Parameters
+/** \page TopicFunctionTakingEigenTypes Writing Functions Taking %Eigen Types as Parameters
-Eigen's use of expression templates results in potentially every expression being of a different type. If you pass such an expression to a function taking a parameter of type Matrix, your expression will implicitly be evaluated into a temporary Matrix, which will then be passed to the function. This means that you lose the benefit of expression templates. Concretely, this has two drawbacks:
+%Eigen's use of expression templates results in potentially every expression being of a different type. If you pass such an expression to a function taking a parameter of type Matrix, your expression will implicitly be evaluated into a temporary Matrix, which will then be passed to the function. This means that you lose the benefit of expression templates. Concretely, this has two drawbacks:
\li The evaluation into a temporary may be useless and inefficient;
\li This only allows the function to read from the expression, not to write to it.
-Fortunately, all this myriad of expression types have in common that they all inherit a few common, templated base classes. By letting your function take templated parameters of these base types, you can let them play nicely with Eigen's expression templates.
+Fortunately, all this myriad of expression types have in common that they all inherit a few common, templated base classes. By letting your function take templated parameters of these base types, you can let them play nicely with %Eigen's expression templates.
\eigenAutoToc
\section TopicFirstExamples Some First Examples
-This section will provide simple examples for different types of objects Eigen is offering. Before starting with the actual examples, we need to recapitulate which base objects we can work with (see also \ref TopicClassHierarchy).
+This section will provide simple examples for different types of objects %Eigen is offering. Before starting with the actual examples, we need to recapitulate which base objects we can work with (see also \ref TopicClassHierarchy).
\li MatrixBase: The common base class for all dense matrix expressions (as opposed to array expressions, as opposed to sparse and special matrix classes). Use it in functions that are meant to work only on dense matrices.
\li ArrayBase: The common base class for all dense array expressions (as opposed to matrix expressions, etc). Use it in functions that are meant to work only on arrays.
@@ -20,7 +20,7 @@ This section will provide simple examples for different types of objects Eigen i
\li EigenBase: The base class unifying all types of objects that can be evaluated into dense matrices or arrays, for example special matrix classes such as diagonal matrices, permutation matrices, etc. It can be used in functions that are meant to work on any such general type.
<b> %EigenBase Example </b><br/><br/>
-Prints the dimensions of the most generic object present in Eigen. It coulde be any matrix expressions, any dense or sparse matrix and any array.
+Prints the dimensions of the most generic object present in %Eigen. It could be any matrix expressions, any dense or sparse matrix and any array.
<table class="example">
<tr><th>Example:</th><th>Output:</th></tr>
<tr><td>
@@ -76,9 +76,42 @@ where the first argument \c v1 is a vector and the second argument \c 2*v2 is an
These examples are just intended to give the reader a first impression of how functions can be written which take a plain and constant Matrix or Array argument. They are also intended to give the reader an idea about the most common base classes being the optimal candidates for functions. In the next section we will look in more detail at an example and the different ways it can be implemented, while discussing each implementation's problems and advantages. For the discussion below, Matrix and Array as well as MatrixBase and ArrayBase can be exchanged and all arguments still hold.
+
+\section TopicUsingRefClass How to write generic, but non-templated function?
+
+In all the previous examples, the functions had to be template functions. This approach allows to write very generic code, but it is often desirable to write non templated function and still keep some level of genericity to avoid stupid copies of the arguments. The typical example is to write functions accepting both a MatrixXf or a block of a MatrixXf. This exactly the purpose of the Ref class. Here is a simple example:
+
+<table class="example">
+<tr><th>Example:</th><th>Output:</th></tr>
+<tr><td>
+\include function_taking_ref.cpp
+</td>
+<td>
+\verbinclude function_taking_ref.out
+</td></tr></table>
+In the first two calls to inv_cond, no copy occur because the memory layout of the arguments matches the memory layout accepted by Ref<MatrixXf>. However, in the last call, we have a generic expression that will be automatically evaluated into a temporary MatrixXf by the Ref<> object.
+
+A Ref object can also be writable. Here is an example of a function computing the covariance matrix of two input matrices where each row is an observation:
+\code
+void cov(const Ref<const MatrixXf> x, const Ref<const MatrixXf> y, Ref<MatrixXf> C)
+{
+ const float num_observations = static_cast<float>(x.rows());
+ const RowVectorXf x_mean = x.colwise().sum() / num_observations;
+ const RowVectorXf y_mean = y.colwise().sum() / num_observations;
+ C = (x.rowwise() - x_mean).transpose() * (y.rowwise() - y_mean) / num_observations;
+}
+\endcode
+and here are two examples calling cov without any copy:
+\code
+MatrixXf m1, m2, m3
+cov(m1, m2, m3);
+cov(m1.leftCols<3>(), m2.leftCols<3>(), m3.topLeftCorner<3,3>());
+\endcode
+The Ref<> class has two other optional template arguments allowing to control the kind of memory layout that can be accepted without any copy. See the class Ref documentation for the details.
+
\section TopicPlainFunctionsWorking In which cases do functions taking plain Matrix or Array arguments work?
-Let's assume one wants to write a function computing the covariance matrix of two input matrices where each row is an observation. The implementation of this function might look like this
+Without using template functions, and without the Ref class, a naive implementation of the previous cov function might look like this
\code
MatrixXf cov(const MatrixXf& x, const MatrixXf& y)
{
@@ -88,7 +121,7 @@ MatrixXf cov(const MatrixXf& x, const MatrixXf& y)
return (x.rowwise() - x_mean).transpose() * (y.rowwise() - y_mean) / num_observations;
}
\endcode
-and contrary to what one might think at first, this implementation is fine unless you require a genric implementation that works with double matrices too and unless you do not care about temporary objects. Why is that the case? Where are temporaries involved? How can code as given below compile?
+and contrary to what one might think at first, this implementation is fine unless you require a generic implementation that works with double matrices too and unless you do not care about temporary objects. Why is that the case? Where are temporaries involved? How can code as given below compile?
\code
MatrixXf x,y,z;
MatrixXf C = cov(x,y+z);
@@ -97,6 +130,7 @@ In this special case, the example is fine and will be working because both param
\b Note: Functions taking \e const references to Matrix (or Array) can process expressions at the cost of temporaries.
+
\section TopicPlainFunctionsFailing In which cases do functions taking a plain Matrix or Array argument fail?
Here, we consider a slightly modified version of the function given above. This time, we do not want to return the result but pass an additional non-const paramter which allows us to store the result. A first naive implementation might look as follows.
@@ -149,7 +183,7 @@ MatrixXf y = MatrixXf::Random(100,3);
MatrixXf C;
cov(x, y, C);
\endcode
-This is not the case anymore, when we are using an implementation taking MatrixBase as a parameter. In general, Eigen supports automatic resizing but it is not possible to do so on expressions. Why should resizing of a matrix Block be allowed? It is a reference to a sub-matrix and we definitely don't want to resize that. So how can we incorporate resizing if we cannot resize on MatrixBase? The solution is to resize the derived object as in this implementation.
+This is not the case anymore, when we are using an implementation taking MatrixBase as a parameter. In general, %Eigen supports automatic resizing but it is not possible to do so on expressions. Why should resizing of a matrix Block be allowed? It is a reference to a sub-matrix and we definitely don't want to resize that. So how can we incorporate resizing if we cannot resize on MatrixBase? The solution is to resize the derived object as in this implementation.
\code
template <typename Derived, typename OtherDerived>
void cov(const MatrixBase<Derived>& x, const MatrixBase<Derived>& y, MatrixBase<OtherDerived> const & C_)
diff --git a/doc/LinearLeastSquares.dox b/doc/LinearLeastSquares.dox
new file mode 100644
index 000000000..ab21a87ae
--- /dev/null
+++ b/doc/LinearLeastSquares.dox
@@ -0,0 +1,27 @@
+namespace Eigen {
+
+/** \eigenManualPage LinearLeastSquares Solving linear least squares problems
+
+lede
+
+\eigenAutoToc
+
+\section LinearLeastSquaresCopied Copied
+
+The best way to do least squares solving is with a SVD decomposition. Eigen provides one as the JacobiSVD class, and its solve()
+is doing least-squares solving.
+
+Here is an example:
+<table class="example">
+<tr><th>Example:</th><th>Output:</th></tr>
+<tr>
+ <td>\include TutorialLinAlgSVDSolve.cpp </td>
+ <td>\verbinclude TutorialLinAlgSVDSolve.out </td>
+</tr>
+</table>
+
+For more information, including faster but less reliable methods, read our page concentrating on \ref LinearLeastSquares "linear least squares problems".
+
+*/
+
+}
diff --git a/doc/Manual.dox b/doc/Manual.dox
index d6b9f7adf..3367982ca 100644
--- a/doc/Manual.dox
+++ b/doc/Manual.dox
@@ -135,6 +135,8 @@ namespace Eigen {
\ingroup Sparse_Reference */
/** \addtogroup IterativeLinearSolvers_Module
\ingroup Sparse_Reference */
+/** \addtogroup Sparse_Module
+ \ingroup Sparse_Reference */
/** \addtogroup Support_modules
\ingroup Sparse_Reference */
diff --git a/doc/QuickReference.dox b/doc/QuickReference.dox
index a5f0dab56..5e0168649 100644
--- a/doc/QuickReference.dox
+++ b/doc/QuickReference.dox
@@ -45,7 +45,7 @@ All combinations are allowed: you can have a matrix with a fixed number of rows
Matrix<double, 6, Dynamic> // Dynamic number of columns (heap allocation)
Matrix<double, Dynamic, 2> // Dynamic number of rows (heap allocation)
Matrix<double, Dynamic, Dynamic, RowMajor> // Fully dynamic, row major (heap allocation)
-Matrix<double, 13, 3> // Fully fixed (static allocation)
+Matrix<double, 13, 3> // Fully fixed (usually allocated on stack)
\endcode
In most cases, you can simply use one of the convenience typedefs for \ref matrixtypedefs "matrices" and \ref arraytypedefs "arrays". Some examples:
diff --git a/doc/TopicAliasing.dox b/doc/TopicAliasing.dox
index bd1d329ce..c2654aed2 100644
--- a/doc/TopicAliasing.dox
+++ b/doc/TopicAliasing.dox
@@ -2,7 +2,7 @@ namespace Eigen {
/** \eigenManualPage TopicAliasing Aliasing
-In Eigen, aliasing refers to assignment statement in which the same matrix (or array or vector) appears on the
+In %Eigen, aliasing refers to assignment statement in which the same matrix (or array or vector) appears on the
left and on the right of the assignment operators. Statements like <tt>mat = 2 * mat;</tt> or <tt>mat =
mat.transpose();</tt> exhibit aliasing. The aliasing in the first example is harmless, but the aliasing in the
second example leads to unexpected results. This page explains what aliasing is, when it is harmful, and what
@@ -32,7 +32,7 @@ This assignment exhibits aliasing: the coefficient \c mat(1,1) appears both in t
<tt>mat.bottomRightCorner(2,2)</tt> on the left-hand side of the assignment and the block
<tt>mat.topLeftCorner(2,2)</tt> on the right-hand side. After the assignment, the (2,2) entry in the bottom
right corner should have the value of \c mat(1,1) before the assignment, which is 5. However, the output shows
-that \c mat(2,2) is actually 1. The problem is that Eigen uses lazy evaluation (see
+that \c mat(2,2) is actually 1. The problem is that %Eigen uses lazy evaluation (see
\ref TopicEigenExpressionTemplates) for <tt>mat.topLeftCorner(2,2)</tt>. The result is similar to
\code
mat(1,1) = mat(0,0);
@@ -43,10 +43,13 @@ mat(2,2) = mat(1,1);
Thus, \c mat(2,2) is assigned the \e new value of \c mat(1,1) instead of the old value. The next section
explains how to solve this problem by calling \link DenseBase::eval() eval()\endlink.
-Note that if \c mat were a bigger, then the blocks would not overlap, and there would be no aliasing
-problem. This means that in general aliasing cannot be detected at compile time. However, Eigen does detect
-some instances of aliasing, albeit at run time. The following example exhibiting aliasing was mentioned in
-\ref TutorialMatrixArithmetic :
+Aliasing occurs more naturally when trying to shrink a matrix. For example, the expressions <tt>vec =
+vec.head(n)</tt> and <tt>mat = mat.block(i,j,r,c)</tt> exhibit aliasing.
+
+In general, aliasing cannot be detected at compile time: if \c mat in the first example were a bit bigger,
+then the blocks would not overlap, and there would be no aliasing problem. However, %Eigen does detect some
+instances of aliasing, albeit at run time. The following example exhibiting aliasing was mentioned in \ref
+TutorialMatrixArithmetic :
<table class="example">
<tr><th>Example</th><th>Output</th></tr>
@@ -57,24 +60,24 @@ some instances of aliasing, albeit at run time. The following example exhibitin
\verbinclude tut_arithmetic_transpose_aliasing.out
</td></tr></table>
-Again, the output shows the aliasing issue. However, by default Eigen uses a run-time assertion to detect this
+Again, the output shows the aliasing issue. However, by default %Eigen uses a run-time assertion to detect this
and exits with a message like
\verbatim
void Eigen::DenseBase<Derived>::checkTransposeAliasing(const OtherDerived&) const
[with OtherDerived = Eigen::Transpose<Eigen::Matrix<int, 2, 2, 0, 2, 2> >, Derived = Eigen::Matrix<int, 2, 2, 0, 2, 2>]:
Assertion `(!internal::check_transpose_aliasing_selector<Scalar,internal::blas_traits<Derived>::IsTransposed,OtherDerived>::run(internal::extract_data(derived()), other))
-&& "aliasing detected during tranposition, use transposeInPlace() or evaluate the rhs into a temporary using .eval()"' failed.
+&& "aliasing detected during transposition, use transposeInPlace() or evaluate the rhs into a temporary using .eval()"' failed.
\endverbatim
-The user can turn Eigen's run-time assertions like the one to detect this aliasing problem off by defining the
+The user can turn %Eigen's run-time assertions like the one to detect this aliasing problem off by defining the
EIGEN_NO_DEBUG macro, and the above program was compiled with this macro turned off in order to illustrate the
-aliasing problem. See \ref TopicAssertions for more information about Eigen's run-time assertions.
+aliasing problem. See \ref TopicAssertions for more information about %Eigen's run-time assertions.
\section TopicAliasingSolution Resolving aliasing issues
-If you understand the cause of the aliasing issue, then it is obvious what must happen to solve it: Eigen has
+If you understand the cause of the aliasing issue, then it is obvious what must happen to solve it: %Eigen has
to evaluate the right-hand side fully into a temporary matrix/array and then assign it to the left-hand
side. The function \link DenseBase::eval() eval() \endlink does precisely that.
@@ -93,7 +96,7 @@ Now, \c mat(2,2) equals 5 after the assignment, as it should be.
The same solution also works for the second example, with the transpose: simply replace the line
<tt>a = a.transpose();</tt> with <tt>a = a.transpose().eval();</tt>. However, in this common case there is a
-better solution. Eigen provides the special-purpose function
+better solution. %Eigen provides the special-purpose function
\link DenseBase::transposeInPlace() transposeInPlace() \endlink which replaces a matrix by its transpose.
This is shown below:
@@ -107,7 +110,7 @@ This is shown below:
</td></tr></table>
If an xxxInPlace() function is available, then it is best to use it, because it indicates more clearly what you
-are doing. This may also allow Eigen to optimize more aggressively. These are some of the xxxInPlace()
+are doing. This may also allow %Eigen to optimize more aggressively. These are some of the xxxInPlace()
functions provided:
<table class="manual">
@@ -120,6 +123,9 @@ functions provided:
<tr class="alt"> <td> DenseBase::transpose() </td> <td> DenseBase::transposeInPlace() </td> </tr>
</table>
+In the special case where a matrix or vector is shrunk using an expression like <tt>vec = vec.head(n)</tt>,
+you can use \link PlainObjectBase::conservativeResize() conservativeResize() \endlink.
+
\section TopicAliasingCwise Aliasing and component-wise operations
@@ -128,8 +134,8 @@ right-hand side of an assignment operator, and it is then often necessary to eva
explicitly. However, applying component-wise operations (such as matrix addition, scalar multiplication and
array multiplication) is safe.
-The following example has only component-wise operations. Thus, there is no need for .eval() even though
-the same matrix appears on both sides of the assignments.
+The following example has only component-wise operations. Thus, there is no need for \link DenseBase::eval()
+eval() \endlink even though the same matrix appears on both sides of the assignments.
<table class="example">
<tr><th>Example</th><th>Output</th></tr>
@@ -147,8 +153,8 @@ not necessary to evaluate the right-hand side explicitly.
\section TopicAliasingMatrixMult Aliasing and matrix multiplication
-Matrix multiplication is the only operation in Eigen that assumes aliasing by default. Thus, if \c matA is a
-matrix, then the statement <tt>matA = matA * matA;</tt> is safe. All other operations in Eigen assume that
+Matrix multiplication is the only operation in %Eigen that assumes aliasing by default. Thus, if \c matA is a
+matrix, then the statement <tt>matA = matA * matA;</tt> is safe. All other operations in %Eigen assume that
there are no aliasing problems, either because the result is assigned to a different matrix or because it is a
component-wise operation.
@@ -161,14 +167,14 @@ component-wise operation.
\verbinclude TopicAliasing_mult1.out
</td></tr></table>
-However, this comes at a price. When executing the expression <tt>matA = matA * matA</tt>, Eigen evaluates the
-product in a temporary matrix which is assigned to \c matA after the computation. This is fine. But Eigen does
+However, this comes at a price. When executing the expression <tt>matA = matA * matA</tt>, %Eigen evaluates the
+product in a temporary matrix which is assigned to \c matA after the computation. This is fine. But %Eigen does
the same when the product is assigned to a different matrix (e.g., <tt>matB = matA * matA</tt>). In that case,
it is more efficient to evaluate the product directly into \c matB instead of evaluating it first into a
temporary matrix and copying that matrix to \c matB.
The user can indicate with the \link MatrixBase::noalias() noalias()\endlink function that there is no
-aliasing, as follows: <tt>matB.noalias() = matA * matA</tt>. This allows Eigen to evaluate the matrix product
+aliasing, as follows: <tt>matB.noalias() = matA * matA</tt>. This allows %Eigen to evaluate the matrix product
<tt>matA * matA</tt> directly into \c matB.
<table class="example">
@@ -199,9 +205,9 @@ Aliasing occurs when the same matrix or array coefficients appear both on the le
an assignment operator.
- Aliasing is harmless with coefficient-wise computations; this includes scalar multiplication and matrix or
array addition.
- - When you multiply two matrices, Eigen assumes that aliasing occurs. If you know that there is no aliasing,
+ - When you multiply two matrices, %Eigen assumes that aliasing occurs. If you know that there is no aliasing,
then you can use \link MatrixBase::noalias() noalias()\endlink.
- - In all other situations, Eigen assumes that there is no aliasing issue and thus gives the wrong result if
+ - In all other situations, %Eigen assumes that there is no aliasing issue and thus gives the wrong result if
aliasing does in fact occur. To prevent this, you have to use \link DenseBase::eval() eval() \endlink or
one of the xxxInPlace() functions.
diff --git a/doc/TutorialMatrixClass.dox b/doc/TutorialMatrixClass.dox
index 057341422..7ea0cd789 100644
--- a/doc/TutorialMatrixClass.dox
+++ b/doc/TutorialMatrixClass.dox
@@ -79,8 +79,8 @@ Matrix3f a;
MatrixXf b;
\endcode
Here,
-\li \c a is a 3x3 matrix, with a static float[9] array of uninitialized coefficients,
-\li \c b is a dynamic-size matrix whose size is currently 0x0, and whose array of
+\li \c a is a 3-by-3 matrix, with a plain float[9] array of uninitialized coefficients,
+\li \c b is a dynamic-size matrix whose size is currently 0-by-0, and whose array of
coefficients hasn't yet been allocated at all.
Constructors taking sizes are also available. For matrices, the number of rows is always passed first.
@@ -197,7 +197,7 @@ The simple answer is: use fixed
sizes for very small sizes where you can, and use dynamic sizes for larger sizes or where you have to. For small sizes,
especially for sizes smaller than (roughly) 16, using fixed sizes is hugely beneficial
to performance, as it allows Eigen to avoid dynamic memory allocation and to unroll
-loops. Internally, a fixed-size Eigen matrix is just a plain static array, i.e. doing
+loops. Internally, a fixed-size Eigen matrix is just a plain array, i.e. doing
\code Matrix4f mymatrix; \endcode
really amounts to just doing
\code float mymatrix[16]; \endcode
@@ -212,8 +212,9 @@ member variables.
The limitation of using fixed sizes, of course, is that this is only possible
when you know the sizes at compile time. Also, for large enough sizes, say for sizes
greater than (roughly) 32, the performance benefit of using fixed sizes becomes negligible.
-Worse, trying to create a very large matrix using fixed sizes could result in a stack overflow,
-since Eigen will try to allocate the array as a static array, which by default goes on the stack.
+Worse, trying to create a very large matrix using fixed sizes inside a function could result in a
+stack overflow, since Eigen will try to allocate the array automatically as a local variable, and
+this is normally done on the stack.
Finally, depending on circumstances, Eigen can also be more aggressive trying to vectorize
(use SIMD instructions) when dynamic sizes are used, see \ref TopicVectorization "Vectorization".
@@ -239,7 +240,7 @@ Matrix<typename Scalar,
\li \c MaxRowsAtCompileTime and \c MaxColsAtCompileTime are useful when you want to specify that, even though
the exact sizes of your matrices are not known at compile time, a fixed upper bound is known at
compile time. The biggest reason why you might want to do that is to avoid dynamic memory allocation.
- For example the following matrix type uses a static array of 12 floats, without dynamic memory allocation:
+ For example the following matrix type uses a plain array of 12 floats, without dynamic memory allocation:
\code
Matrix<float, Dynamic, Dynamic, 0, 3, 4>
\endcode
diff --git a/doc/TutorialSparse.dox b/doc/TutorialSparse.dox
index 98c9997e1..dbfb4a9eb 100644
--- a/doc/TutorialSparse.dox
+++ b/doc/TutorialSparse.dox
@@ -2,7 +2,7 @@ namespace Eigen {
/** \eigenManualPage TutorialSparse Sparse matrix manipulations
-\eigeneigenAutoToc
+\eigenAutoToc
Manipulating and solving sparse problems involves various modules which are summarized below:
@@ -14,7 +14,7 @@ Manipulating and solving sparse problems involves various modules which are summ
<td>%Sparse LU factorization to solve general square sparse systems</td></tr>
<tr><td>\link SparseQR_Module SparseQR \endlink</td><td>\code #include<Eigen/SparseQR>\endcode </td><td>%Sparse QR factorization for solving sparse linear least-squares problems</td></tr>
<tr><td>\link IterativeLinearSolvers_Module IterativeLinearSolvers \endlink</td><td>\code#include <Eigen/IterativeLinearSolvers>\endcode</td><td>Iterative solvers to solve large general linear square problems (including self-adjoint positive definite problems)</td></tr>
-<tr><td>\link Sparse_modules Sparse \endlink</td><td>\code#include <Eigen/Sparse>\endcode</td><td>Includes all the above modules</td></tr>
+<tr><td>\link Sparse_Module Sparse \endlink</td><td>\code#include <Eigen/Sparse>\endcode</td><td>Includes all the above modules</td></tr>
</table>
\section TutorialSparseIntro Sparse matrix format
@@ -116,7 +116,7 @@ Describing the \a buildProblem and \a save functions is out of the scope of this
The SparseMatrix and SparseVector classes take three template arguments:
* the scalar type (e.g., double)
- * the storage order (ColMajor or RowMajor, the default is RowMajor)
+ * the storage order (ColMajor or RowMajor, the default is ColMajor)
* the inner index type (default is \c int).
As for dense Matrix objects, constructors takes the size of the object.
@@ -290,9 +290,9 @@ sm3 = 4 * sm1.adjoint() * sm2;
\endcode
The second algorithm prunes on the fly the explicit zeros, or the values smaller than a given threshold. It is enabled and controlled through the prune() functions:
\code
-sm3 = (sm1 * sm2).prune(); // removes numerical zeros
-sm3 = (sm1 * sm2).prune(ref); // removes elements much smaller than ref
-sm3 = (sm1 * sm2).prune(ref,epsilon); // removes elements smaller than ref*epsilon
+sm3 = (sm1 * sm2).pruned(); // removes numerical zeros
+sm3 = (sm1 * sm2).pruned(ref); // removes elements much smaller than ref
+sm3 = (sm1 * sm2).pruned(ref,epsilon); // removes elements smaller than ref*epsilon
\endcode
- \b permutations. Finally, permutations can be applied to sparse matrices too:
diff --git a/doc/UsingIntelMKL.dox b/doc/UsingIntelMKL.dox
index 7c5981460..4b624a156 100644
--- a/doc/UsingIntelMKL.dox
+++ b/doc/UsingIntelMKL.dox
@@ -40,7 +40,7 @@ Since Eigen version 3.1 and later, users can benefit from built-in Intel MKL opt
<a href="http://eigen.tuxfamily.org/Counter/redirect_to_mkl.php"> Intel MKL </a> provides highly optimized multi-threaded mathematical routines for x86-compatible architectures.
Intel MKL is available on Linux, Mac and Windows for both Intel64 and IA32 architectures.
-\warning Be aware that Intel® MKL is a proprietary software. It is the responsibility of the users to buy MKL licenses for their products. Moreover, the license of the user product has to allow linking to proprietary software that excludes any unmodified versions of the GPL. As a consequence, this also means that Eigen has to be used through the LGPL3+ license.
+\warning Be aware that Intel® MKL is a proprietary software. It is the responsibility of the users to buy MKL licenses for their products. Moreover, the license of the user product has to allow linking to proprietary software that excludes any unmodified versions of the GPL.
Using Intel MKL through Eigen is easy:
-# define the \c EIGEN_USE_MKL_ALL macro before including any Eigen's header
diff --git a/doc/examples/function_taking_ref.cpp b/doc/examples/function_taking_ref.cpp
new file mode 100644
index 000000000..162a202e4
--- /dev/null
+++ b/doc/examples/function_taking_ref.cpp
@@ -0,0 +1,19 @@
+#include <iostream>
+#include <Eigen/SVD>
+using namespace Eigen;
+using namespace std;
+
+float inv_cond(const Ref<const MatrixXf>& a)
+{
+ const VectorXf sing_vals = a.jacobiSvd().singularValues();
+ return sing_vals(sing_vals.size()-1) / sing_vals(0);
+}
+
+int main()
+{
+ Matrix4f m = Matrix4f::Random();
+ cout << "matrix m:" << endl << m << endl << endl;
+ cout << "inv_cond(m): " << inv_cond(m) << endl;
+ cout << "inv_cond(m(1:3,1:3)): " << inv_cond(m.topLeftCorner(3,3)) << endl;
+ cout << "inv_cond(m+I): " << inv_cond(m+Matrix4f::Identity()) << endl;
+}
diff --git a/doc/snippets/Cwise_asin.cpp b/doc/snippets/Cwise_asin.cpp
new file mode 100644
index 000000000..8dad838fd
--- /dev/null
+++ b/doc/snippets/Cwise_asin.cpp
@@ -0,0 +1,2 @@
+Array3d v(0, sqrt(2.)/2, 1);
+cout << v.asin() << endl;
diff --git a/doc/snippets/MatrixBase_template_int_int_block_int_int_int_int.cpp b/doc/snippets/MatrixBase_template_int_int_block_int_int_int_int.cpp
new file mode 100644
index 000000000..4dced03ba
--- /dev/null
+++ b/doc/snippets/MatrixBase_template_int_int_block_int_int_int_int.cpp
@@ -0,0 +1,5 @@
+Matrix4i m = Matrix4i::Random();
+cout << "Here is the matrix m:" << endl << m << endl;
+cout << "Here is the block:" << endl << m.block<2, Dynamic>(1, 1, 2, 3) << endl;
+m.block<2, Dynamic>(1, 1, 2, 3).setZero();
+cout << "Now the matrix m is:" << endl << m << endl;
diff --git a/doc/snippets/MatrixBase_template_int_int_bottomLeftCorner_int_int.cpp b/doc/snippets/MatrixBase_template_int_int_bottomLeftCorner_int_int.cpp
new file mode 100644
index 000000000..a1edcc808
--- /dev/null
+++ b/doc/snippets/MatrixBase_template_int_int_bottomLeftCorner_int_int.cpp
@@ -0,0 +1,6 @@
+Matrix4i m = Matrix4i::Random();
+cout << "Here is the matrix m:" << endl << m << endl;
+cout << "Here is m.bottomLeftCorner<2,Dynamic>(2,2):" << endl;
+cout << m.bottomLeftCorner<2,Dynamic>(2,2) << endl;
+m.bottomLeftCorner<2,Dynamic>(2,2).setZero();
+cout << "Now the matrix m is:" << endl << m << endl;
diff --git a/doc/snippets/MatrixBase_template_int_int_bottomRightCorner_int_int.cpp b/doc/snippets/MatrixBase_template_int_int_bottomRightCorner_int_int.cpp
new file mode 100644
index 000000000..a65508fd8
--- /dev/null
+++ b/doc/snippets/MatrixBase_template_int_int_bottomRightCorner_int_int.cpp
@@ -0,0 +1,6 @@
+Matrix4i m = Matrix4i::Random();
+cout << "Here is the matrix m:" << endl << m << endl;
+cout << "Here is m.bottomRightCorner<2,Dynamic>(2,2):" << endl;
+cout << m.bottomRightCorner<2,Dynamic>(2,2) << endl;
+m.bottomRightCorner<2,Dynamic>(2,2).setZero();
+cout << "Now the matrix m is:" << endl << m << endl;
diff --git a/doc/snippets/MatrixBase_template_int_int_topLeftCorner_int_int.cpp b/doc/snippets/MatrixBase_template_int_int_topLeftCorner_int_int.cpp
new file mode 100644
index 000000000..fac761f63
--- /dev/null
+++ b/doc/snippets/MatrixBase_template_int_int_topLeftCorner_int_int.cpp
@@ -0,0 +1,6 @@
+Matrix4i m = Matrix4i::Random();
+cout << "Here is the matrix m:" << endl << m << endl;
+cout << "Here is m.topLeftCorner<2,Dynamic>(2,2):" << endl;
+cout << m.topLeftCorner<2,Dynamic>(2,2) << endl;
+m.topLeftCorner<2,Dynamic>(2,2).setZero();
+cout << "Now the matrix m is:" << endl << m << endl;
diff --git a/doc/snippets/MatrixBase_template_int_int_topRightCorner_int_int.cpp b/doc/snippets/MatrixBase_template_int_int_topRightCorner_int_int.cpp
new file mode 100644
index 000000000..a17acc004
--- /dev/null
+++ b/doc/snippets/MatrixBase_template_int_int_topRightCorner_int_int.cpp
@@ -0,0 +1,6 @@
+Matrix4i m = Matrix4i::Random();
+cout << "Here is the matrix m:" << endl << m << endl;
+cout << "Here is m.topRightCorner<2,Dynamic>(2,2):" << endl;
+cout << m.topRightCorner<2,Dynamic>(2,2) << endl;
+m.topRightCorner<2,Dynamic>(2,2).setZero();
+cout << "Now the matrix m is:" << endl << m << endl;
diff --git a/lapack/CMakeLists.txt b/lapack/CMakeLists.txt
index 174e77d8d..7e7444326 100644
--- a/lapack/CMakeLists.txt
+++ b/lapack/CMakeLists.txt
@@ -18,352 +18,80 @@ single.cpp double.cpp complex_single.cpp complex_double.cpp ../blas/xerbla.cpp
if(EIGEN_Fortran_COMPILER_WORKS)
-set(EigenLapack_SRCS
-slarft.f dlarft.f clarft.f zlarft.f
-slarfb.f dlarfb.f clarfb.f zlarfb.f
-slarfg.f dlarfg.f clarfg.f zlarfg.f
-slarf.f dlarf.f clarf.f zlarf.f
+set(EigenLapack_SRCS ${EigenLapack_SRCS}
+ slarft.f dlarft.f clarft.f zlarft.f
+ slarfb.f dlarfb.f clarfb.f zlarfb.f
+ slarfg.f dlarfg.f clarfg.f zlarfg.f
+ slarf.f dlarf.f clarf.f zlarf.f
+ sladiv.f dladiv.f cladiv.f zladiv.f
+ ilaslr.f iladlr.f ilaclr.f ilazlr.f
+ ilaslc.f iladlc.f ilaclc.f ilazlc.f
+ dlapy2.f dlapy3.f slapy2.f slapy3.f
+ clacgv.f zlacgv.f
+ slamch.f dlamch.f
+ second_NONE.f dsecnd_NONE.f
)
-get_filename_component(eigen_full_path_to_reference_to_reference_lapack "./reference/" ABSOLUTE)
-if(EXISTS ${eigen_full_path_to_reference_to_reference_lapack})
-set(EigenLapack_SRCS ${EigenLapack_SRCS}
-# reference/dpotrf.f reference/zpotrf.f reference/cpotrf.f reference/spotrf.f
-# reference/dpotrs.f reference/spotrs.f reference/zpotrs.f reference/cpotrs.f
-# reference/dgetrf.f reference/cgetrf.f reference/sgetrf.f reference/zgetrf.f
-# reference/cgetrs.f reference/dgetrs.f reference/sgetrs.f reference/zgetrs.f
-# reference/dsyev.f reference/ssyev.f
-reference/dlamch.f reference/ilaver.f reference/lsame.f reference/slamch.f reference/second_NONE.f reference/dsecnd_NONE.f
-reference/cbdsqr.f reference/ctbrfs.f reference/dorml2.f reference/sla_porfsx_extended.f reference/zggglm.f
-reference/cgbbrd.f reference/ctbtrs.f reference/dormlq.f reference/sla_porpvgrw.f reference/zgghrd.f
-reference/cgbcon.f reference/ctfsm.f reference/dormql.f reference/slapy2.f reference/zgglse.f
-reference/cgbequb.f reference/ctftri.f reference/dormqr.f reference/slapy3.f reference/zggqrf.f
-reference/cgbequ.f reference/ctfttp.f reference/dormr2.f reference/slaqgb.f reference/zggrqf.f
-reference/cgbrfs.f reference/ctfttr.f reference/dormr3.f reference/slaqge.f reference/zggsvd.f
-reference/cgbrfsx.f reference/ctgevc.f reference/dormrq.f reference/slaqp2.f reference/zggsvp.f
-reference/cgbsv.f reference/ctgex2.f reference/dormrz.f reference/slaqps.f reference/zgtcon.f
-reference/cgbsvx.f reference/ctgexc.f reference/dormtr.f reference/slaqr0.f reference/zgtrfs.f
-reference/cgbsvxx.f reference/ctgsen.f reference/dpbcon.f reference/slaqr1.f reference/zgtsv.f
-reference/cgbtf2.f reference/ctgsja.f reference/dpbequ.f reference/slaqr2.f reference/zgtsvx.f
-reference/cgbtrf.f reference/ctgsna.f reference/dpbrfs.f reference/slaqr3.f reference/zgttrf.f
-reference/cgbtrs.f reference/ctgsy2.f reference/dpbstf.f reference/slaqr4.f reference/zgttrs.f
-reference/cgebak.f reference/ctgsyl.f reference/dpbsv.f reference/slaqr5.f reference/zgtts2.f
-reference/cgebal.f reference/ctpcon.f reference/dpbsvx.f reference/slaqsb.f reference/zhbevd.f
-reference/cgebd2.f reference/ctprfs.f reference/dpbtf2.f reference/slaqsp.f reference/zhbev.f
-reference/cgebrd.f reference/ctptri.f reference/dpbtrf.f reference/slaqsy.f reference/zhbevx.f
-reference/cgecon.f reference/ctptrs.f reference/dpbtrs.f reference/slaqtr.f reference/zhbgst.f
-reference/cgeequb.f reference/ctpttf.f reference/dpftrf.f reference/slar1v.f reference/zhbgvd.f
-reference/cgeequ.f reference/ctpttr.f reference/dpftri.f reference/slar2v.f reference/zhbgv.f
-reference/cgees.f reference/ctrcon.f reference/dpftrs.f reference/slarfb.f reference/zhbgvx.f
-reference/cgeesx.f reference/ctrevc.f reference/dpocon.f reference/slarf.f reference/zhbtrd.f
-reference/cgeev.f reference/ctrexc.f reference/dpoequb.f reference/slarfg.f reference/zhecon.f
-reference/cgeevx.f reference/ctrrfs.f reference/dpoequ.f reference/slarfp.f reference/zheequb.f
-reference/cgegs.f reference/ctrsen.f reference/dporfs.f reference/slarft.f reference/zheevd.f
-reference/cgegv.f reference/ctrsna.f reference/dporfsx.f reference/slarfx.f reference/zheev.f
-reference/cgehd2.f reference/ctrsyl.f reference/dposv.f reference/slargv.f reference/zheevr.f
-reference/cgehrd.f reference/ctrti2.f reference/dposvx.f reference/slarnv.f reference/zheevx.f
-reference/cgelq2.f reference/ctrtri.f reference/dposvxx.f reference/sla_rpvgrw.f reference/zhegs2.f
-reference/cgelqf.f reference/ctrtrs.f reference/dpotf2.f reference/slarra.f reference/zhegst.f
-reference/cgelsd.f reference/ctrttf.f
-reference/slarrb.f reference/zhegvd.f
-reference/cgels.f reference/ctrttp.f reference/dpotri.f reference/slarrc.f reference/zhegv.f
-reference/cgelss.f reference/ctzrqf.f reference/slarrd.f reference/zhegvx.f
-reference/cgelsx.f reference/ctzrzf.f reference/dppcon.f reference/slarre.f reference/zherfs.f
-reference/cgelsy.f reference/cung2l.f reference/dppequ.f reference/slarrf.f reference/zherfsx.f
-reference/cgeql2.f reference/cung2r.f reference/dpprfs.f reference/slarrj.f reference/zhesv.f
-reference/cgeqlf.f reference/cungbr.f reference/dppsv.f reference/slarrk.f reference/zhesvx.f
-reference/cgeqp3.f reference/cunghr.f reference/dppsvx.f reference/slarrr.f reference/zhesvxx.f
-reference/cgeqpf.f reference/cungl2.f reference/dpptrf.f reference/slarrv.f reference/zhetd2.f
-reference/cgeqr2.f reference/cunglq.f reference/dpptri.f reference/slarscl2.f reference/zhetf2.f
-reference/cgeqrf.f reference/cungql.f reference/dpptrs.f reference/slartg.f reference/zhetrd.f
-reference/cgerfs.f reference/cungqr.f reference/dpstf2.f reference/slartv.f reference/zhetrf.f
-reference/cgerfsx.f reference/cungr2.f reference/dpstrf.f reference/slaruv.f reference/zhetri.f
-reference/cgerq2.f reference/cungrq.f reference/dptcon.f reference/slarzb.f reference/zhetrs.f
-reference/cgerqf.f reference/cungtr.f reference/dpteqr.f reference/slarz.f reference/zhfrk.f
-reference/cgesc2.f reference/cunm2l.f reference/dptrfs.f reference/slarzt.f reference/zhgeqz.f
-reference/cgesdd.f reference/cunm2r.f reference/dptsv.f reference/slas2.f reference/zhpcon.f
-reference/cgesvd.f reference/cunmbr.f reference/dptsvx.f reference/slascl2.f reference/zhpevd.f
-reference/cgesv.f reference/cunmhr.f reference/dpttrf.f reference/slascl.f reference/zhpev.f
-reference/cgesvx.f reference/cunml2.f reference/dpttrs.f reference/slasd0.f reference/zhpevx.f
-reference/cgesvxx.f reference/cunmlq.f reference/dptts2.f reference/slasd1.f reference/zhpgst.f
-reference/cgetc2.f reference/cunmql.f reference/drscl.f reference/slasd2.f reference/zhpgvd.f
-reference/cgetf2.f reference/cunmqr.f reference/dsbevd.f reference/slasd3.f reference/zhpgv.f
-reference/cunmr2.f reference/dsbev.f reference/slasd4.f reference/zhpgvx.f
-reference/cgetri.f reference/cunmr3.f reference/dsbevx.f reference/slasd5.f reference/zhprfs.f
- reference/cunmrq.f reference/dsbgst.f reference/slasd6.f reference/zhpsv.f
-reference/cggbak.f reference/cunmrz.f reference/dsbgvd.f reference/slasd7.f reference/zhpsvx.f
-reference/cggbal.f reference/cunmtr.f reference/dsbgv.f reference/slasd8.f reference/zhptrd.f
-reference/cgges.f reference/cupgtr.f reference/dsbgvx.f reference/slasda.f reference/zhptrf.f
-reference/cggesx.f reference/cupmtr.f reference/dsbtrd.f reference/slasdq.f reference/zhptri.f
-reference/cggev.f reference/dbdsdc.f reference/dsfrk.f reference/slasdt.f reference/zhptrs.f
-reference/cggevx.f reference/dbdsqr.f reference/dsgesv.f reference/slaset.f reference/zhsein.f
-reference/cggglm.f reference/ddisna.f reference/dspcon.f reference/slasq1.f reference/zhseqr.f
-reference/cgghrd.f reference/dgbbrd.f reference/dspevd.f reference/slasq2.f reference/zlabrd.f
-reference/cgglse.f reference/dgbcon.f reference/dspev.f reference/slasq3.f reference/zlacgv.f
-reference/cggqrf.f reference/dgbequb.f reference/dspevx.f reference/slasq4.f reference/zlacn2.f
-reference/cggrqf.f reference/dgbequ.f reference/dspgst.f reference/slasq5.f reference/zlacon.f
-reference/cggsvd.f reference/dgbrfs.f reference/dspgvd.f reference/slasq6.f reference/zlacp2.f
-reference/cggsvp.f reference/dgbrfsx.f reference/dspgv.f reference/slasr.f reference/zlacpy.f
-reference/cgtcon.f reference/dgbsv.f reference/dspgvx.f reference/slasrt.f reference/zlacrm.f
-reference/cgtrfs.f reference/dgbsvx.f reference/dsposv.f reference/slassq.f reference/zlacrt.f
-reference/cgtsv.f reference/dgbsvxx.f reference/dsprfs.f reference/slasv2.f reference/zladiv.f
-reference/cgtsvx.f reference/dgbtf2.f reference/dspsv.f reference/slaswp.f reference/zlaed0.f
-reference/cgttrf.f reference/dgbtrf.f reference/dspsvx.f reference/slasy2.f reference/zlaed7.f
-reference/cgttrs.f reference/dgbtrs.f reference/dsptrd.f reference/sla_syamv.f reference/zlaed8.f
-reference/cgtts2.f reference/dgebak.f reference/dsptrf.f reference/slasyf.f reference/zlaein.f
-reference/chbevd.f reference/dgebal.f reference/dsptri.f reference/sla_syrcond.f reference/zlaesy.f
-reference/chbev.f reference/dgebd2.f reference/dsptrs.f reference/sla_syrfsx_extended.f reference/zlaev2.f
-reference/chbevx.f reference/dgebrd.f reference/dstebz.f reference/sla_syrpvgrw.f reference/zlag2c.f
-reference/chbgst.f reference/dgecon.f reference/dstedc.f reference/slatbs.f reference/zla_gbamv.f
-reference/chbgvd.f reference/dgeequb.f reference/dstegr.f reference/slatdf.f reference/zla_gbrcond_c.f
-reference/chbgv.f reference/dgeequ.f reference/dstein.f reference/slatps.f reference/zla_gbrcond_x.f
-reference/chbgvx.f reference/dgees.f reference/dstemr.f reference/slatrd.f reference/zla_gbrfsx_extended.f
-reference/chbtrd.f reference/dgeesx.f reference/dsteqr.f reference/slatrs.f reference/zla_gbrpvgrw.f
-reference/checon.f reference/dgeev.f reference/dsterf.f reference/slatrz.f reference/zla_geamv.f
-reference/cheequb.f reference/dgeevx.f reference/dstevd.f reference/slatzm.f reference/zla_gercond_c.f
-reference/cheevd.f reference/dgegs.f reference/dstev.f reference/slauu2.f reference/zla_gercond_x.f
-reference/cheev.f reference/dgegv.f reference/dstevr.f reference/slauum.f reference/zla_gerfsx_extended.f
-reference/cheevr.f reference/dgehd2.f reference/dstevx.f reference/sla_wwaddw.f reference/zlags2.f
-reference/cheevx.f reference/dgehrd.f reference/dsycon.f reference/sopgtr.f reference/zlagtm.f
-reference/chegs2.f reference/dgejsv.f reference/dsyequb.f reference/sopmtr.f reference/zla_heamv.f
-reference/chegst.f reference/dgelq2.f reference/dsyevd.f reference/sorg2l.f reference/zlahef.f
-reference/chegvd.f reference/dgelqf.f reference/sorg2r.f reference/zla_hercond_c.f
-reference/chegv.f reference/dgelsd.f reference/dsyevr.f reference/sorgbr.f reference/zla_hercond_x.f
-reference/chegvx.f reference/dgels.f reference/dsyevx.f reference/sorghr.f reference/zla_herfsx_extended.f
-reference/cherfs.f reference/dgelss.f reference/dsygs2.f reference/sorgl2.f reference/zla_herpvgrw.f
-reference/cherfsx.f reference/dgelsx.f reference/dsygst.f reference/sorglq.f reference/zlahqr.f
-reference/chesv.f reference/dgelsy.f reference/dsygvd.f reference/sorgql.f reference/zlahr2.f
-reference/chesvx.f reference/dgeql2.f reference/dsygv.f reference/sorgqr.f reference/zlahrd.f
-reference/chesvxx.f reference/dgeqlf.f reference/dsygvx.f reference/sorgr2.f reference/zlaic1.f
-reference/chetd2.f reference/dgeqp3.f reference/dsyrfs.f reference/sorgrq.f reference/zla_lin_berr.f
-reference/chetf2.f reference/dgeqpf.f reference/dsyrfsx.f reference/sorgtr.f reference/zlals0.f
-reference/chetrd.f reference/dgeqr2.f reference/dsysv.f reference/sorm2l.f reference/zlalsa.f
-reference/chetrf.f reference/dgeqrf.f reference/dsysvx.f reference/sorm2r.f reference/zlalsd.f
-reference/chetri.f reference/dgerfs.f reference/dsysvxx.f reference/sormbr.f reference/zlangb.f
-reference/chetrs.f reference/dgerfsx.f reference/dsytd2.f reference/sormhr.f reference/zlange.f
-reference/chfrk.f reference/dgerq2.f reference/dsytf2.f reference/sorml2.f reference/zlangt.f
-reference/chgeqz.f reference/dgerqf.f reference/dsytrd.f reference/sormlq.f reference/zlanhb.f
-reference/chla_transtype.f reference/dgesc2.f reference/dsytrf.f reference/sormql.f reference/zlanhe.f
-reference/chpcon.f reference/dgesdd.f reference/dsytri.f reference/sormqr.f reference/zlanhf.f
-reference/chpevd.f reference/dgesvd.f reference/dsytrs.f reference/sormr2.f reference/zlanhp.f
-reference/chpev.f reference/dgesv.f reference/dtbcon.f reference/sormr3.f reference/zlanhs.f
-reference/chpevx.f reference/dgesvj.f reference/dtbrfs.f reference/sormrq.f reference/zlanht.f
-reference/chpgst.f reference/dgesvx.f reference/dtbtrs.f reference/sormrz.f reference/zlansb.f
-reference/chpgvd.f reference/dgesvxx.f reference/dtfsm.f reference/sormtr.f reference/zlansp.f
-reference/chpgv.f reference/dgetc2.f reference/dtftri.f reference/spbcon.f reference/zlansy.f
-reference/chpgvx.f reference/dgetf2.f reference/dtfttp.f reference/spbequ.f reference/zlantb.f
-reference/chprfs.f
-reference/dtfttr.f reference/spbrfs.f reference/zlantp.f
-reference/chpsv.f reference/dgetri.f reference/dtgevc.f reference/spbstf.f reference/zlantr.f
-reference/chpsvx.f reference/dtgex2.f reference/spbsv.f reference/zlapll.f
-reference/chptrd.f reference/dggbak.f reference/dtgexc.f reference/spbsvx.f reference/zlapmt.f
-reference/chptrf.f reference/dggbal.f reference/dtgsen.f reference/spbtf2.f reference/zla_porcond_c.f
-reference/chptri.f reference/dgges.f reference/dtgsja.f reference/spbtrf.f reference/zla_porcond_x.f
-reference/chptrs.f reference/dggesx.f reference/dtgsna.f reference/spbtrs.f reference/zla_porfsx_extended.f
-reference/chsein.f reference/dggev.f reference/dtgsy2.f reference/spftrf.f reference/zla_porpvgrw.f
-reference/chseqr.f reference/dggevx.f reference/dtgsyl.f reference/spftri.f reference/zlaqgb.f
-reference/clabrd.f reference/dggglm.f reference/dtpcon.f reference/spftrs.f reference/zlaqge.f
-reference/clacgv.f reference/dgghrd.f reference/dtprfs.f reference/spocon.f reference/zlaqhb.f
-reference/clacn2.f reference/dgglse.f reference/dtptri.f reference/spoequb.f reference/zlaqhe.f
-reference/clacon.f reference/dggqrf.f reference/dtptrs.f reference/spoequ.f reference/zlaqhp.f
-reference/clacp2.f reference/dggrqf.f reference/dtpttf.f reference/sporfs.f reference/zlaqp2.f
-reference/clacpy.f reference/dggsvd.f reference/dtpttr.f reference/sporfsx.f reference/zlaqps.f
-reference/clacrm.f reference/dggsvp.f reference/dtrcon.f reference/sposv.f reference/zlaqr0.f
-reference/clacrt.f reference/dgsvj0.f reference/dtrevc.f reference/sposvx.f reference/zlaqr1.f
-reference/cladiv.f reference/dgsvj1.f reference/dtrexc.f reference/sposvxx.f reference/zlaqr2.f
-reference/claed0.f reference/dgtcon.f reference/dtrrfs.f reference/spotf2.f reference/zlaqr3.f
-reference/claed7.f reference/dgtrfs.f reference/dtrsen.f
-reference/zlaqr4.f
-reference/claed8.f reference/dgtsv.f reference/dtrsna.f reference/spotri.f reference/zlaqr5.f
-reference/claein.f reference/dgtsvx.f reference/dtrsyl.f reference/zlaqsb.f
-reference/claesy.f reference/dgttrf.f reference/dtrti2.f reference/sppcon.f reference/zlaqsp.f
-reference/claev2.f reference/dgttrs.f reference/dtrtri.f reference/sppequ.f reference/zlaqsy.f
-reference/clag2z.f reference/dgtts2.f reference/dtrtrs.f reference/spprfs.f reference/zlar1v.f
-reference/cla_gbamv.f reference/dhgeqz.f reference/dtrttf.f reference/sppsv.f reference/zlar2v.f
-reference/cla_gbrcond_c.f reference/dhsein.f reference/dtrttp.f reference/sppsvx.f reference/zlarcm.f
-reference/cla_gbrcond_x.f reference/dhseqr.f reference/dtzrqf.f reference/spptrf.f reference/zlarfb.f
-reference/cla_gbrfsx_extended.f reference/disnan.f reference/dtzrzf.f reference/spptri.f reference/zlarf.f
-reference/cla_gbrpvgrw.f reference/dlabad.f reference/dzsum1.f reference/spptrs.f reference/zlarfg.f
-reference/cla_geamv.f reference/dlabrd.f reference/icmax1.f reference/spstf2.f reference/zlarfp.f
-reference/cla_gercond_c.f reference/dlacn2.f reference/ieeeck.f reference/spstrf.f reference/zlarft.f
-reference/cla_gercond_x.f reference/dlacon.f reference/ilaclc.f reference/sptcon.f reference/zlarfx.f
-reference/cla_gerfsx_extended.f reference/dlacpy.f reference/ilaclr.f reference/spteqr.f reference/zlargv.f
-reference/clags2.f reference/dladiv.f reference/iladiag.f reference/sptrfs.f reference/zlarnv.f
-reference/clagtm.f reference/dlae2.f reference/iladlc.f reference/sptsv.f reference/zla_rpvgrw.f
-reference/cla_heamv.f reference/dlaebz.f reference/iladlr.f reference/sptsvx.f reference/zlarrv.f
-reference/clahef.f reference/dlaed0.f reference/ilaenv.f reference/spttrf.f reference/zlarscl2.f
-reference/cla_hercond_c.f reference/dlaed1.f reference/ilaprec.f reference/spttrs.f reference/zlartg.f
-reference/cla_hercond_x.f reference/dlaed2.f reference/ilaslc.f reference/sptts2.f reference/zlartv.f
-reference/cla_herfsx_extended.f reference/dlaed3.f reference/ilaslr.f reference/srscl.f reference/zlarzb.f
-reference/cla_herpvgrw.f reference/dlaed4.f reference/ilatrans.f reference/ssbevd.f reference/zlarz.f
-reference/clahqr.f reference/dlaed5.f reference/ilauplo.f reference/ssbev.f reference/zlarzt.f
-reference/clahr2.f reference/dlaed6.f reference/ilaver.f reference/ssbevx.f reference/zlascl2.f
-reference/clahrd.f reference/dlaed7.f reference/ilazlc.f reference/ssbgst.f reference/zlascl.f
-reference/claic1.f reference/dlaed8.f reference/ilazlr.f reference/ssbgvd.f reference/zlaset.f
-reference/cla_lin_berr.f reference/dlaed9.f reference/iparmq.f reference/ssbgv.f reference/zlasr.f
-reference/clals0.f reference/dlaeda.f reference/izmax1.f reference/ssbgvx.f reference/zlassq.f
-reference/clalsa.f reference/dlaein.f reference/lsamen.f reference/ssbtrd.f reference/zlaswp.f
-reference/clalsd.f reference/dlaev2.f reference/sbdsdc.f reference/ssfrk.f reference/zla_syamv.f
-reference/clangb.f reference/dlaexc.f reference/sbdsqr.f reference/sspcon.f reference/zlasyf.f
-reference/clange.f reference/dlag2.f reference/scsum1.f reference/sspevd.f reference/zla_syrcond_c.f
-reference/clangt.f reference/dlag2s.f reference/sdisna.f reference/sspev.f reference/zla_syrcond_x.f
-reference/clanhb.f reference/dla_gbamv.f reference/sgbbrd.f reference/sspevx.f reference/zla_syrfsx_extended.f
-reference/clanhe.f reference/dla_gbrcond.f reference/sgbcon.f reference/sspgst.f reference/zla_syrpvgrw.f
-reference/clanhf.f reference/dla_gbrfsx_extended.f reference/sgbequb.f reference/sspgvd.f reference/zlat2c.f
-reference/clanhp.f reference/dla_gbrpvgrw.f reference/sgbequ.f reference/sspgv.f reference/zlatbs.f
-reference/clanhs.f reference/dla_geamv.f reference/sgbrfs.f reference/sspgvx.f reference/zlatdf.f
-reference/clanht.f reference/dla_gercond.f reference/sgbrfsx.f reference/ssprfs.f reference/zlatps.f
-reference/clansb.f reference/dla_gerfsx_extended.f reference/sgbsv.f reference/sspsv.f reference/zlatrd.f
-reference/clansp.f reference/dlags2.f reference/sgbsvx.f reference/sspsvx.f reference/zlatrs.f
-reference/clansy.f reference/dlagtf.f reference/sgbsvxx.f reference/ssptrd.f reference/zlatrz.f
-reference/clantb.f reference/dlagtm.f reference/sgbtf2.f reference/ssptrf.f reference/zlatzm.f
-reference/clantp.f reference/dlagts.f reference/sgbtrf.f reference/ssptri.f reference/zlauu2.f
-reference/clantr.f reference/dlagv2.f reference/sgbtrs.f reference/ssptrs.f reference/zlauum.f
-reference/clapll.f reference/dlahqr.f reference/sgebak.f reference/sstebz.f reference/zla_wwaddw.f
-reference/clapmt.f reference/dlahr2.f reference/sgebal.f reference/sstedc.f reference/zpbcon.f
-reference/cla_porcond_c.f reference/dlahrd.f reference/sgebd2.f reference/sstegr.f reference/zpbequ.f
-reference/cla_porcond_x.f reference/dlaic1.f reference/sgebrd.f reference/sstein.f reference/zpbrfs.f
-reference/cla_porfsx_extended.f reference/dlaisnan.f reference/sgecon.f reference/sstemr.f reference/zpbstf.f
-reference/cla_porpvgrw.f reference/dla_lin_berr.f reference/sgeequb.f reference/ssteqr.f reference/zpbsv.f
-reference/claqgb.f reference/dlaln2.f reference/sgeequ.f reference/ssterf.f reference/zpbsvx.f
-reference/claqge.f reference/dlals0.f reference/sgees.f reference/sstevd.f reference/zpbtf2.f
-reference/claqhb.f reference/dlalsa.f reference/sgeesx.f reference/sstev.f reference/zpbtrf.f
-reference/claqhe.f reference/dlalsd.f reference/sgeev.f reference/sstevr.f reference/zpbtrs.f
-reference/claqhp.f reference/dlamrg.f reference/sgeevx.f reference/sstevx.f reference/zpftrf.f
-reference/claqp2.f reference/dlaneg.f reference/sgegs.f reference/ssycon.f reference/zpftri.f
-reference/claqps.f reference/dlangb.f reference/sgegv.f reference/ssyequb.f reference/zpftrs.f
-reference/claqr0.f reference/dlange.f reference/sgehd2.f reference/ssyevd.f reference/zpocon.f
-reference/claqr1.f reference/dlangt.f reference/sgehrd.f reference/zpoequb.f
-reference/claqr2.f reference/dlanhs.f reference/sgejsv.f reference/ssyevr.f reference/zpoequ.f
-reference/claqr3.f reference/dlansb.f reference/sgelq2.f reference/ssyevx.f reference/zporfs.f
-reference/claqr4.f reference/dlansf.f reference/sgelqf.f reference/ssygs2.f reference/zporfsx.f
-reference/claqr5.f reference/dlansp.f reference/sgelsd.f reference/ssygst.f reference/zposv.f
-reference/claqsb.f reference/dlanst.f reference/sgels.f reference/ssygvd.f reference/zposvx.f
-reference/claqsp.f reference/dlansy.f reference/sgelss.f reference/ssygv.f reference/zposvxx.f
-reference/claqsy.f reference/dlantb.f reference/sgelsx.f reference/ssygvx.f reference/zpotf2.f
-reference/clar1v.f reference/dlantp.f reference/sgelsy.f reference/ssyrfs.f
-reference/clar2v.f reference/dlantr.f reference/sgeql2.f reference/ssyrfsx.f reference/zpotri.f
-reference/clarcm.f reference/dlanv2.f reference/sgeqlf.f reference/ssysv.f
-reference/clarfb.f reference/dlapll.f reference/sgeqp3.f reference/ssysvx.f reference/zppcon.f
-reference/clarf.f reference/dlapmt.f reference/sgeqpf.f reference/ssysvxx.f reference/zppequ.f
-reference/clarfg.f reference/dla_porcond.f reference/sgeqr2.f reference/ssytd2.f reference/zpprfs.f
-reference/clarfp.f reference/dla_porfsx_extended.f reference/sgeqrf.f reference/ssytf2.f reference/zppsv.f
-reference/clarft.f reference/dla_porpvgrw.f reference/sgerfs.f reference/ssytrd.f reference/zppsvx.f
-reference/clarfx.f reference/dlapy2.f reference/sgerfsx.f reference/ssytrf.f reference/zpptrf.f
-reference/clargv.f reference/dlapy3.f reference/sgerq2.f reference/ssytri.f reference/zpptri.f
-reference/clarnv.f reference/dlaqgb.f reference/sgerqf.f reference/ssytrs.f reference/zpptrs.f
-reference/cla_rpvgrw.f reference/dlaqge.f reference/sgesc2.f reference/stbcon.f reference/zpstf2.f
-reference/clarrv.f reference/dlaqp2.f reference/sgesdd.f reference/stbrfs.f reference/zpstrf.f
-reference/clarscl2.f reference/dlaqps.f reference/sgesvd.f reference/stbtrs.f reference/zptcon.f
-reference/clartg.f reference/dlaqr0.f reference/sgesv.f reference/stfsm.f reference/zpteqr.f
-reference/clartv.f reference/dlaqr1.f reference/sgesvj.f reference/stftri.f reference/zptrfs.f
-reference/clarzb.f reference/dlaqr2.f reference/sgesvx.f reference/stfttp.f reference/zptsv.f
-reference/clarz.f reference/dlaqr3.f reference/sgesvxx.f reference/stfttr.f reference/zptsvx.f
-reference/clarzt.f reference/dlaqr4.f reference/sgetc2.f reference/stgevc.f reference/zpttrf.f
-reference/clascl2.f reference/dlaqr5.f reference/sgetf2.f reference/stgex2.f reference/zpttrs.f
-reference/clascl.f reference/dlaqsb.f
-reference/stgexc.f reference/zptts2.f
-reference/claset.f reference/dlaqsp.f reference/sgetri.f reference/stgsen.f reference/zrot.f
-reference/clasr.f reference/dlaqsy.f reference/stgsja.f reference/zspcon.f
-reference/classq.f reference/dlaqtr.f reference/sggbak.f reference/stgsna.f reference/zspmv.f
-reference/claswp.f reference/dlar1v.f reference/sggbal.f reference/stgsy2.f reference/zspr.f
-reference/cla_syamv.f reference/dlar2v.f reference/sgges.f reference/stgsyl.f reference/zsprfs.f
-reference/clasyf.f reference/dlarfb.f reference/sggesx.f reference/stpcon.f reference/zspsv.f
-reference/cla_syrcond_c.f reference/dlarf.f reference/sggev.f reference/stprfs.f reference/zspsvx.f
-reference/cla_syrcond_x.f reference/dlarfg.f reference/sggevx.f reference/stptri.f reference/zsptrf.f
-reference/cla_syrfsx_extended.f reference/dlarfp.f reference/sggglm.f reference/stptrs.f reference/zsptri.f
-reference/cla_syrpvgrw.f reference/dlarft.f reference/sgghrd.f reference/stpttf.f reference/zsptrs.f
-reference/clatbs.f reference/dlarfx.f reference/sgglse.f reference/stpttr.f reference/zstedc.f
-reference/clatdf.f reference/dlargv.f reference/sggqrf.f reference/strcon.f reference/zstegr.f
-reference/clatps.f reference/dlarnv.f reference/sggrqf.f reference/strevc.f reference/zstein.f
-reference/clatrd.f reference/dla_rpvgrw.f reference/sggsvd.f reference/strexc.f reference/zstemr.f
-reference/clatrs.f reference/dlarra.f reference/sggsvp.f reference/strrfs.f reference/zsteqr.f
-reference/clatrz.f reference/dlarrb.f reference/sgsvj0.f reference/strsen.f reference/zsycon.f
-reference/clatzm.f reference/dlarrc.f reference/sgsvj1.f reference/strsna.f reference/zsyequb.f
-reference/clauu2.f reference/dlarrd.f reference/sgtcon.f reference/strsyl.f reference/zsymv.f
-reference/clauum.f reference/dlarre.f reference/sgtrfs.f reference/strti2.f reference/zsyr.f
-reference/cla_wwaddw.f reference/dlarrf.f reference/sgtsv.f reference/strtri.f reference/zsyrfs.f
-reference/cpbcon.f reference/dlarrj.f reference/sgtsvx.f reference/strtrs.f reference/zsyrfsx.f
-reference/cpbequ.f reference/dlarrk.f reference/sgttrf.f reference/strttf.f reference/zsysv.f
-reference/cpbrfs.f reference/dlarrr.f reference/sgttrs.f reference/strttp.f reference/zsysvx.f
-reference/cpbstf.f reference/dlarrv.f reference/sgtts2.f reference/stzrqf.f reference/zsysvxx.f
-reference/cpbsv.f reference/dlarscl2.f reference/shgeqz.f reference/stzrzf.f reference/zsytf2.f
-reference/cpbsvx.f reference/dlartg.f reference/shsein.f reference/xerbla_array.f reference/zsytrf.f
-reference/cpbtf2.f reference/dlartv.f reference/shseqr.f reference/xerbla.f reference/zsytri.f
-reference/cpbtrf.f reference/dlaruv.f reference/sisnan.f reference/zbdsqr.f reference/zsytrs.f
-reference/cpbtrs.f reference/dlarzb.f reference/slabad.f reference/zcgesv.f reference/ztbcon.f
-reference/cpftrf.f reference/dlarz.f reference/slabrd.f reference/zcposv.f reference/ztbrfs.f
-reference/cpftri.f reference/dlarzt.f reference/slacn2.f reference/zdrscl.f reference/ztbtrs.f
-reference/cpftrs.f reference/dlas2.f reference/slacon.f reference/zgbbrd.f reference/ztfsm.f
-reference/cpocon.f reference/dlascl2.f reference/slacpy.f reference/zgbcon.f reference/ztftri.f
-reference/cpoequb.f reference/dlascl.f reference/sladiv.f reference/zgbequb.f reference/ztfttp.f
-reference/cpoequ.f reference/dlasd0.f reference/slae2.f reference/zgbequ.f reference/ztfttr.f
-reference/cporfs.f reference/dlasd1.f reference/slaebz.f reference/zgbrfs.f reference/ztgevc.f
-reference/cporfsx.f reference/dlasd2.f reference/slaed0.f reference/zgbrfsx.f reference/ztgex2.f
-reference/cposv.f reference/dlasd3.f reference/slaed1.f reference/zgbsv.f reference/ztgexc.f
-reference/cposvx.f reference/dlasd4.f reference/slaed2.f reference/zgbsvx.f reference/ztgsen.f
-reference/cposvxx.f reference/dlasd5.f reference/slaed3.f reference/zgbsvxx.f reference/ztgsja.f
-reference/cpotf2.f reference/dlasd6.f reference/slaed4.f reference/zgbtf2.f reference/ztgsna.f
-reference/dlasd7.f reference/slaed5.f reference/zgbtrf.f reference/ztgsy2.f
-reference/cpotri.f reference/dlasd8.f reference/slaed6.f reference/zgbtrs.f reference/ztgsyl.f
- reference/dlasda.f reference/slaed7.f reference/zgebak.f reference/ztpcon.f
-reference/cppcon.f reference/dlasdq.f reference/slaed8.f reference/zgebal.f reference/ztprfs.f
-reference/cppequ.f reference/dlasdt.f reference/slaed9.f reference/zgebd2.f reference/ztptri.f
-reference/cpprfs.f reference/dlaset.f reference/slaeda.f reference/zgebrd.f reference/ztptrs.f
-reference/cppsv.f reference/dlasq1.f reference/slaein.f reference/zgecon.f reference/ztpttf.f
-reference/cppsvx.f reference/dlasq2.f reference/slaev2.f reference/zgeequb.f reference/ztpttr.f
-reference/cpptrf.f reference/dlasq3.f reference/slaexc.f reference/zgeequ.f reference/ztrcon.f
-reference/cpptri.f reference/dlasq4.f reference/slag2d.f reference/zgees.f reference/ztrevc.f
-reference/cpptrs.f reference/dlasq5.f reference/slag2.f reference/zgeesx.f reference/ztrexc.f
-reference/cpstf2.f reference/dlasq6.f reference/sla_gbamv.f reference/zgeev.f reference/ztrrfs.f
-reference/cpstrf.f reference/dlasr.f reference/sla_gbrcond.f reference/zgeevx.f reference/ztrsen.f
-reference/cptcon.f reference/dlasrt.f reference/sla_gbrfsx_extended.f reference/zgegs.f reference/ztrsna.f
-reference/cpteqr.f reference/dlassq.f reference/sla_gbrpvgrw.f reference/zgegv.f reference/ztrsyl.f
-reference/cptrfs.f reference/dlasv2.f reference/sla_geamv.f reference/zgehd2.f reference/ztrti2.f
-reference/cptsv.f reference/dlaswp.f reference/sla_gercond.f reference/zgehrd.f reference/ztrtri.f
-reference/cptsvx.f reference/dlasy2.f reference/sla_gerfsx_extended.f reference/zgelq2.f reference/ztrtrs.f
-reference/cpttrf.f reference/dla_syamv.f reference/slags2.f reference/zgelqf.f reference/ztrttf.f
-reference/cpttrs.f reference/dlasyf.f reference/slagtf.f reference/zgelsd.f reference/ztrttp.f
-reference/cptts2.f reference/dla_syrcond.f reference/slagtm.f reference/zgels.f reference/ztzrqf.f
-reference/crot.f reference/dla_syrfsx_extended.f reference/slagts.f reference/zgelss.f reference/ztzrzf.f
-reference/cspcon.f reference/dla_syrpvgrw.f reference/slagv2.f reference/zgelsx.f reference/zung2l.f
-reference/cspmv.f reference/dlat2s.f reference/slahqr.f reference/zgelsy.f reference/zung2r.f
-reference/cspr.f reference/dlatbs.f reference/slahr2.f reference/zgeql2.f reference/zungbr.f
-reference/csprfs.f reference/dlatdf.f reference/slahrd.f reference/zgeqlf.f reference/zunghr.f
-reference/cspsv.f reference/dlatps.f reference/slaic1.f reference/zgeqp3.f reference/zungl2.f
-reference/cspsvx.f reference/dlatrd.f reference/slaisnan.f reference/zgeqpf.f reference/zunglq.f
-reference/csptrf.f reference/dlatrs.f reference/sla_lin_berr.f reference/zgeqr2.f reference/zungql.f
-reference/csptri.f reference/dlatrz.f reference/slaln2.f reference/zgeqrf.f reference/zungqr.f
-reference/csptrs.f reference/dlatzm.f reference/slals0.f reference/zgerfs.f reference/zungr2.f
-reference/csrscl.f reference/dlauu2.f reference/slalsa.f reference/zgerfsx.f reference/zungrq.f
-reference/cstedc.f reference/dlauum.f reference/slalsd.f reference/zgerq2.f reference/zungtr.f
-reference/cstegr.f reference/dla_wwaddw.f reference/slamrg.f reference/zgerqf.f reference/zunm2l.f
-reference/cstein.f reference/dopgtr.f reference/slaneg.f reference/zgesc2.f reference/zunm2r.f
-reference/cstemr.f reference/dopmtr.f reference/slangb.f reference/zgesdd.f reference/zunmbr.f
-reference/csteqr.f reference/dorg2l.f reference/slange.f reference/zgesvd.f reference/zunmhr.f
-reference/csycon.f reference/dorg2r.f reference/slangt.f reference/zgesv.f reference/zunml2.f
-reference/csyequb.f reference/dorgbr.f reference/slanhs.f reference/zgesvx.f reference/zunmlq.f
-reference/csymv.f reference/dorghr.f reference/slansb.f reference/zgesvxx.f reference/zunmql.f
-reference/csyr.f reference/dorgl2.f reference/slansf.f reference/zgetc2.f reference/zunmqr.f
-reference/csyrfs.f reference/dorglq.f reference/slansp.f reference/zgetf2.f reference/zunmr2.f
-reference/csyrfsx.f reference/dorgql.f reference/slanst.f
-reference/zunmr3.f
-reference/csysv.f reference/dorgqr.f reference/slansy.f reference/zgetri.f reference/zunmrq.f
-reference/csysvx.f reference/dorgr2.f reference/slantb.f reference/zunmrz.f
-reference/csysvxx.f reference/dorgrq.f reference/slantp.f reference/zggbak.f reference/zunmtr.f
-reference/csytf2.f reference/dorgtr.f reference/slantr.f reference/zggbal.f reference/zupgtr.f
-reference/csytrf.f reference/dorm2l.f reference/slanv2.f reference/zgges.f reference/zupmtr.f
-reference/csytri.f reference/dorm2r.f reference/slapll.f reference/zggesx.f
-reference/csytrs.f reference/dormbr.f reference/slapmt.f reference/zggev.f
-reference/ctbcon.f reference/dormhr.f reference/sla_porcond.f reference/zggevx.f
-)
-endif()
+option(EIGEN_ENABLE_LAPACK_TESTS OFF "Enbale the Lapack unit tests")
+
+if(EIGEN_ENABLE_LAPACK_TESTS)
+
+ get_filename_component(eigen_full_path_to_reference_lapack "./reference/" ABSOLUTE)
+ if(NOT EXISTS ${eigen_full_path_to_reference_lapack})
+ # Download lapack and install sources and testing at the right place
+ message(STATUS "Download lapack_addons_3.4.1.tgz...")
+
+ file(DOWNLOAD "http://downloads.tuxfamily.org/eigen/lapack_addons_3.4.1.tgz"
+ "${CMAKE_CURRENT_SOURCE_DIR}/lapack_addons_3.4.1.tgz"
+ INACTIVITY_TIMEOUT 15
+ TIMEOUT 240
+ STATUS download_status
+ EXPECTED_MD5 5758ce55afcf79da98de8b9de1615ad5
+ SHOW_PROGRESS)
+
+ message(STATUS ${download_status})
+ list(GET download_status 0 download_status_num)
+ set(download_status_num 0)
+ if(download_status_num EQUAL 0)
+ message(STATUS "Setup lapack reference and lapack unit tests")
+ execute_process(COMMAND tar xzf "lapack_addons_3.4.1.tgz" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+ else()
+ message(STATUS "Download of lapack_addons_3.4.1.tgz failed, LAPACK unit tests wont be enabled")
+ set(EIGEN_ENABLE_LAPACK_TESTS false)
+ endif()
+
+ endif()
+
+ get_filename_component(eigen_full_path_to_reference_lapack "./reference/" ABSOLUTE)
+ if(EXISTS ${eigen_full_path_to_reference_lapack})
+ set(EigenLapack_funcfilenames
+ ssyev.f dsyev.f csyev.f zsyev.f
+ spotrf.f dpotrf.f cpotrf.f zpotrf.f
+ spotrs.f dpotrs.f cpotrs.f zpotrs.f
+ sgetrf.f dgetrf.f cgetrf.f zgetrf.f
+ sgetrs.f dgetrs.f cgetrs.f zgetrs.f)
+
+ FILE(GLOB ReferenceLapack_SRCS0 RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "reference/*.f")
+ foreach(filename1 IN LISTS ReferenceLapack_SRCS0)
+ string(REPLACE "reference/" "" filename ${filename1})
+ list(FIND EigenLapack_SRCS ${filename} id1)
+ list(FIND EigenLapack_funcfilenames ${filename} id2)
+ if((id1 EQUAL -1) AND (id2 EQUAL -1))
+ set(ReferenceLapack_SRCS ${ReferenceLapack_SRCS} reference/${filename})
+ endif()
+ endforeach()
+ endif()
+
+
+endif(EIGEN_ENABLE_LAPACK_TESTS)
endif(EIGEN_Fortran_COMPILER_WORKS)
-add_library(eigen_lapack_static ${EigenLapack_SRCS})
+add_library(eigen_lapack_static ${EigenLapack_SRCS} ${ReferenceLapack_SRCS})
add_library(eigen_lapack SHARED ${EigenLapack_SRCS})
+target_link_libraries(eigen_lapack eigen_blas)
+
if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)
target_link_libraries(eigen_lapack_static ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO})
target_link_libraries(eigen_lapack ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO})
@@ -376,5 +104,343 @@ install(TARGETS eigen_lapack eigen_lapack_static
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
-# add_subdirectory(testing)
+
+
+get_filename_component(eigen_full_path_to_testing_lapack "./testing/" ABSOLUTE)
+if(EXISTS ${eigen_full_path_to_testing_lapack})
+
+ # The following comes from lapack/TESTING/CMakeLists.txt
+ # Get Python
+ find_package(PythonInterp)
+ message(STATUS "Looking for Python found - ${PYTHONINTERP_FOUND}")
+ if (PYTHONINTERP_FOUND)
+ message(STATUS "Using Python version ${PYTHON_VERSION_STRING}")
+ endif()
+
+ set(LAPACK_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+ set(LAPACK_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
+ set(BUILD_SINGLE true)
+ set(BUILD_DOUBLE true)
+ set(BUILD_COMPLEX true)
+ set(BUILD_COMPLEX16E true)
+
+ if(MSVC_VERSION)
+# string(REPLACE "/STACK:10000000" "/STACK:900000000000000000"
+# CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
+ string(REGEX REPLACE "(.*)/STACK:(.*) (.*)" "\\1/STACK:900000000000000000 \\3"
+ CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
+ endif()
+ add_subdirectory(testing/MATGEN)
+ add_subdirectory(testing/LIN)
+ add_subdirectory(testing/EIG)
+ macro(add_lapack_test output input target)
+ set(TEST_INPUT "${LAPACK_SOURCE_DIR}/testing/${input}")
+ set(TEST_OUTPUT "${LAPACK_BINARY_DIR}/testing/${output}")
+ get_target_property(TEST_LOC ${target} LOCATION)
+ string(REPLACE "." "_" input_name ${input})
+ set(testName "${target}_${input_name}")
+ if(EXISTS "${TEST_INPUT}")
+ add_test(LAPACK-${testName} "${CMAKE_COMMAND}"
+ -DTEST=${TEST_LOC}
+ -DINPUT=${TEST_INPUT}
+ -DOUTPUT=${TEST_OUTPUT}
+ -DINTDIR=${CMAKE_CFG_INTDIR}
+ -P "${LAPACK_SOURCE_DIR}/testing/runtest.cmake")
+ endif()
+ endmacro(add_lapack_test)
+
+ if (BUILD_SINGLE)
+ add_lapack_test(stest.out stest.in xlintsts)
+ #
+ # ======== SINGLE RFP LIN TESTS ========================
+ add_lapack_test(stest_rfp.out stest_rfp.in xlintstrfs)
+ #
+ #
+ # ======== SINGLE EIG TESTS ===========================
+ #
+
+ add_lapack_test(snep.out nep.in xeigtsts)
+
+
+ add_lapack_test(ssep.out sep.in xeigtsts)
+
+
+ add_lapack_test(ssvd.out svd.in xeigtsts)
+
+
+ add_lapack_test(sec.out sec.in xeigtsts)
+
+
+ add_lapack_test(sed.out sed.in xeigtsts)
+
+
+ add_lapack_test(sgg.out sgg.in xeigtsts)
+
+
+ add_lapack_test(sgd.out sgd.in xeigtsts)
+
+
+ add_lapack_test(ssb.out ssb.in xeigtsts)
+
+
+ add_lapack_test(ssg.out ssg.in xeigtsts)
+
+
+ add_lapack_test(sbal.out sbal.in xeigtsts)
+
+
+ add_lapack_test(sbak.out sbak.in xeigtsts)
+
+
+ add_lapack_test(sgbal.out sgbal.in xeigtsts)
+
+
+ add_lapack_test(sgbak.out sgbak.in xeigtsts)
+
+
+ add_lapack_test(sbb.out sbb.in xeigtsts)
+
+
+ add_lapack_test(sglm.out glm.in xeigtsts)
+
+
+ add_lapack_test(sgqr.out gqr.in xeigtsts)
+
+
+ add_lapack_test(sgsv.out gsv.in xeigtsts)
+
+
+ add_lapack_test(scsd.out csd.in xeigtsts)
+
+
+ add_lapack_test(slse.out lse.in xeigtsts)
+ endif()
+
+ if (BUILD_DOUBLE)
+ #
+ # ======== DOUBLE LIN TESTS ===========================
+ add_lapack_test(dtest.out dtest.in xlintstd)
+ #
+ # ======== DOUBLE RFP LIN TESTS ========================
+ add_lapack_test(dtest_rfp.out dtest_rfp.in xlintstrfd)
+ #
+ # ======== DOUBLE EIG TESTS ===========================
+
+ add_lapack_test(dnep.out nep.in xeigtstd)
+
+
+ add_lapack_test(dsep.out sep.in xeigtstd)
+
+
+ add_lapack_test(dsvd.out svd.in xeigtstd)
+
+
+ add_lapack_test(dec.out dec.in xeigtstd)
+
+
+ add_lapack_test(ded.out ded.in xeigtstd)
+
+
+ add_lapack_test(dgg.out dgg.in xeigtstd)
+
+
+ add_lapack_test(dgd.out dgd.in xeigtstd)
+
+
+ add_lapack_test(dsb.out dsb.in xeigtstd)
+
+
+ add_lapack_test(dsg.out dsg.in xeigtstd)
+
+
+ add_lapack_test(dbal.out dbal.in xeigtstd)
+
+
+ add_lapack_test(dbak.out dbak.in xeigtstd)
+
+
+ add_lapack_test(dgbal.out dgbal.in xeigtstd)
+
+
+ add_lapack_test(dgbak.out dgbak.in xeigtstd)
+
+
+ add_lapack_test(dbb.out dbb.in xeigtstd)
+
+
+ add_lapack_test(dglm.out glm.in xeigtstd)
+
+
+ add_lapack_test(dgqr.out gqr.in xeigtstd)
+
+
+ add_lapack_test(dgsv.out gsv.in xeigtstd)
+
+
+ add_lapack_test(dcsd.out csd.in xeigtstd)
+
+
+ add_lapack_test(dlse.out lse.in xeigtstd)
+ endif()
+
+ if (BUILD_COMPLEX)
+ add_lapack_test(ctest.out ctest.in xlintstc)
+ #
+ # ======== COMPLEX RFP LIN TESTS ========================
+ add_lapack_test(ctest_rfp.out ctest_rfp.in xlintstrfc)
+ #
+ # ======== COMPLEX EIG TESTS ===========================
+
+ add_lapack_test(cnep.out nep.in xeigtstc)
+
+
+ add_lapack_test(csep.out sep.in xeigtstc)
+
+
+ add_lapack_test(csvd.out svd.in xeigtstc)
+
+
+ add_lapack_test(cec.out cec.in xeigtstc)
+
+
+ add_lapack_test(ced.out ced.in xeigtstc)
+
+
+ add_lapack_test(cgg.out cgg.in xeigtstc)
+
+
+ add_lapack_test(cgd.out cgd.in xeigtstc)
+
+
+ add_lapack_test(csb.out csb.in xeigtstc)
+
+
+ add_lapack_test(csg.out csg.in xeigtstc)
+
+
+ add_lapack_test(cbal.out cbal.in xeigtstc)
+
+
+ add_lapack_test(cbak.out cbak.in xeigtstc)
+
+
+ add_lapack_test(cgbal.out cgbal.in xeigtstc)
+
+
+ add_lapack_test(cgbak.out cgbak.in xeigtstc)
+
+
+ add_lapack_test(cbb.out cbb.in xeigtstc)
+
+
+ add_lapack_test(cglm.out glm.in xeigtstc)
+
+
+ add_lapack_test(cgqr.out gqr.in xeigtstc)
+
+
+ add_lapack_test(cgsv.out gsv.in xeigtstc)
+
+
+ add_lapack_test(ccsd.out csd.in xeigtstc)
+
+
+ add_lapack_test(clse.out lse.in xeigtstc)
+ endif()
+
+ if (BUILD_COMPLEX16)
+ #
+ # ======== COMPLEX16 LIN TESTS ========================
+ add_lapack_test(ztest.out ztest.in xlintstz)
+ #
+ # ======== COMPLEX16 RFP LIN TESTS ========================
+ add_lapack_test(ztest_rfp.out ztest_rfp.in xlintstrfz)
+ #
+ # ======== COMPLEX16 EIG TESTS ===========================
+
+ add_lapack_test(znep.out nep.in xeigtstz)
+
+
+ add_lapack_test(zsep.out sep.in xeigtstz)
+
+
+ add_lapack_test(zsvd.out svd.in xeigtstz)
+
+
+ add_lapack_test(zec.out zec.in xeigtstz)
+
+
+ add_lapack_test(zed.out zed.in xeigtstz)
+
+
+ add_lapack_test(zgg.out zgg.in xeigtstz)
+
+
+ add_lapack_test(zgd.out zgd.in xeigtstz)
+
+
+ add_lapack_test(zsb.out zsb.in xeigtstz)
+
+
+ add_lapack_test(zsg.out zsg.in xeigtstz)
+
+
+ add_lapack_test(zbal.out zbal.in xeigtstz)
+
+
+ add_lapack_test(zbak.out zbak.in xeigtstz)
+
+
+ add_lapack_test(zgbal.out zgbal.in xeigtstz)
+
+
+ add_lapack_test(zgbak.out zgbak.in xeigtstz)
+
+
+ add_lapack_test(zbb.out zbb.in xeigtstz)
+
+
+ add_lapack_test(zglm.out glm.in xeigtstz)
+
+
+ add_lapack_test(zgqr.out gqr.in xeigtstz)
+
+
+ add_lapack_test(zgsv.out gsv.in xeigtstz)
+
+
+ add_lapack_test(zcsd.out csd.in xeigtstz)
+
+
+ add_lapack_test(zlse.out lse.in xeigtstz)
+ endif()
+
+
+ if (BUILD_SIMPLE)
+ if (BUILD_DOUBLE)
+ #
+ # ======== SINGLE-DOUBLE PROTO LIN TESTS ==============
+ add_lapack_test(dstest.out dstest.in xlintstds)
+ endif()
+ endif()
+
+
+ if (BUILD_COMPLEX)
+ if (BUILD_COMPLEX16)
+ #
+ # ======== COMPLEX-COMPLEX16 LIN TESTS ========================
+ add_lapack_test(zctest.out zctest.in xlintstzc)
+ endif()
+ endif()
+
+ # ==============================================================================
+
+ execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${LAPACK_SOURCE_DIR}/testing/lapack_testing.py ${LAPACK_BINARY_DIR})
+ add_test(
+ NAME LAPACK_Test_Summary
+ WORKING_DIRECTORY ${LAPACK_BINARY_DIR}
+ COMMAND ${PYTHON_EXECUTABLE} "lapack_testing.py"
+ )
+
+endif()
diff --git a/lapack/cholesky.cpp b/lapack/cholesky.cpp
index 604fa437a..ea3bc123b 100644
--- a/lapack/cholesky.cpp
+++ b/lapack/cholesky.cpp
@@ -26,8 +26,8 @@ EIGEN_LAPACK_FUNC(potrf,(char* uplo, int *n, RealScalar *pa, int *lda, int *info
Scalar* a = reinterpret_cast<Scalar*>(pa);
MatrixType A(a,*n,*n,*lda);
int ret;
- if(UPLO(*uplo)==UP) ret = internal::llt_inplace<Scalar, Upper>::blocked(A);
- else ret = internal::llt_inplace<Scalar, Lower>::blocked(A);
+ if(UPLO(*uplo)==UP) ret = int(internal::llt_inplace<Scalar, Upper>::blocked(A));
+ else ret = int(internal::llt_inplace<Scalar, Lower>::blocked(A));
if(ret>=0)
*info = ret+1;
diff --git a/lapack/clacgv.f b/lapack/clacgv.f
new file mode 100644
index 000000000..359eb07f3
--- /dev/null
+++ b/lapack/clacgv.f
@@ -0,0 +1,116 @@
+*> \brief \b CLACGV
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+*> \htmlonly
+*> Download CLACGV + dependencies
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/clacgv.f">
+*> [TGZ]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/clacgv.f">
+*> [ZIP]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/clacgv.f">
+*> [TXT]</a>
+*> \endhtmlonly
+*
+* Definition:
+* ===========
+*
+* SUBROUTINE CLACGV( N, X, INCX )
+*
+* .. Scalar Arguments ..
+* INTEGER INCX, N
+* ..
+* .. Array Arguments ..
+* COMPLEX X( * )
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> CLACGV conjugates a complex vector of length N.
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] N
+*> \verbatim
+*> N is INTEGER
+*> The length of the vector X. N >= 0.
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*> X is COMPLEX array, dimension
+*> (1+(N-1)*abs(INCX))
+*> On entry, the vector of length N to be conjugated.
+*> On exit, X is overwritten with conjg(X).
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*> INCX is INTEGER
+*> The spacing between successive elements of X.
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*> \ingroup complexOTHERauxiliary
+*
+* =====================================================================
+ SUBROUTINE CLACGV( N, X, INCX )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2011
+*
+* .. Scalar Arguments ..
+ INTEGER INCX, N
+* ..
+* .. Array Arguments ..
+ COMPLEX X( * )
+* ..
+*
+* =====================================================================
+*
+* .. Local Scalars ..
+ INTEGER I, IOFF
+* ..
+* .. Intrinsic Functions ..
+ INTRINSIC CONJG
+* ..
+* .. Executable Statements ..
+*
+ IF( INCX.EQ.1 ) THEN
+ DO 10 I = 1, N
+ X( I ) = CONJG( X( I ) )
+ 10 CONTINUE
+ ELSE
+ IOFF = 1
+ IF( INCX.LT.0 )
+ $ IOFF = 1 - ( N-1 )*INCX
+ DO 20 I = 1, N
+ X( IOFF ) = CONJG( X( IOFF ) )
+ IOFF = IOFF + INCX
+ 20 CONTINUE
+ END IF
+ RETURN
+*
+* End of CLACGV
+*
+ END
diff --git a/lapack/cladiv.f b/lapack/cladiv.f
new file mode 100644
index 000000000..2807ac5fc
--- /dev/null
+++ b/lapack/cladiv.f
@@ -0,0 +1,97 @@
+*> \brief \b CLADIV
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+*> \htmlonly
+*> Download CLADIV + dependencies
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cladiv.f">
+*> [TGZ]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cladiv.f">
+*> [ZIP]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cladiv.f">
+*> [TXT]</a>
+*> \endhtmlonly
+*
+* Definition:
+* ===========
+*
+* COMPLEX FUNCTION CLADIV( X, Y )
+*
+* .. Scalar Arguments ..
+* COMPLEX X, Y
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> CLADIV := X / Y, where X and Y are complex. The computation of X / Y
+*> will not overflow on an intermediary step unless the results
+*> overflows.
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] X
+*> \verbatim
+*> X is COMPLEX
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*> Y is COMPLEX
+*> The complex scalars X and Y.
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*> \ingroup complexOTHERauxiliary
+*
+* =====================================================================
+ COMPLEX FUNCTION CLADIV( X, Y )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2011
+*
+* .. Scalar Arguments ..
+ COMPLEX X, Y
+* ..
+*
+* =====================================================================
+*
+* .. Local Scalars ..
+ REAL ZI, ZR
+* ..
+* .. External Subroutines ..
+ EXTERNAL SLADIV
+* ..
+* .. Intrinsic Functions ..
+ INTRINSIC AIMAG, CMPLX, REAL
+* ..
+* .. Executable Statements ..
+*
+ CALL SLADIV( REAL( X ), AIMAG( X ), REAL( Y ), AIMAG( Y ), ZR,
+ $ ZI )
+ CLADIV = CMPLX( ZR, ZI )
+*
+ RETURN
+*
+* End of CLADIV
+*
+ END
diff --git a/lapack/dladiv.f b/lapack/dladiv.f
new file mode 100644
index 000000000..090a90654
--- /dev/null
+++ b/lapack/dladiv.f
@@ -0,0 +1,128 @@
+*> \brief \b DLADIV
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+*> \htmlonly
+*> Download DLADIV + dependencies
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dladiv.f">
+*> [TGZ]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dladiv.f">
+*> [ZIP]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dladiv.f">
+*> [TXT]</a>
+*> \endhtmlonly
+*
+* Definition:
+* ===========
+*
+* SUBROUTINE DLADIV( A, B, C, D, P, Q )
+*
+* .. Scalar Arguments ..
+* DOUBLE PRECISION A, B, C, D, P, Q
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> DLADIV performs complex division in real arithmetic
+*>
+*> a + i*b
+*> p + i*q = ---------
+*> c + i*d
+*>
+*> The algorithm is due to Robert L. Smith and can be found
+*> in D. Knuth, The art of Computer Programming, Vol.2, p.195
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] A
+*> \verbatim
+*> A is DOUBLE PRECISION
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*> B is DOUBLE PRECISION
+*> \endverbatim
+*>
+*> \param[in] C
+*> \verbatim
+*> C is DOUBLE PRECISION
+*> \endverbatim
+*>
+*> \param[in] D
+*> \verbatim
+*> D is DOUBLE PRECISION
+*> The scalars a, b, c, and d in the above expression.
+*> \endverbatim
+*>
+*> \param[out] P
+*> \verbatim
+*> P is DOUBLE PRECISION
+*> \endverbatim
+*>
+*> \param[out] Q
+*> \verbatim
+*> Q is DOUBLE PRECISION
+*> The scalars p and q in the above expression.
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*> \ingroup auxOTHERauxiliary
+*
+* =====================================================================
+ SUBROUTINE DLADIV( A, B, C, D, P, Q )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2011
+*
+* .. Scalar Arguments ..
+ DOUBLE PRECISION A, B, C, D, P, Q
+* ..
+*
+* =====================================================================
+*
+* .. Local Scalars ..
+ DOUBLE PRECISION E, F
+* ..
+* .. Intrinsic Functions ..
+ INTRINSIC ABS
+* ..
+* .. Executable Statements ..
+*
+ IF( ABS( D ).LT.ABS( C ) ) THEN
+ E = D / C
+ F = C + D*E
+ P = ( A+B*E ) / F
+ Q = ( B-A*E ) / F
+ ELSE
+ E = C / D
+ F = D + C*E
+ P = ( B+A*E ) / F
+ Q = ( -A+B*E ) / F
+ END IF
+*
+ RETURN
+*
+* End of DLADIV
+*
+ END
diff --git a/lapack/dlamch.f b/lapack/dlamch.f
new file mode 100644
index 000000000..eb307e5e1
--- /dev/null
+++ b/lapack/dlamch.f
@@ -0,0 +1,189 @@
+*> \brief \b DLAMCH
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+* Definition:
+* ===========
+*
+* DOUBLE PRECISION FUNCTION DLAMCH( CMACH )
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> DLAMCH determines double precision machine parameters.
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] CMACH
+*> \verbatim
+*> Specifies the value to be returned by DLAMCH:
+*> = 'E' or 'e', DLAMCH := eps
+*> = 'S' or 's , DLAMCH := sfmin
+*> = 'B' or 'b', DLAMCH := base
+*> = 'P' or 'p', DLAMCH := eps*base
+*> = 'N' or 'n', DLAMCH := t
+*> = 'R' or 'r', DLAMCH := rnd
+*> = 'M' or 'm', DLAMCH := emin
+*> = 'U' or 'u', DLAMCH := rmin
+*> = 'L' or 'l', DLAMCH := emax
+*> = 'O' or 'o', DLAMCH := rmax
+*> where
+*> eps = relative machine precision
+*> sfmin = safe minimum, such that 1/sfmin does not overflow
+*> base = base of the machine
+*> prec = eps*base
+*> t = number of (base) digits in the mantissa
+*> rnd = 1.0 when rounding occurs in addition, 0.0 otherwise
+*> emin = minimum exponent before (gradual) underflow
+*> rmin = underflow threshold - base**(emin-1)
+*> emax = largest exponent before overflow
+*> rmax = overflow threshold - (base**emax)*(1-eps)
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*> \ingroup auxOTHERauxiliary
+*
+* =====================================================================
+ DOUBLE PRECISION FUNCTION DLAMCH( CMACH )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2011
+*
+* .. Scalar Arguments ..
+ CHARACTER CMACH
+* ..
+*
+* =====================================================================
+*
+* .. Parameters ..
+ DOUBLE PRECISION ONE, ZERO
+ PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )
+* ..
+* .. Local Scalars ..
+ DOUBLE PRECISION RND, EPS, SFMIN, SMALL, RMACH
+* ..
+* .. External Functions ..
+ LOGICAL LSAME
+ EXTERNAL LSAME
+* ..
+* .. Intrinsic Functions ..
+ INTRINSIC DIGITS, EPSILON, HUGE, MAXEXPONENT,
+ $ MINEXPONENT, RADIX, TINY
+* ..
+* .. Executable Statements ..
+*
+*
+* Assume rounding, not chopping. Always.
+*
+ RND = ONE
+*
+ IF( ONE.EQ.RND ) THEN
+ EPS = EPSILON(ZERO) * 0.5
+ ELSE
+ EPS = EPSILON(ZERO)
+ END IF
+*
+ IF( LSAME( CMACH, 'E' ) ) THEN
+ RMACH = EPS
+ ELSE IF( LSAME( CMACH, 'S' ) ) THEN
+ SFMIN = TINY(ZERO)
+ SMALL = ONE / HUGE(ZERO)
+ IF( SMALL.GE.SFMIN ) THEN
+*
+* Use SMALL plus a bit, to avoid the possibility of rounding
+* causing overflow when computing 1/sfmin.
+*
+ SFMIN = SMALL*( ONE+EPS )
+ END IF
+ RMACH = SFMIN
+ ELSE IF( LSAME( CMACH, 'B' ) ) THEN
+ RMACH = RADIX(ZERO)
+ ELSE IF( LSAME( CMACH, 'P' ) ) THEN
+ RMACH = EPS * RADIX(ZERO)
+ ELSE IF( LSAME( CMACH, 'N' ) ) THEN
+ RMACH = DIGITS(ZERO)
+ ELSE IF( LSAME( CMACH, 'R' ) ) THEN
+ RMACH = RND
+ ELSE IF( LSAME( CMACH, 'M' ) ) THEN
+ RMACH = MINEXPONENT(ZERO)
+ ELSE IF( LSAME( CMACH, 'U' ) ) THEN
+ RMACH = tiny(zero)
+ ELSE IF( LSAME( CMACH, 'L' ) ) THEN
+ RMACH = MAXEXPONENT(ZERO)
+ ELSE IF( LSAME( CMACH, 'O' ) ) THEN
+ RMACH = HUGE(ZERO)
+ ELSE
+ RMACH = ZERO
+ END IF
+*
+ DLAMCH = RMACH
+ RETURN
+*
+* End of DLAMCH
+*
+ END
+************************************************************************
+*> \brief \b DLAMC3
+*> \details
+*> \b Purpose:
+*> \verbatim
+*> DLAMC3 is intended to force A and B to be stored prior to doing
+*> the addition of A and B , for use in situations where optimizers
+*> might hold one of these in a register.
+*> \endverbatim
+*> \author LAPACK is a software package provided by Univ. of Tennessee, Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..
+*> \date November 2011
+*> \ingroup auxOTHERauxiliary
+*>
+*> \param[in] A
+*> \verbatim
+*> A is a DOUBLE PRECISION
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*> B is a DOUBLE PRECISION
+*> The values A and B.
+*> \endverbatim
+*>
+ DOUBLE PRECISION FUNCTION DLAMC3( A, B )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+* November 2010
+*
+* .. Scalar Arguments ..
+ DOUBLE PRECISION A, B
+* ..
+* =====================================================================
+*
+* .. Executable Statements ..
+*
+ DLAMC3 = A + B
+*
+ RETURN
+*
+* End of DLAMC3
+*
+ END
+*
+************************************************************************
diff --git a/lapack/dlapy2.f b/lapack/dlapy2.f
new file mode 100644
index 000000000..e6a62bf4a
--- /dev/null
+++ b/lapack/dlapy2.f
@@ -0,0 +1,104 @@
+*> \brief \b DLAPY2
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+*> \htmlonly
+*> Download DLAPY2 + dependencies
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlapy2.f">
+*> [TGZ]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlapy2.f">
+*> [ZIP]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlapy2.f">
+*> [TXT]</a>
+*> \endhtmlonly
+*
+* Definition:
+* ===========
+*
+* DOUBLE PRECISION FUNCTION DLAPY2( X, Y )
+*
+* .. Scalar Arguments ..
+* DOUBLE PRECISION X, Y
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> DLAPY2 returns sqrt(x**2+y**2), taking care not to cause unnecessary
+*> overflow.
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] X
+*> \verbatim
+*> X is DOUBLE PRECISION
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*> Y is DOUBLE PRECISION
+*> X and Y specify the values x and y.
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*> \ingroup auxOTHERauxiliary
+*
+* =====================================================================
+ DOUBLE PRECISION FUNCTION DLAPY2( X, Y )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2011
+*
+* .. Scalar Arguments ..
+ DOUBLE PRECISION X, Y
+* ..
+*
+* =====================================================================
+*
+* .. Parameters ..
+ DOUBLE PRECISION ZERO
+ PARAMETER ( ZERO = 0.0D0 )
+ DOUBLE PRECISION ONE
+ PARAMETER ( ONE = 1.0D0 )
+* ..
+* .. Local Scalars ..
+ DOUBLE PRECISION W, XABS, YABS, Z
+* ..
+* .. Intrinsic Functions ..
+ INTRINSIC ABS, MAX, MIN, SQRT
+* ..
+* .. Executable Statements ..
+*
+ XABS = ABS( X )
+ YABS = ABS( Y )
+ W = MAX( XABS, YABS )
+ Z = MIN( XABS, YABS )
+ IF( Z.EQ.ZERO ) THEN
+ DLAPY2 = W
+ ELSE
+ DLAPY2 = W*SQRT( ONE+( Z / W )**2 )
+ END IF
+ RETURN
+*
+* End of DLAPY2
+*
+ END
diff --git a/lapack/dlapy3.f b/lapack/dlapy3.f
new file mode 100644
index 000000000..ae9844f80
--- /dev/null
+++ b/lapack/dlapy3.f
@@ -0,0 +1,111 @@
+*> \brief \b DLAPY3
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+*> \htmlonly
+*> Download DLAPY3 + dependencies
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlapy3.f">
+*> [TGZ]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlapy3.f">
+*> [ZIP]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlapy3.f">
+*> [TXT]</a>
+*> \endhtmlonly
+*
+* Definition:
+* ===========
+*
+* DOUBLE PRECISION FUNCTION DLAPY3( X, Y, Z )
+*
+* .. Scalar Arguments ..
+* DOUBLE PRECISION X, Y, Z
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> DLAPY3 returns sqrt(x**2+y**2+z**2), taking care not to cause
+*> unnecessary overflow.
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] X
+*> \verbatim
+*> X is DOUBLE PRECISION
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*> Y is DOUBLE PRECISION
+*> \endverbatim
+*>
+*> \param[in] Z
+*> \verbatim
+*> Z is DOUBLE PRECISION
+*> X, Y and Z specify the values x, y and z.
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*> \ingroup auxOTHERauxiliary
+*
+* =====================================================================
+ DOUBLE PRECISION FUNCTION DLAPY3( X, Y, Z )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2011
+*
+* .. Scalar Arguments ..
+ DOUBLE PRECISION X, Y, Z
+* ..
+*
+* =====================================================================
+*
+* .. Parameters ..
+ DOUBLE PRECISION ZERO
+ PARAMETER ( ZERO = 0.0D0 )
+* ..
+* .. Local Scalars ..
+ DOUBLE PRECISION W, XABS, YABS, ZABS
+* ..
+* .. Intrinsic Functions ..
+ INTRINSIC ABS, MAX, SQRT
+* ..
+* .. Executable Statements ..
+*
+ XABS = ABS( X )
+ YABS = ABS( Y )
+ ZABS = ABS( Z )
+ W = MAX( XABS, YABS, ZABS )
+ IF( W.EQ.ZERO ) THEN
+* W can be zero for max(0,nan,0)
+* adding all three entries together will make sure
+* NaN will not disappear.
+ DLAPY3 = XABS + YABS + ZABS
+ ELSE
+ DLAPY3 = W*SQRT( ( XABS / W )**2+( YABS / W )**2+
+ $ ( ZABS / W )**2 )
+ END IF
+ RETURN
+*
+* End of DLAPY3
+*
+ END
diff --git a/lapack/dsecnd_NONE.f b/lapack/dsecnd_NONE.f
new file mode 100644
index 000000000..61a8dff13
--- /dev/null
+++ b/lapack/dsecnd_NONE.f
@@ -0,0 +1,52 @@
+*> \brief \b DSECND returns nothing
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+* Definition:
+* ===========
+*
+* DOUBLE PRECISION FUNCTION DSECND( )
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> DSECND returns nothing instead of returning the user time for a process in seconds.
+*> If you are using that routine, it means that neither EXTERNAL ETIME,
+*> EXTERNAL ETIME_, INTERNAL ETIME, INTERNAL CPU_TIME is available on
+*> your machine.
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*> \ingroup auxOTHERauxiliary
+*
+* =====================================================================
+ DOUBLE PRECISION FUNCTION DSECND( )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2011
+*
+* =====================================================================
+*
+ DSECND = 0.0D+0
+ RETURN
+*
+* End of DSECND
+*
+ END
diff --git a/lapack/ilaclc.f b/lapack/ilaclc.f
new file mode 100644
index 000000000..4ceb61c52
--- /dev/null
+++ b/lapack/ilaclc.f
@@ -0,0 +1,118 @@
+*> \brief \b ILACLC
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+*> \htmlonly
+*> Download ILACLC + dependencies
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ilaclc.f">
+*> [TGZ]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ilaclc.f">
+*> [ZIP]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ilaclc.f">
+*> [TXT]</a>
+*> \endhtmlonly
+*
+* Definition:
+* ===========
+*
+* INTEGER FUNCTION ILACLC( M, N, A, LDA )
+*
+* .. Scalar Arguments ..
+* INTEGER M, N, LDA
+* ..
+* .. Array Arguments ..
+* COMPLEX A( LDA, * )
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> ILACLC scans A for its last non-zero column.
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] M
+*> \verbatim
+*> M is INTEGER
+*> The number of rows of the matrix A.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*> N is INTEGER
+*> The number of columns of the matrix A.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*> A is COMPLEX array, dimension (LDA,N)
+*> The m by n matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*> LDA is INTEGER
+*> The leading dimension of the array A. LDA >= max(1,M).
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*> \ingroup complexOTHERauxiliary
+*
+* =====================================================================
+ INTEGER FUNCTION ILACLC( M, N, A, LDA )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2011
+*
+* .. Scalar Arguments ..
+ INTEGER M, N, LDA
+* ..
+* .. Array Arguments ..
+ COMPLEX A( LDA, * )
+* ..
+*
+* =====================================================================
+*
+* .. Parameters ..
+ COMPLEX ZERO
+ PARAMETER ( ZERO = (0.0E+0, 0.0E+0) )
+* ..
+* .. Local Scalars ..
+ INTEGER I
+* ..
+* .. Executable Statements ..
+*
+* Quick test for the common case where one corner is non-zero.
+ IF( N.EQ.0 ) THEN
+ ILACLC = N
+ ELSE IF( A(1, N).NE.ZERO .OR. A(M, N).NE.ZERO ) THEN
+ ILACLC = N
+ ELSE
+* Now scan each column from the end, returning with the first non-zero.
+ DO ILACLC = N, 1, -1
+ DO I = 1, M
+ IF( A(I, ILACLC).NE.ZERO ) RETURN
+ END DO
+ END DO
+ END IF
+ RETURN
+ END
diff --git a/lapack/ilaclr.f b/lapack/ilaclr.f
new file mode 100644
index 000000000..d8ab09c55
--- /dev/null
+++ b/lapack/ilaclr.f
@@ -0,0 +1,121 @@
+*> \brief \b ILACLR
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+*> \htmlonly
+*> Download ILACLR + dependencies
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ilaclr.f">
+*> [TGZ]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ilaclr.f">
+*> [ZIP]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ilaclr.f">
+*> [TXT]</a>
+*> \endhtmlonly
+*
+* Definition:
+* ===========
+*
+* INTEGER FUNCTION ILACLR( M, N, A, LDA )
+*
+* .. Scalar Arguments ..
+* INTEGER M, N, LDA
+* ..
+* .. Array Arguments ..
+* COMPLEX A( LDA, * )
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> ILACLR scans A for its last non-zero row.
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] M
+*> \verbatim
+*> M is INTEGER
+*> The number of rows of the matrix A.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*> N is INTEGER
+*> The number of columns of the matrix A.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*> A is array, dimension (LDA,N)
+*> The m by n matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*> LDA is INTEGER
+*> The leading dimension of the array A. LDA >= max(1,M).
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date April 2012
+*
+*> \ingroup complexOTHERauxiliary
+*
+* =====================================================================
+ INTEGER FUNCTION ILACLR( M, N, A, LDA )
+*
+* -- LAPACK auxiliary routine (version 3.4.1) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* April 2012
+*
+* .. Scalar Arguments ..
+ INTEGER M, N, LDA
+* ..
+* .. Array Arguments ..
+ COMPLEX A( LDA, * )
+* ..
+*
+* =====================================================================
+*
+* .. Parameters ..
+ COMPLEX ZERO
+ PARAMETER ( ZERO = (0.0E+0, 0.0E+0) )
+* ..
+* .. Local Scalars ..
+ INTEGER I, J
+* ..
+* .. Executable Statements ..
+*
+* Quick test for the common case where one corner is non-zero.
+ IF( M.EQ.0 ) THEN
+ ILACLR = M
+ ELSE IF( A(M, 1).NE.ZERO .OR. A(M, N).NE.ZERO ) THEN
+ ILACLR = M
+ ELSE
+* Scan up each column tracking the last zero row seen.
+ ILACLR = 0
+ DO J = 1, N
+ I=M
+ DO WHILE((A(MAX(I,1),J).EQ.ZERO).AND.(I.GE.1))
+ I=I-1
+ ENDDO
+ ILACLR = MAX( ILACLR, I )
+ END DO
+ END IF
+ RETURN
+ END
diff --git a/lapack/iladlc.f b/lapack/iladlc.f
new file mode 100644
index 000000000..f84bd833a
--- /dev/null
+++ b/lapack/iladlc.f
@@ -0,0 +1,118 @@
+*> \brief \b ILADLC
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+*> \htmlonly
+*> Download ILADLC + dependencies
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/iladlc.f">
+*> [TGZ]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/iladlc.f">
+*> [ZIP]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/iladlc.f">
+*> [TXT]</a>
+*> \endhtmlonly
+*
+* Definition:
+* ===========
+*
+* INTEGER FUNCTION ILADLC( M, N, A, LDA )
+*
+* .. Scalar Arguments ..
+* INTEGER M, N, LDA
+* ..
+* .. Array Arguments ..
+* DOUBLE PRECISION A( LDA, * )
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> ILADLC scans A for its last non-zero column.
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] M
+*> \verbatim
+*> M is INTEGER
+*> The number of rows of the matrix A.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*> N is INTEGER
+*> The number of columns of the matrix A.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*> A is DOUBLE PRECISION array, dimension (LDA,N)
+*> The m by n matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*> LDA is INTEGER
+*> The leading dimension of the array A. LDA >= max(1,M).
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*> \ingroup auxOTHERauxiliary
+*
+* =====================================================================
+ INTEGER FUNCTION ILADLC( M, N, A, LDA )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2011
+*
+* .. Scalar Arguments ..
+ INTEGER M, N, LDA
+* ..
+* .. Array Arguments ..
+ DOUBLE PRECISION A( LDA, * )
+* ..
+*
+* =====================================================================
+*
+* .. Parameters ..
+ DOUBLE PRECISION ZERO
+ PARAMETER ( ZERO = 0.0D+0 )
+* ..
+* .. Local Scalars ..
+ INTEGER I
+* ..
+* .. Executable Statements ..
+*
+* Quick test for the common case where one corner is non-zero.
+ IF( N.EQ.0 ) THEN
+ ILADLC = N
+ ELSE IF( A(1, N).NE.ZERO .OR. A(M, N).NE.ZERO ) THEN
+ ILADLC = N
+ ELSE
+* Now scan each column from the end, returning with the first non-zero.
+ DO ILADLC = N, 1, -1
+ DO I = 1, M
+ IF( A(I, ILADLC).NE.ZERO ) RETURN
+ END DO
+ END DO
+ END IF
+ RETURN
+ END
diff --git a/lapack/iladlr.f b/lapack/iladlr.f
new file mode 100644
index 000000000..2114c6164
--- /dev/null
+++ b/lapack/iladlr.f
@@ -0,0 +1,121 @@
+*> \brief \b ILADLR
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+*> \htmlonly
+*> Download ILADLR + dependencies
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/iladlr.f">
+*> [TGZ]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/iladlr.f">
+*> [ZIP]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/iladlr.f">
+*> [TXT]</a>
+*> \endhtmlonly
+*
+* Definition:
+* ===========
+*
+* INTEGER FUNCTION ILADLR( M, N, A, LDA )
+*
+* .. Scalar Arguments ..
+* INTEGER M, N, LDA
+* ..
+* .. Array Arguments ..
+* DOUBLE PRECISION A( LDA, * )
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> ILADLR scans A for its last non-zero row.
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] M
+*> \verbatim
+*> M is INTEGER
+*> The number of rows of the matrix A.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*> N is INTEGER
+*> The number of columns of the matrix A.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*> A is DOUBLE PRECISION array, dimension (LDA,N)
+*> The m by n matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*> LDA is INTEGER
+*> The leading dimension of the array A. LDA >= max(1,M).
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date April 2012
+*
+*> \ingroup auxOTHERauxiliary
+*
+* =====================================================================
+ INTEGER FUNCTION ILADLR( M, N, A, LDA )
+*
+* -- LAPACK auxiliary routine (version 3.4.1) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* April 2012
+*
+* .. Scalar Arguments ..
+ INTEGER M, N, LDA
+* ..
+* .. Array Arguments ..
+ DOUBLE PRECISION A( LDA, * )
+* ..
+*
+* =====================================================================
+*
+* .. Parameters ..
+ DOUBLE PRECISION ZERO
+ PARAMETER ( ZERO = 0.0D+0 )
+* ..
+* .. Local Scalars ..
+ INTEGER I, J
+* ..
+* .. Executable Statements ..
+*
+* Quick test for the common case where one corner is non-zero.
+ IF( M.EQ.0 ) THEN
+ ILADLR = M
+ ELSE IF( A(M, 1).NE.ZERO .OR. A(M, N).NE.ZERO ) THEN
+ ILADLR = M
+ ELSE
+* Scan up each column tracking the last zero row seen.
+ ILADLR = 0
+ DO J = 1, N
+ I=M
+ DO WHILE((A(MAX(I,1),J).EQ.ZERO).AND.(I.GE.1))
+ I=I-1
+ ENDDO
+ ILADLR = MAX( ILADLR, I )
+ END DO
+ END IF
+ RETURN
+ END
diff --git a/lapack/ilaslc.f b/lapack/ilaslc.f
new file mode 100644
index 000000000..e3db0f4ae
--- /dev/null
+++ b/lapack/ilaslc.f
@@ -0,0 +1,118 @@
+*> \brief \b ILASLC
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+*> \htmlonly
+*> Download ILASLC + dependencies
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ilaslc.f">
+*> [TGZ]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ilaslc.f">
+*> [ZIP]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ilaslc.f">
+*> [TXT]</a>
+*> \endhtmlonly
+*
+* Definition:
+* ===========
+*
+* INTEGER FUNCTION ILASLC( M, N, A, LDA )
+*
+* .. Scalar Arguments ..
+* INTEGER M, N, LDA
+* ..
+* .. Array Arguments ..
+* REAL A( LDA, * )
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> ILASLC scans A for its last non-zero column.
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] M
+*> \verbatim
+*> M is INTEGER
+*> The number of rows of the matrix A.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*> N is INTEGER
+*> The number of columns of the matrix A.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*> A is REAL array, dimension (LDA,N)
+*> The m by n matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*> LDA is INTEGER
+*> The leading dimension of the array A. LDA >= max(1,M).
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*> \ingroup realOTHERauxiliary
+*
+* =====================================================================
+ INTEGER FUNCTION ILASLC( M, N, A, LDA )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2011
+*
+* .. Scalar Arguments ..
+ INTEGER M, N, LDA
+* ..
+* .. Array Arguments ..
+ REAL A( LDA, * )
+* ..
+*
+* =====================================================================
+*
+* .. Parameters ..
+ REAL ZERO
+ PARAMETER ( ZERO = 0.0D+0 )
+* ..
+* .. Local Scalars ..
+ INTEGER I
+* ..
+* .. Executable Statements ..
+*
+* Quick test for the common case where one corner is non-zero.
+ IF( N.EQ.0 ) THEN
+ ILASLC = N
+ ELSE IF( A(1, N).NE.ZERO .OR. A(M, N).NE.ZERO ) THEN
+ ILASLC = N
+ ELSE
+* Now scan each column from the end, returning with the first non-zero.
+ DO ILASLC = N, 1, -1
+ DO I = 1, M
+ IF( A(I, ILASLC).NE.ZERO ) RETURN
+ END DO
+ END DO
+ END IF
+ RETURN
+ END
diff --git a/lapack/ilaslr.f b/lapack/ilaslr.f
new file mode 100644
index 000000000..48b73f44d
--- /dev/null
+++ b/lapack/ilaslr.f
@@ -0,0 +1,121 @@
+*> \brief \b ILASLR
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+*> \htmlonly
+*> Download ILASLR + dependencies
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ilaslr.f">
+*> [TGZ]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ilaslr.f">
+*> [ZIP]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ilaslr.f">
+*> [TXT]</a>
+*> \endhtmlonly
+*
+* Definition:
+* ===========
+*
+* INTEGER FUNCTION ILASLR( M, N, A, LDA )
+*
+* .. Scalar Arguments ..
+* INTEGER M, N, LDA
+* ..
+* .. Array Arguments ..
+* REAL A( LDA, * )
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> ILASLR scans A for its last non-zero row.
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] M
+*> \verbatim
+*> M is INTEGER
+*> The number of rows of the matrix A.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*> N is INTEGER
+*> The number of columns of the matrix A.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*> A is REAL array, dimension (LDA,N)
+*> The m by n matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*> LDA is INTEGER
+*> The leading dimension of the array A. LDA >= max(1,M).
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date April 2012
+*
+*> \ingroup realOTHERauxiliary
+*
+* =====================================================================
+ INTEGER FUNCTION ILASLR( M, N, A, LDA )
+*
+* -- LAPACK auxiliary routine (version 3.4.1) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* April 2012
+*
+* .. Scalar Arguments ..
+ INTEGER M, N, LDA
+* ..
+* .. Array Arguments ..
+ REAL A( LDA, * )
+* ..
+*
+* =====================================================================
+*
+* .. Parameters ..
+ REAL ZERO
+ PARAMETER ( ZERO = 0.0E+0 )
+* ..
+* .. Local Scalars ..
+ INTEGER I, J
+* ..
+* .. Executable Statements ..
+*
+* Quick test for the common case where one corner is non-zero.
+ IF( M.EQ.0 ) THEN
+ ILASLR = M
+ ELSEIF( A(M, 1).NE.ZERO .OR. A(M, N).NE.ZERO ) THEN
+ ILASLR = M
+ ELSE
+* Scan up each column tracking the last zero row seen.
+ ILASLR = 0
+ DO J = 1, N
+ I=M
+ DO WHILE((A(MAX(I,1),J).EQ.ZERO).AND.(I.GE.1))
+ I=I-1
+ ENDDO
+ ILASLR = MAX( ILASLR, I )
+ END DO
+ END IF
+ RETURN
+ END
diff --git a/lapack/ilazlc.f b/lapack/ilazlc.f
new file mode 100644
index 000000000..15b149022
--- /dev/null
+++ b/lapack/ilazlc.f
@@ -0,0 +1,118 @@
+*> \brief \b ILAZLC
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+*> \htmlonly
+*> Download ILAZLC + dependencies
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ilazlc.f">
+*> [TGZ]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ilazlc.f">
+*> [ZIP]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ilazlc.f">
+*> [TXT]</a>
+*> \endhtmlonly
+*
+* Definition:
+* ===========
+*
+* INTEGER FUNCTION ILAZLC( M, N, A, LDA )
+*
+* .. Scalar Arguments ..
+* INTEGER M, N, LDA
+* ..
+* .. Array Arguments ..
+* COMPLEX*16 A( LDA, * )
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> ILAZLC scans A for its last non-zero column.
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] M
+*> \verbatim
+*> M is INTEGER
+*> The number of rows of the matrix A.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*> N is INTEGER
+*> The number of columns of the matrix A.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*> A is COMPLEX*16 array, dimension (LDA,N)
+*> The m by n matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*> LDA is INTEGER
+*> The leading dimension of the array A. LDA >= max(1,M).
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*> \ingroup complex16OTHERauxiliary
+*
+* =====================================================================
+ INTEGER FUNCTION ILAZLC( M, N, A, LDA )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2011
+*
+* .. Scalar Arguments ..
+ INTEGER M, N, LDA
+* ..
+* .. Array Arguments ..
+ COMPLEX*16 A( LDA, * )
+* ..
+*
+* =====================================================================
+*
+* .. Parameters ..
+ COMPLEX*16 ZERO
+ PARAMETER ( ZERO = (0.0D+0, 0.0D+0) )
+* ..
+* .. Local Scalars ..
+ INTEGER I
+* ..
+* .. Executable Statements ..
+*
+* Quick test for the common case where one corner is non-zero.
+ IF( N.EQ.0 ) THEN
+ ILAZLC = N
+ ELSE IF( A(1, N).NE.ZERO .OR. A(M, N).NE.ZERO ) THEN
+ ILAZLC = N
+ ELSE
+* Now scan each column from the end, returning with the first non-zero.
+ DO ILAZLC = N, 1, -1
+ DO I = 1, M
+ IF( A(I, ILAZLC).NE.ZERO ) RETURN
+ END DO
+ END DO
+ END IF
+ RETURN
+ END
diff --git a/lapack/ilazlr.f b/lapack/ilazlr.f
new file mode 100644
index 000000000..b2ab943ca
--- /dev/null
+++ b/lapack/ilazlr.f
@@ -0,0 +1,121 @@
+*> \brief \b ILAZLR
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+*> \htmlonly
+*> Download ILAZLR + dependencies
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ilazlr.f">
+*> [TGZ]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ilazlr.f">
+*> [ZIP]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ilazlr.f">
+*> [TXT]</a>
+*> \endhtmlonly
+*
+* Definition:
+* ===========
+*
+* INTEGER FUNCTION ILAZLR( M, N, A, LDA )
+*
+* .. Scalar Arguments ..
+* INTEGER M, N, LDA
+* ..
+* .. Array Arguments ..
+* COMPLEX*16 A( LDA, * )
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> ILAZLR scans A for its last non-zero row.
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] M
+*> \verbatim
+*> M is INTEGER
+*> The number of rows of the matrix A.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*> N is INTEGER
+*> The number of columns of the matrix A.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*> A is COMPLEX*16 array, dimension (LDA,N)
+*> The m by n matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*> LDA is INTEGER
+*> The leading dimension of the array A. LDA >= max(1,M).
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date April 2012
+*
+*> \ingroup complex16OTHERauxiliary
+*
+* =====================================================================
+ INTEGER FUNCTION ILAZLR( M, N, A, LDA )
+*
+* -- LAPACK auxiliary routine (version 3.4.1) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* April 2012
+*
+* .. Scalar Arguments ..
+ INTEGER M, N, LDA
+* ..
+* .. Array Arguments ..
+ COMPLEX*16 A( LDA, * )
+* ..
+*
+* =====================================================================
+*
+* .. Parameters ..
+ COMPLEX*16 ZERO
+ PARAMETER ( ZERO = (0.0D+0, 0.0D+0) )
+* ..
+* .. Local Scalars ..
+ INTEGER I, J
+* ..
+* .. Executable Statements ..
+*
+* Quick test for the common case where one corner is non-zero.
+ IF( M.EQ.0 ) THEN
+ ILAZLR = M
+ ELSE IF( A(M, 1).NE.ZERO .OR. A(M, N).NE.ZERO ) THEN
+ ILAZLR = M
+ ELSE
+* Scan up each column tracking the last zero row seen.
+ ILAZLR = 0
+ DO J = 1, N
+ I=M
+ DO WHILE((A(MAX(I,1),J).EQ.ZERO).AND.(I.GE.1))
+ I=I-1
+ ENDDO
+ ILAZLR = MAX( ILAZLR, I )
+ END DO
+ END IF
+ RETURN
+ END
diff --git a/lapack/lu.cpp b/lapack/lu.cpp
index 311511674..90cebe0f4 100644
--- a/lapack/lu.cpp
+++ b/lapack/lu.cpp
@@ -28,8 +28,8 @@ EIGEN_LAPACK_FUNC(getrf,(int *m, int *n, RealScalar *pa, int *lda, int *ipiv, in
Scalar* a = reinterpret_cast<Scalar*>(pa);
int nb_transpositions;
- int ret = Eigen::internal::partial_lu_impl<Scalar,ColMajor,int>
- ::blocked_lu(*m, *n, a, *lda, ipiv, nb_transpositions);
+ int ret = int(Eigen::internal::partial_lu_impl<Scalar,ColMajor,int>
+ ::blocked_lu(*m, *n, a, *lda, ipiv, nb_transpositions));
for(int i=0; i<std::min(*m,*n); ++i)
ipiv[i]++;
diff --git a/lapack/second_NONE.f b/lapack/second_NONE.f
new file mode 100644
index 000000000..d3e6d3319
--- /dev/null
+++ b/lapack/second_NONE.f
@@ -0,0 +1,52 @@
+*> \brief \b SECOND returns nothing
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+* Definition:
+* ===========
+*
+* REAL FUNCTION SECOND( )
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> SECOND returns nothing instead of returning the user time for a process in seconds.
+*> If you are using that routine, it means that neither EXTERNAL ETIME,
+*> EXTERNAL ETIME_, INTERNAL ETIME, INTERNAL CPU_TIME is available on
+*> your machine.
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*> \ingroup auxOTHERauxiliary
+*
+* =====================================================================
+ REAL FUNCTION SECOND( )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2011
+*
+* =====================================================================
+*
+ SECOND = 0.0E+0
+ RETURN
+*
+* End of SECOND
+*
+ END
diff --git a/lapack/sladiv.f b/lapack/sladiv.f
new file mode 100644
index 000000000..da3afa36b
--- /dev/null
+++ b/lapack/sladiv.f
@@ -0,0 +1,128 @@
+*> \brief \b SLADIV
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+*> \htmlonly
+*> Download SLADIV + dependencies
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/sladiv.f">
+*> [TGZ]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/sladiv.f">
+*> [ZIP]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/sladiv.f">
+*> [TXT]</a>
+*> \endhtmlonly
+*
+* Definition:
+* ===========
+*
+* SUBROUTINE SLADIV( A, B, C, D, P, Q )
+*
+* .. Scalar Arguments ..
+* REAL A, B, C, D, P, Q
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> SLADIV performs complex division in real arithmetic
+*>
+*> a + i*b
+*> p + i*q = ---------
+*> c + i*d
+*>
+*> The algorithm is due to Robert L. Smith and can be found
+*> in D. Knuth, The art of Computer Programming, Vol.2, p.195
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] A
+*> \verbatim
+*> A is REAL
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*> B is REAL
+*> \endverbatim
+*>
+*> \param[in] C
+*> \verbatim
+*> C is REAL
+*> \endverbatim
+*>
+*> \param[in] D
+*> \verbatim
+*> D is REAL
+*> The scalars a, b, c, and d in the above expression.
+*> \endverbatim
+*>
+*> \param[out] P
+*> \verbatim
+*> P is REAL
+*> \endverbatim
+*>
+*> \param[out] Q
+*> \verbatim
+*> Q is REAL
+*> The scalars p and q in the above expression.
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*> \ingroup auxOTHERauxiliary
+*
+* =====================================================================
+ SUBROUTINE SLADIV( A, B, C, D, P, Q )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2011
+*
+* .. Scalar Arguments ..
+ REAL A, B, C, D, P, Q
+* ..
+*
+* =====================================================================
+*
+* .. Local Scalars ..
+ REAL E, F
+* ..
+* .. Intrinsic Functions ..
+ INTRINSIC ABS
+* ..
+* .. Executable Statements ..
+*
+ IF( ABS( D ).LT.ABS( C ) ) THEN
+ E = D / C
+ F = C + D*E
+ P = ( A+B*E ) / F
+ Q = ( B-A*E ) / F
+ ELSE
+ E = C / D
+ F = D + C*E
+ P = ( B+A*E ) / F
+ Q = ( -A+B*E ) / F
+ END IF
+*
+ RETURN
+*
+* End of SLADIV
+*
+ END
diff --git a/lapack/slamch.f b/lapack/slamch.f
new file mode 100644
index 000000000..4bffad0eb
--- /dev/null
+++ b/lapack/slamch.f
@@ -0,0 +1,192 @@
+*> \brief \b SLAMCH
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+* Definition:
+* ===========
+*
+* REAL FUNCTION SLAMCH( CMACH )
+*
+* .. Scalar Arguments ..
+* CHARACTER CMACH
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> SLAMCH determines single precision machine parameters.
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] CMACH
+*> \verbatim
+*> Specifies the value to be returned by SLAMCH:
+*> = 'E' or 'e', SLAMCH := eps
+*> = 'S' or 's , SLAMCH := sfmin
+*> = 'B' or 'b', SLAMCH := base
+*> = 'P' or 'p', SLAMCH := eps*base
+*> = 'N' or 'n', SLAMCH := t
+*> = 'R' or 'r', SLAMCH := rnd
+*> = 'M' or 'm', SLAMCH := emin
+*> = 'U' or 'u', SLAMCH := rmin
+*> = 'L' or 'l', SLAMCH := emax
+*> = 'O' or 'o', SLAMCH := rmax
+*> where
+*> eps = relative machine precision
+*> sfmin = safe minimum, such that 1/sfmin does not overflow
+*> base = base of the machine
+*> prec = eps*base
+*> t = number of (base) digits in the mantissa
+*> rnd = 1.0 when rounding occurs in addition, 0.0 otherwise
+*> emin = minimum exponent before (gradual) underflow
+*> rmin = underflow threshold - base**(emin-1)
+*> emax = largest exponent before overflow
+*> rmax = overflow threshold - (base**emax)*(1-eps)
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*> \ingroup auxOTHERauxiliary
+*
+* =====================================================================
+ REAL FUNCTION SLAMCH( CMACH )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2011
+*
+* .. Scalar Arguments ..
+ CHARACTER CMACH
+* ..
+*
+* =====================================================================
+*
+* .. Parameters ..
+ REAL ONE, ZERO
+ PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 )
+* ..
+* .. Local Scalars ..
+ REAL RND, EPS, SFMIN, SMALL, RMACH
+* ..
+* .. External Functions ..
+ LOGICAL LSAME
+ EXTERNAL LSAME
+* ..
+* .. Intrinsic Functions ..
+ INTRINSIC DIGITS, EPSILON, HUGE, MAXEXPONENT,
+ $ MINEXPONENT, RADIX, TINY
+* ..
+* .. Executable Statements ..
+*
+*
+* Assume rounding, not chopping. Always.
+*
+ RND = ONE
+*
+ IF( ONE.EQ.RND ) THEN
+ EPS = EPSILON(ZERO) * 0.5
+ ELSE
+ EPS = EPSILON(ZERO)
+ END IF
+*
+ IF( LSAME( CMACH, 'E' ) ) THEN
+ RMACH = EPS
+ ELSE IF( LSAME( CMACH, 'S' ) ) THEN
+ SFMIN = TINY(ZERO)
+ SMALL = ONE / HUGE(ZERO)
+ IF( SMALL.GE.SFMIN ) THEN
+*
+* Use SMALL plus a bit, to avoid the possibility of rounding
+* causing overflow when computing 1/sfmin.
+*
+ SFMIN = SMALL*( ONE+EPS )
+ END IF
+ RMACH = SFMIN
+ ELSE IF( LSAME( CMACH, 'B' ) ) THEN
+ RMACH = RADIX(ZERO)
+ ELSE IF( LSAME( CMACH, 'P' ) ) THEN
+ RMACH = EPS * RADIX(ZERO)
+ ELSE IF( LSAME( CMACH, 'N' ) ) THEN
+ RMACH = DIGITS(ZERO)
+ ELSE IF( LSAME( CMACH, 'R' ) ) THEN
+ RMACH = RND
+ ELSE IF( LSAME( CMACH, 'M' ) ) THEN
+ RMACH = MINEXPONENT(ZERO)
+ ELSE IF( LSAME( CMACH, 'U' ) ) THEN
+ RMACH = tiny(zero)
+ ELSE IF( LSAME( CMACH, 'L' ) ) THEN
+ RMACH = MAXEXPONENT(ZERO)
+ ELSE IF( LSAME( CMACH, 'O' ) ) THEN
+ RMACH = HUGE(ZERO)
+ ELSE
+ RMACH = ZERO
+ END IF
+*
+ SLAMCH = RMACH
+ RETURN
+*
+* End of SLAMCH
+*
+ END
+************************************************************************
+*> \brief \b SLAMC3
+*> \details
+*> \b Purpose:
+*> \verbatim
+*> SLAMC3 is intended to force A and B to be stored prior to doing
+*> the addition of A and B , for use in situations where optimizers
+*> might hold one of these in a register.
+*> \endverbatim
+*> \author LAPACK is a software package provided by Univ. of Tennessee, Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..
+*> \date November 2011
+*> \ingroup auxOTHERauxiliary
+*>
+*> \param[in] A
+*> \verbatim
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*> The values A and B.
+*> \endverbatim
+*>
+*
+ REAL FUNCTION SLAMC3( A, B )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
+* November 2010
+*
+* .. Scalar Arguments ..
+ REAL A, B
+* ..
+* =====================================================================
+*
+* .. Executable Statements ..
+*
+ SLAMC3 = A + B
+*
+ RETURN
+*
+* End of SLAMC3
+*
+ END
+*
+************************************************************************
diff --git a/lapack/slapy2.f b/lapack/slapy2.f
new file mode 100644
index 000000000..1f6b1ca4f
--- /dev/null
+++ b/lapack/slapy2.f
@@ -0,0 +1,104 @@
+*> \brief \b SLAPY2
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+*> \htmlonly
+*> Download SLAPY2 + dependencies
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/slapy2.f">
+*> [TGZ]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/slapy2.f">
+*> [ZIP]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/slapy2.f">
+*> [TXT]</a>
+*> \endhtmlonly
+*
+* Definition:
+* ===========
+*
+* REAL FUNCTION SLAPY2( X, Y )
+*
+* .. Scalar Arguments ..
+* REAL X, Y
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> SLAPY2 returns sqrt(x**2+y**2), taking care not to cause unnecessary
+*> overflow.
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] X
+*> \verbatim
+*> X is REAL
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*> Y is REAL
+*> X and Y specify the values x and y.
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*> \ingroup auxOTHERauxiliary
+*
+* =====================================================================
+ REAL FUNCTION SLAPY2( X, Y )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2011
+*
+* .. Scalar Arguments ..
+ REAL X, Y
+* ..
+*
+* =====================================================================
+*
+* .. Parameters ..
+ REAL ZERO
+ PARAMETER ( ZERO = 0.0E0 )
+ REAL ONE
+ PARAMETER ( ONE = 1.0E0 )
+* ..
+* .. Local Scalars ..
+ REAL W, XABS, YABS, Z
+* ..
+* .. Intrinsic Functions ..
+ INTRINSIC ABS, MAX, MIN, SQRT
+* ..
+* .. Executable Statements ..
+*
+ XABS = ABS( X )
+ YABS = ABS( Y )
+ W = MAX( XABS, YABS )
+ Z = MIN( XABS, YABS )
+ IF( Z.EQ.ZERO ) THEN
+ SLAPY2 = W
+ ELSE
+ SLAPY2 = W*SQRT( ONE+( Z / W )**2 )
+ END IF
+ RETURN
+*
+* End of SLAPY2
+*
+ END
diff --git a/lapack/slapy3.f b/lapack/slapy3.f
new file mode 100644
index 000000000..aa2f5bfc4
--- /dev/null
+++ b/lapack/slapy3.f
@@ -0,0 +1,111 @@
+*> \brief \b SLAPY3
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+*> \htmlonly
+*> Download SLAPY3 + dependencies
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/slapy3.f">
+*> [TGZ]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/slapy3.f">
+*> [ZIP]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/slapy3.f">
+*> [TXT]</a>
+*> \endhtmlonly
+*
+* Definition:
+* ===========
+*
+* REAL FUNCTION SLAPY3( X, Y, Z )
+*
+* .. Scalar Arguments ..
+* REAL X, Y, Z
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> SLAPY3 returns sqrt(x**2+y**2+z**2), taking care not to cause
+*> unnecessary overflow.
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] X
+*> \verbatim
+*> X is REAL
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*> Y is REAL
+*> \endverbatim
+*>
+*> \param[in] Z
+*> \verbatim
+*> Z is REAL
+*> X, Y and Z specify the values x, y and z.
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*> \ingroup auxOTHERauxiliary
+*
+* =====================================================================
+ REAL FUNCTION SLAPY3( X, Y, Z )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2011
+*
+* .. Scalar Arguments ..
+ REAL X, Y, Z
+* ..
+*
+* =====================================================================
+*
+* .. Parameters ..
+ REAL ZERO
+ PARAMETER ( ZERO = 0.0E0 )
+* ..
+* .. Local Scalars ..
+ REAL W, XABS, YABS, ZABS
+* ..
+* .. Intrinsic Functions ..
+ INTRINSIC ABS, MAX, SQRT
+* ..
+* .. Executable Statements ..
+*
+ XABS = ABS( X )
+ YABS = ABS( Y )
+ ZABS = ABS( Z )
+ W = MAX( XABS, YABS, ZABS )
+ IF( W.EQ.ZERO ) THEN
+* W can be zero for max(0,nan,0)
+* adding all three entries together will make sure
+* NaN will not disappear.
+ SLAPY3 = XABS + YABS + ZABS
+ ELSE
+ SLAPY3 = W*SQRT( ( XABS / W )**2+( YABS / W )**2+
+ $ ( ZABS / W )**2 )
+ END IF
+ RETURN
+*
+* End of SLAPY3
+*
+ END
diff --git a/lapack/zlacgv.f b/lapack/zlacgv.f
new file mode 100644
index 000000000..16c2e2ed9
--- /dev/null
+++ b/lapack/zlacgv.f
@@ -0,0 +1,116 @@
+*> \brief \b ZLACGV
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+*> \htmlonly
+*> Download ZLACGV + dependencies
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zlacgv.f">
+*> [TGZ]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zlacgv.f">
+*> [ZIP]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zlacgv.f">
+*> [TXT]</a>
+*> \endhtmlonly
+*
+* Definition:
+* ===========
+*
+* SUBROUTINE ZLACGV( N, X, INCX )
+*
+* .. Scalar Arguments ..
+* INTEGER INCX, N
+* ..
+* .. Array Arguments ..
+* COMPLEX*16 X( * )
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> ZLACGV conjugates a complex vector of length N.
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] N
+*> \verbatim
+*> N is INTEGER
+*> The length of the vector X. N >= 0.
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*> X is COMPLEX*16 array, dimension
+*> (1+(N-1)*abs(INCX))
+*> On entry, the vector of length N to be conjugated.
+*> On exit, X is overwritten with conjg(X).
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*> INCX is INTEGER
+*> The spacing between successive elements of X.
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*> \ingroup complex16OTHERauxiliary
+*
+* =====================================================================
+ SUBROUTINE ZLACGV( N, X, INCX )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2011
+*
+* .. Scalar Arguments ..
+ INTEGER INCX, N
+* ..
+* .. Array Arguments ..
+ COMPLEX*16 X( * )
+* ..
+*
+* =====================================================================
+*
+* .. Local Scalars ..
+ INTEGER I, IOFF
+* ..
+* .. Intrinsic Functions ..
+ INTRINSIC DCONJG
+* ..
+* .. Executable Statements ..
+*
+ IF( INCX.EQ.1 ) THEN
+ DO 10 I = 1, N
+ X( I ) = DCONJG( X( I ) )
+ 10 CONTINUE
+ ELSE
+ IOFF = 1
+ IF( INCX.LT.0 )
+ $ IOFF = 1 - ( N-1 )*INCX
+ DO 20 I = 1, N
+ X( IOFF ) = DCONJG( X( IOFF ) )
+ IOFF = IOFF + INCX
+ 20 CONTINUE
+ END IF
+ RETURN
+*
+* End of ZLACGV
+*
+ END
diff --git a/lapack/zladiv.f b/lapack/zladiv.f
new file mode 100644
index 000000000..aa71db14a
--- /dev/null
+++ b/lapack/zladiv.f
@@ -0,0 +1,97 @@
+*> \brief \b ZLADIV
+*
+* =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+* http://www.netlib.org/lapack/explore-html/
+*
+*> \htmlonly
+*> Download ZLADIV + dependencies
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zladiv.f">
+*> [TGZ]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zladiv.f">
+*> [ZIP]</a>
+*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zladiv.f">
+*> [TXT]</a>
+*> \endhtmlonly
+*
+* Definition:
+* ===========
+*
+* COMPLEX*16 FUNCTION ZLADIV( X, Y )
+*
+* .. Scalar Arguments ..
+* COMPLEX*16 X, Y
+* ..
+*
+*
+*> \par Purpose:
+* =============
+*>
+*> \verbatim
+*>
+*> ZLADIV := X / Y, where X and Y are complex. The computation of X / Y
+*> will not overflow on an intermediary step unless the results
+*> overflows.
+*> \endverbatim
+*
+* Arguments:
+* ==========
+*
+*> \param[in] X
+*> \verbatim
+*> X is COMPLEX*16
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*> Y is COMPLEX*16
+*> The complex scalars X and Y.
+*> \endverbatim
+*
+* Authors:
+* ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date November 2011
+*
+*> \ingroup complex16OTHERauxiliary
+*
+* =====================================================================
+ COMPLEX*16 FUNCTION ZLADIV( X, Y )
+*
+* -- LAPACK auxiliary routine (version 3.4.0) --
+* -- LAPACK is a software package provided by Univ. of Tennessee, --
+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+* November 2011
+*
+* .. Scalar Arguments ..
+ COMPLEX*16 X, Y
+* ..
+*
+* =====================================================================
+*
+* .. Local Scalars ..
+ DOUBLE PRECISION ZI, ZR
+* ..
+* .. External Subroutines ..
+ EXTERNAL DLADIV
+* ..
+* .. Intrinsic Functions ..
+ INTRINSIC DBLE, DCMPLX, DIMAG
+* ..
+* .. Executable Statements ..
+*
+ CALL DLADIV( DBLE( X ), DIMAG( X ), DBLE( Y ), DIMAG( Y ), ZR,
+ $ ZI )
+ ZLADIV = DCMPLX( ZR, ZI )
+*
+ RETURN
+*
+* End of ZLADIV
+*
+ END
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index be9617d85..580e2ef5e 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -153,7 +153,7 @@ ei_add_test(diagonal)
ei_add_test(miscmatrices)
ei_add_test(commainitializer)
ei_add_test(smallvectors)
-ei_add_test(map)
+ei_add_test(mapped_matrix)
ei_add_test(mapstride)
ei_add_test(mapstaticmethods)
ei_add_test(array)
diff --git a/test/adjoint.cpp b/test/adjoint.cpp
index 72ad9e407..ea36f7841 100644
--- a/test/adjoint.cpp
+++ b/test/adjoint.cpp
@@ -16,7 +16,7 @@ template<bool IsInteger> struct adjoint_specific;
template<> struct adjoint_specific<true> {
template<typename Vec, typename Mat, typename Scalar>
static void run(const Vec& v1, const Vec& v2, Vec& v3, const Mat& square, Scalar s1, Scalar s2) {
- VERIFY(test_isApproxWithRef((s1 * v1 + s2 * v2).dot(v3), internal::conj(s1) * v1.dot(v3) + internal::conj(s2) * v2.dot(v3), 0));
+ VERIFY(test_isApproxWithRef((s1 * v1 + s2 * v2).dot(v3), numext::conj(s1) * v1.dot(v3) + numext::conj(s2) * v2.dot(v3), 0));
VERIFY(test_isApproxWithRef(v3.dot(s1 * v1 + s2 * v2), s1*v3.dot(v1)+s2*v3.dot(v2), 0));
// check compatibility of dot and adjoint
@@ -28,9 +28,10 @@ template<> struct adjoint_specific<false> {
template<typename Vec, typename Mat, typename Scalar>
static void run(const Vec& v1, const Vec& v2, Vec& v3, const Mat& square, Scalar s1, Scalar s2) {
typedef typename NumTraits<Scalar>::Real RealScalar;
+ using std::abs;
RealScalar ref = NumTraits<Scalar>::IsInteger ? RealScalar(0) : (std::max)((s1 * v1 + s2 * v2).norm(),v3.norm());
- VERIFY(test_isApproxWithRef((s1 * v1 + s2 * v2).dot(v3), internal::conj(s1) * v1.dot(v3) + internal::conj(s2) * v2.dot(v3), ref));
+ VERIFY(test_isApproxWithRef((s1 * v1 + s2 * v2).dot(v3), numext::conj(s1) * v1.dot(v3) + numext::conj(s2) * v2.dot(v3), ref));
VERIFY(test_isApproxWithRef(v3.dot(s1 * v1 + s2 * v2), s1*v3.dot(v1)+s2*v3.dot(v2), ref));
VERIFY_IS_APPROX(v1.squaredNorm(), v1.norm() * v1.norm());
@@ -44,7 +45,7 @@ template<> struct adjoint_specific<false> {
// check compatibility of dot and adjoint
ref = NumTraits<Scalar>::IsInteger ? 0 : (std::max)((std::max)(v1.norm(),v2.norm()),(std::max)((square * v2).norm(),(square.adjoint() * v1).norm()));
- VERIFY(test_isApproxWithRef(v1.dot(square * v2), (square.adjoint() * v1).dot(v2), ref));
+ VERIFY(internal::isMuchSmallerThan(abs(v1.dot(square * v2) - (square.adjoint() * v1).dot(v2)), ref, test_precision<Scalar>()));
// check that Random().normalized() works: tricky as the random xpr must be evaluated by
// normalized() in order to produce a consistent result.
@@ -85,11 +86,11 @@ template<typename MatrixType> void adjoint(const MatrixType& m)
// check multiplicative behavior
VERIFY_IS_APPROX((m1.adjoint() * m2).adjoint(), m2.adjoint() * m1);
- VERIFY_IS_APPROX((s1 * m1).adjoint(), internal::conj(s1) * m1.adjoint());
+ VERIFY_IS_APPROX((s1 * m1).adjoint(), numext::conj(s1) * m1.adjoint());
// check basic properties of dot, squaredNorm
- VERIFY_IS_APPROX(internal::conj(v1.dot(v2)), v2.dot(v1));
- VERIFY_IS_APPROX(internal::real(v1.dot(v1)), v1.squaredNorm());
+ VERIFY_IS_APPROX(numext::conj(v1.dot(v2)), v2.dot(v1));
+ VERIFY_IS_APPROX(numext::real(v1.dot(v1)), v1.squaredNorm());
adjoint_specific<NumTraits<Scalar>::IsInteger>::run(v1, v2, v3, square, s1, s2);
@@ -98,8 +99,8 @@ template<typename MatrixType> void adjoint(const MatrixType& m)
// like in testBasicStuff, test operator() to check const-qualification
Index r = internal::random<Index>(0, rows-1),
c = internal::random<Index>(0, cols-1);
- VERIFY_IS_APPROX(m1.conjugate()(r,c), internal::conj(m1(r,c)));
- VERIFY_IS_APPROX(m1.adjoint()(c,r), internal::conj(m1(r,c)));
+ VERIFY_IS_APPROX(m1.conjugate()(r,c), numext::conj(m1(r,c)));
+ VERIFY_IS_APPROX(m1.adjoint()(c,r), numext::conj(m1(r,c)));
// check inplace transpose
m3 = m1;
diff --git a/test/array.cpp b/test/array.cpp
index ceb00fa05..8960e49f8 100644
--- a/test/array.cpp
+++ b/test/array.cpp
@@ -152,6 +152,7 @@ template<typename ArrayType> void comparisons(const ArrayType& m)
template<typename ArrayType> void array_real(const ArrayType& m)
{
using std::abs;
+ using std::sqrt;
typedef typename ArrayType::Index Index;
typedef typename ArrayType::Scalar Scalar;
typedef typename NumTraits<Scalar>::Real RealScalar;
@@ -160,8 +161,8 @@ template<typename ArrayType> void array_real(const ArrayType& m)
Index cols = m.cols();
ArrayType m1 = ArrayType::Random(rows, cols),
- m2 = ArrayType::Random(rows, cols),
- m3(rows, cols);
+ m2 = ArrayType::Random(rows, cols),
+ m3(rows, cols);
Scalar s1 = internal::random<Scalar>();
@@ -182,14 +183,14 @@ template<typename ArrayType> void array_real(const ArrayType& m)
// VERIFY_IS_APPROX(m1.abs().sqrt(), std::sqrt(std::abs(m1)));
VERIFY_IS_APPROX(m1.abs().sqrt(), sqrt(abs(m1)));
- VERIFY_IS_APPROX(m1.abs(), sqrt(internal::abs2(m1)));
+ VERIFY_IS_APPROX(m1.abs(), sqrt(numext::abs2(m1)));
- VERIFY_IS_APPROX(internal::abs2(internal::real(m1)) + internal::abs2(internal::imag(m1)), internal::abs2(m1));
- VERIFY_IS_APPROX(internal::abs2(real(m1)) + internal::abs2(imag(m1)), internal::abs2(m1));
+ VERIFY_IS_APPROX(numext::abs2(numext::real(m1)) + numext::abs2(numext::imag(m1)), numext::abs2(m1));
+ VERIFY_IS_APPROX(numext::abs2(real(m1)) + numext::abs2(imag(m1)), numext::abs2(m1));
if(!NumTraits<Scalar>::IsComplex)
- VERIFY_IS_APPROX(internal::real(m1), m1);
+ VERIFY_IS_APPROX(numext::real(m1), m1);
- VERIFY((m1.abs().log() == log(abs(m1))).all());
+ VERIFY_IS_APPROX(m1.abs().log() , log(abs(m1)));
// VERIFY_IS_APPROX(m1.exp(), std::exp(m1));
VERIFY_IS_APPROX(m1.exp() * m2.exp(), exp(m1+m2));
@@ -211,6 +212,13 @@ template<typename ArrayType> void array_real(const ArrayType& m)
s1 += Scalar(tiny);
m1 += ArrayType::Constant(rows,cols,Scalar(tiny));
VERIFY_IS_APPROX(s1/m1, s1 * m1.inverse());
+
+ // check inplace transpose
+ m3 = m1;
+ m3.transposeInPlace();
+ VERIFY_IS_APPROX(m3,m1.transpose());
+ m3.transposeInPlace();
+ VERIFY_IS_APPROX(m3,m1);
}
template<typename ArrayType> void array_complex(const ArrayType& m)
diff --git a/test/array_for_matrix.cpp b/test/array_for_matrix.cpp
index 99cda1ffe..1250c9ff5 100644
--- a/test/array_for_matrix.cpp
+++ b/test/array_for_matrix.cpp
@@ -25,10 +25,10 @@ template<typename MatrixType> void array_for_matrix(const MatrixType& m)
ColVectorType cv1 = ColVectorType::Random(rows);
RowVectorType rv1 = RowVectorType::Random(cols);
-
+
Scalar s1 = internal::random<Scalar>(),
s2 = internal::random<Scalar>();
-
+
// scalar addition
VERIFY_IS_APPROX(m1.array() + s1, s1 + m1.array());
VERIFY_IS_APPROX((m1.array() + s1).matrix(), MatrixType::Constant(rows,cols,s1) + m1);
@@ -138,7 +138,7 @@ template<typename VectorType> void lpNorm(const VectorType& v)
VERIFY_IS_APPROX(u.template lpNorm<Infinity>(), u.cwiseAbs().maxCoeff());
VERIFY_IS_APPROX(u.template lpNorm<1>(), u.cwiseAbs().sum());
VERIFY_IS_APPROX(u.template lpNorm<2>(), sqrt(u.array().abs().square().sum()));
- VERIFY_IS_APPROX(internal::pow(u.template lpNorm<5>(), typename VectorType::RealScalar(5)), u.array().abs().pow(5).sum());
+ VERIFY_IS_APPROX(numext::pow(u.template lpNorm<5>(), typename VectorType::RealScalar(5)), u.array().abs().pow(5).sum());
}
template<typename MatrixType> void cwise_min_max(const MatrixType& m)
diff --git a/test/basicstuff.cpp b/test/basicstuff.cpp
index 0fbae19e8..8c0621ecd 100644
--- a/test/basicstuff.cpp
+++ b/test/basicstuff.cpp
@@ -141,10 +141,10 @@ template<typename MatrixType> void basicStuffComplex(const MatrixType& m)
Scalar s1 = internal::random<Scalar>(),
s2 = internal::random<Scalar>();
- VERIFY(internal::real(s1)==internal::real_ref(s1));
- VERIFY(internal::imag(s1)==internal::imag_ref(s1));
- internal::real_ref(s1) = internal::real(s2);
- internal::imag_ref(s1) = internal::imag(s2);
+ VERIFY(numext::real(s1)==numext::real_ref(s1));
+ VERIFY(numext::imag(s1)==numext::imag_ref(s1));
+ numext::real_ref(s1) = numext::real(s2);
+ numext::imag_ref(s1) = numext::imag(s2);
VERIFY(internal::isApprox(s1, s2, NumTraits<RealScalar>::epsilon()));
// extended precision in Intel FPUs means that s1 == s2 in the line above is not guaranteed.
diff --git a/test/block.cpp b/test/block.cpp
index 0969262ca..189fa5aba 100644
--- a/test/block.cpp
+++ b/test/block.cpp
@@ -77,6 +77,12 @@ template<typename MatrixType> void block(const MatrixType& m)
// check that fixed block() and block() agree
Matrix<Scalar,Dynamic,Dynamic> b = m1.template block<BlockRows,BlockCols>(3,3);
VERIFY_IS_EQUAL(b, m1.block(3,3,BlockRows,BlockCols));
+
+ // same tests with mixed fixed/dynamic size
+ m1.template block<BlockRows,Dynamic>(1,1,BlockRows,BlockCols) *= s1;
+ m1.template block<BlockRows,Dynamic>(1,1,BlockRows,BlockCols)(0,3) = m1.template block<2,5>(1,1)(1,2);
+ Matrix<Scalar,Dynamic,Dynamic> b2 = m1.template block<Dynamic,BlockCols>(3,3,2,5);
+ VERIFY_IS_EQUAL(b2, m1.block(3,3,BlockRows,BlockCols));
}
if (rows>2)
@@ -96,11 +102,11 @@ template<typename MatrixType> void block(const MatrixType& m)
}
// stress some basic stuffs with block matrices
- VERIFY(internal::real(ones.col(c1).sum()) == RealScalar(rows));
- VERIFY(internal::real(ones.row(r1).sum()) == RealScalar(cols));
+ VERIFY(numext::real(ones.col(c1).sum()) == RealScalar(rows));
+ VERIFY(numext::real(ones.row(r1).sum()) == RealScalar(cols));
- VERIFY(internal::real(ones.col(c1).dot(ones.col(c2))) == RealScalar(rows));
- VERIFY(internal::real(ones.row(r1).dot(ones.row(r2))) == RealScalar(cols));
+ VERIFY(numext::real(ones.col(c1).dot(ones.col(c2))) == RealScalar(rows));
+ VERIFY(numext::real(ones.row(r1).dot(ones.row(r2))) == RealScalar(cols));
// now test some block-inside-of-block.
diff --git a/test/cholesky.cpp b/test/cholesky.cpp
index ca7ecb1f4..378525a83 100644
--- a/test/cholesky.cpp
+++ b/test/cholesky.cpp
@@ -82,14 +82,14 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
symm += a1 * a1.adjoint();
}
- SquareMatrixType symmUp = symm.template triangularView<Upper>();
- SquareMatrixType symmLo = symm.template triangularView<Lower>();
-
// to test if really Cholesky only uses the upper triangular part, uncomment the following
// FIXME: currently that fails !!
//symm.template part<StrictlyLower>().setZero();
{
+ SquareMatrixType symmUp = symm.template triangularView<Upper>();
+ SquareMatrixType symmLo = symm.template triangularView<Lower>();
+
LLT<SquareMatrixType,Lower> chollo(symmLo);
VERIFY_IS_APPROX(symm, chollo.reconstructedMatrix());
vecX = chollo.solve(vecB);
@@ -113,6 +113,21 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
VERIFY_IS_APPROX(MatrixType(chollo.matrixU().transpose().conjugate()), MatrixType(chollo.matrixL()));
VERIFY_IS_APPROX(MatrixType(cholup.matrixL().transpose().conjugate()), MatrixType(cholup.matrixU()));
VERIFY_IS_APPROX(MatrixType(cholup.matrixU().transpose().conjugate()), MatrixType(cholup.matrixL()));
+
+ // test some special use cases of SelfCwiseBinaryOp:
+ MatrixType m1 = MatrixType::Random(rows,cols), m2(rows,cols);
+ m2 = m1;
+ m2 += symmLo.template selfadjointView<Lower>().llt().solve(matB);
+ VERIFY_IS_APPROX(m2, m1 + symmLo.template selfadjointView<Lower>().llt().solve(matB));
+ m2 = m1;
+ m2 -= symmLo.template selfadjointView<Lower>().llt().solve(matB);
+ VERIFY_IS_APPROX(m2, m1 - symmLo.template selfadjointView<Lower>().llt().solve(matB));
+ m2 = m1;
+ m2.noalias() += symmLo.template selfadjointView<Lower>().llt().solve(matB);
+ VERIFY_IS_APPROX(m2, m1 + symmLo.template selfadjointView<Lower>().llt().solve(matB));
+ m2 = m1;
+ m2.noalias() -= symmLo.template selfadjointView<Lower>().llt().solve(matB);
+ VERIFY_IS_APPROX(m2, m1 - symmLo.template selfadjointView<Lower>().llt().solve(matB));
}
// LDLT
@@ -166,21 +181,6 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
symm = -symm;
}
- // test some special use cases of SelfCwiseBinaryOp:
- MatrixType m1 = MatrixType::Random(rows,cols), m2(rows,cols);
- m2 = m1;
- m2 += symmLo.template selfadjointView<Lower>().llt().solve(matB);
- VERIFY_IS_APPROX(m2, m1 + symmLo.template selfadjointView<Lower>().llt().solve(matB));
- m2 = m1;
- m2 -= symmLo.template selfadjointView<Lower>().llt().solve(matB);
- VERIFY_IS_APPROX(m2, m1 - symmLo.template selfadjointView<Lower>().llt().solve(matB));
- m2 = m1;
- m2.noalias() += symmLo.template selfadjointView<Lower>().llt().solve(matB);
- VERIFY_IS_APPROX(m2, m1 + symmLo.template selfadjointView<Lower>().llt().solve(matB));
- m2 = m1;
- m2.noalias() -= symmLo.template selfadjointView<Lower>().llt().solve(matB);
- VERIFY_IS_APPROX(m2, m1 - symmLo.template selfadjointView<Lower>().llt().solve(matB));
-
// update/downdate
CALL_SUBTEST(( test_chol_update<SquareMatrixType,LLT>(symm) ));
CALL_SUBTEST(( test_chol_update<SquareMatrixType,LDLT>(symm) ));
@@ -268,10 +268,18 @@ template<typename MatrixType> void cholesky_indefinite(const MatrixType& m)
{
eigen_assert(m.rows() == 2 && m.cols() == 2);
MatrixType mat;
- mat << 1, 0, 0, -1;
- LDLT<MatrixType> ldlt(mat);
- VERIFY(!ldlt.isNegative());
- VERIFY(!ldlt.isPositive());
+ {
+ mat << 1, 0, 0, -1;
+ LDLT<MatrixType> ldlt(mat);
+ VERIFY(!ldlt.isNegative());
+ VERIFY(!ldlt.isPositive());
+ }
+ {
+ mat << 1, 2, 2, 1;
+ LDLT<MatrixType> ldlt(mat);
+ VERIFY(!ldlt.isNegative());
+ VERIFY(!ldlt.isPositive());
+ }
}
template<typename MatrixType> void cholesky_verify_assert()
@@ -296,7 +304,7 @@ template<typename MatrixType> void cholesky_verify_assert()
void test_cholesky()
{
- int s;
+ int s = 0;
for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST_1( cholesky(Matrix<double,1,1>()) );
CALL_SUBTEST_3( cholesky(Matrix2d()) );
@@ -319,5 +327,6 @@ void test_cholesky()
CALL_SUBTEST_9( LLT<MatrixXf>(10) );
CALL_SUBTEST_9( LDLT<MatrixXf>(10) );
- EIGEN_UNUSED_VARIABLE(s)
+ TEST_SET_BUT_UNUSED_VARIABLE(s)
+ TEST_SET_BUT_UNUSED_VARIABLE(nb_temporaries)
}
diff --git a/test/corners.cpp b/test/corners.cpp
index 4705c5f05..3c64c32a1 100644
--- a/test/corners.cpp
+++ b/test/corners.cpp
@@ -62,6 +62,16 @@ template<typename MatrixType, int CRows, int CCols, int SRows, int SCols> void c
VERIFY_IS_EQUAL((matrix.template bottomLeftCorner<r,c>()), (matrix.template block<r,c>(rows-r,0)));
VERIFY_IS_EQUAL((matrix.template bottomRightCorner<r,c>()), (matrix.template block<r,c>(rows-r,cols-c)));
+ VERIFY_IS_EQUAL((matrix.template topLeftCorner<r,c>()), (matrix.template topLeftCorner<r,Dynamic>(r,c)));
+ VERIFY_IS_EQUAL((matrix.template topRightCorner<r,c>()), (matrix.template topRightCorner<r,Dynamic>(r,c)));
+ VERIFY_IS_EQUAL((matrix.template bottomLeftCorner<r,c>()), (matrix.template bottomLeftCorner<r,Dynamic>(r,c)));
+ VERIFY_IS_EQUAL((matrix.template bottomRightCorner<r,c>()), (matrix.template bottomRightCorner<r,Dynamic>(r,c)));
+
+ VERIFY_IS_EQUAL((matrix.template topLeftCorner<r,c>()), (matrix.template topLeftCorner<Dynamic,c>(r,c)));
+ VERIFY_IS_EQUAL((matrix.template topRightCorner<r,c>()), (matrix.template topRightCorner<Dynamic,c>(r,c)));
+ VERIFY_IS_EQUAL((matrix.template bottomLeftCorner<r,c>()), (matrix.template bottomLeftCorner<Dynamic,c>(r,c)));
+ VERIFY_IS_EQUAL((matrix.template bottomRightCorner<r,c>()), (matrix.template bottomRightCorner<Dynamic,c>(r,c)));
+
VERIFY_IS_EQUAL((matrix.template topRows<r>()), (matrix.template block<r,cols>(0,0)));
VERIFY_IS_EQUAL((matrix.template middleRows<r>(sr)), (matrix.template block<r,cols>(sr,0)));
VERIFY_IS_EQUAL((matrix.template bottomRows<r>()), (matrix.template block<r,cols>(rows-r,0)));
@@ -74,6 +84,16 @@ template<typename MatrixType, int CRows, int CCols, int SRows, int SCols> void c
VERIFY_IS_EQUAL((const_matrix.template bottomLeftCorner<r,c>()), (const_matrix.template block<r,c>(rows-r,0)));
VERIFY_IS_EQUAL((const_matrix.template bottomRightCorner<r,c>()), (const_matrix.template block<r,c>(rows-r,cols-c)));
+ VERIFY_IS_EQUAL((const_matrix.template topLeftCorner<r,c>()), (const_matrix.template topLeftCorner<r,Dynamic>(r,c)));
+ VERIFY_IS_EQUAL((const_matrix.template topRightCorner<r,c>()), (const_matrix.template topRightCorner<r,Dynamic>(r,c)));
+ VERIFY_IS_EQUAL((const_matrix.template bottomLeftCorner<r,c>()), (const_matrix.template bottomLeftCorner<r,Dynamic>(r,c)));
+ VERIFY_IS_EQUAL((const_matrix.template bottomRightCorner<r,c>()), (const_matrix.template bottomRightCorner<r,Dynamic>(r,c)));
+
+ VERIFY_IS_EQUAL((const_matrix.template topLeftCorner<r,c>()), (const_matrix.template topLeftCorner<Dynamic,c>(r,c)));
+ VERIFY_IS_EQUAL((const_matrix.template topRightCorner<r,c>()), (const_matrix.template topRightCorner<Dynamic,c>(r,c)));
+ VERIFY_IS_EQUAL((const_matrix.template bottomLeftCorner<r,c>()), (const_matrix.template bottomLeftCorner<Dynamic,c>(r,c)));
+ VERIFY_IS_EQUAL((const_matrix.template bottomRightCorner<r,c>()), (const_matrix.template bottomRightCorner<Dynamic,c>(r,c)));
+
VERIFY_IS_EQUAL((const_matrix.template topRows<r>()), (const_matrix.template block<r,cols>(0,0)));
VERIFY_IS_EQUAL((const_matrix.template middleRows<r>(sr)), (const_matrix.template block<r,cols>(sr,0)));
VERIFY_IS_EQUAL((const_matrix.template bottomRows<r>()), (const_matrix.template block<r,cols>(rows-r,0)));
diff --git a/test/determinant.cpp b/test/determinant.cpp
index e93f2f297..758f3afbb 100644
--- a/test/determinant.cpp
+++ b/test/determinant.cpp
@@ -39,7 +39,7 @@ template<typename MatrixType> void determinant(const MatrixType& m)
m2.col(i).swap(m2.col(j));
VERIFY_IS_APPROX(m2.determinant(), -m1.determinant());
VERIFY_IS_APPROX(m2.determinant(), m2.transpose().determinant());
- VERIFY_IS_APPROX(internal::conj(m2.determinant()), m2.adjoint().determinant());
+ VERIFY_IS_APPROX(numext::conj(m2.determinant()), m2.adjoint().determinant());
m2 = m1;
m2.row(i) += x*m2.row(j);
VERIFY_IS_APPROX(m2.determinant(), m1.determinant());
@@ -53,8 +53,8 @@ template<typename MatrixType> void determinant(const MatrixType& m)
void test_determinant()
{
- int s;
for(int i = 0; i < g_repeat; i++) {
+ int s = 0;
CALL_SUBTEST_1( determinant(Matrix<float, 1, 1>()) );
CALL_SUBTEST_2( determinant(Matrix<double, 2, 2>()) );
CALL_SUBTEST_3( determinant(Matrix<double, 3, 3>()) );
@@ -62,6 +62,6 @@ void test_determinant()
CALL_SUBTEST_5( determinant(Matrix<std::complex<double>, 10, 10>()) );
s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
CALL_SUBTEST_6( determinant(MatrixXd(s, s)) );
+ TEST_SET_BUT_UNUSED_VARIABLE(s)
}
- EIGEN_UNUSED_VARIABLE(s)
}
diff --git a/test/eigen2support.cpp b/test/eigen2support.cpp
index bfcc87323..ad1d98091 100644
--- a/test/eigen2support.cpp
+++ b/test/eigen2support.cpp
@@ -44,8 +44,8 @@ template<typename MatrixType> void eigen2support(const MatrixType& m)
VERIFY_IS_EQUAL((m1.col(0).template end<1>()), (m1.col(0).segment(rows-1,1)));
using std::cos;
- using internal::real;
- using internal::abs2;
+ using numext::real;
+ using numext::abs2;
VERIFY_IS_EQUAL(ei_cos(s1), cos(s1));
VERIFY_IS_EQUAL(ei_real(s1), real(s1));
VERIFY_IS_EQUAL(ei_abs2(s1), abs2(s1));
diff --git a/test/eigensolver_complex.cpp b/test/eigensolver_complex.cpp
index 817fbf2c2..c9d8c0877 100644
--- a/test/eigensolver_complex.cpp
+++ b/test/eigensolver_complex.cpp
@@ -101,7 +101,7 @@ template<typename MatrixType> void eigensolver_verify_assert(const MatrixType& m
void test_eigensolver_complex()
{
- int s;
+ int s = 0;
for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST_1( eigensolver(Matrix4cf()) );
s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
@@ -109,7 +109,6 @@ void test_eigensolver_complex()
CALL_SUBTEST_3( eigensolver(Matrix<std::complex<float>, 1, 1>()) );
CALL_SUBTEST_4( eigensolver(Matrix3f()) );
}
-
CALL_SUBTEST_1( eigensolver_verify_assert(Matrix4cf()) );
s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
CALL_SUBTEST_2( eigensolver_verify_assert(MatrixXcd(s,s)) );
@@ -117,7 +116,7 @@ void test_eigensolver_complex()
CALL_SUBTEST_4( eigensolver_verify_assert(Matrix3f()) );
// Test problem size constructors
- CALL_SUBTEST_5(ComplexEigenSolver<MatrixXf>(s));
+ CALL_SUBTEST_5(ComplexEigenSolver<MatrixXf> tmp(s));
- EIGEN_UNUSED_VARIABLE(s)
+ TEST_SET_BUT_UNUSED_VARIABLE(s)
}
diff --git a/test/eigensolver_generalized_real.cpp b/test/eigensolver_generalized_real.cpp
index b8775871d..566a4bdc6 100644
--- a/test/eigensolver_generalized_real.cpp
+++ b/test/eigensolver_generalized_real.cpp
@@ -43,8 +43,8 @@ template<typename MatrixType> void generalized_eigensolver_real(const MatrixType
void test_eigensolver_generalized_real()
{
- int s;
for(int i = 0; i < g_repeat; i++) {
+ int s = 0;
CALL_SUBTEST_1( generalized_eigensolver_real(Matrix4f()) );
s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
CALL_SUBTEST_2( generalized_eigensolver_real(MatrixXd(s,s)) );
@@ -54,7 +54,6 @@ void test_eigensolver_generalized_real()
CALL_SUBTEST_2( generalized_eigensolver_real(MatrixXd(2,2)) );
CALL_SUBTEST_3( generalized_eigensolver_real(Matrix<double,1,1>()) );
CALL_SUBTEST_4( generalized_eigensolver_real(Matrix2d()) );
+ TEST_SET_BUT_UNUSED_VARIABLE(s)
}
-
- EIGEN_UNUSED_VARIABLE(s)
}
diff --git a/test/eigensolver_generic.cpp b/test/eigensolver_generic.cpp
index a8bbf9007..005af81eb 100644
--- a/test/eigensolver_generic.cpp
+++ b/test/eigensolver_generic.cpp
@@ -88,7 +88,7 @@ template<typename MatrixType> void eigensolver_verify_assert(const MatrixType& m
void test_eigensolver_generic()
{
- int s;
+ int s = 0;
for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST_1( eigensolver(Matrix4f()) );
s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
@@ -108,7 +108,7 @@ void test_eigensolver_generic()
CALL_SUBTEST_4( eigensolver_verify_assert(Matrix2d()) );
// Test problem size constructors
- CALL_SUBTEST_5(EigenSolver<MatrixXf>(s));
+ CALL_SUBTEST_5(EigenSolver<MatrixXf> tmp(s));
// regression test for bug 410
CALL_SUBTEST_2(
@@ -121,5 +121,5 @@ void test_eigensolver_generic()
}
);
- EIGEN_UNUSED_VARIABLE(s)
+ TEST_SET_BUT_UNUSED_VARIABLE(s)
}
diff --git a/test/eigensolver_selfadjoint.cpp b/test/eigensolver_selfadjoint.cpp
index 55b7eea8d..5c6ecd875 100644
--- a/test/eigensolver_selfadjoint.cpp
+++ b/test/eigensolver_selfadjoint.cpp
@@ -110,7 +110,7 @@ template<typename MatrixType> void selfadjointeigensolver(const MatrixType& m)
void test_eigensolver_selfadjoint()
{
- int s;
+ int s = 0;
for(int i = 0; i < g_repeat; i++) {
// very important to test 3x3 and 2x2 matrices since we provide special paths for them
CALL_SUBTEST_1( selfadjointeigensolver(Matrix2d()) );
@@ -135,9 +135,9 @@ void test_eigensolver_selfadjoint()
// Test problem size constructors
s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
- CALL_SUBTEST_8(SelfAdjointEigenSolver<MatrixXf>(s));
- CALL_SUBTEST_8(Tridiagonalization<MatrixXf>(s));
+ CALL_SUBTEST_8(SelfAdjointEigenSolver<MatrixXf> tmp1(s));
+ CALL_SUBTEST_8(Tridiagonalization<MatrixXf> tmp2(s));
- EIGEN_UNUSED_VARIABLE(s)
+ TEST_SET_BUT_UNUSED_VARIABLE(s)
}
diff --git a/test/evaluators.cpp b/test/evaluators.cpp
index 3081d7858..e3922c1be 100644
--- a/test/evaluators.cpp
+++ b/test/evaluators.cpp
@@ -29,25 +29,27 @@ void test_evaluators()
VERIFY_IS_APPROX(w,v_const.transpose().eval());
// Testing Array evaluator
- ArrayXXf a(2,3);
- ArrayXXf b(3,2);
- a << 1,2,3, 4,5,6;
- const ArrayXXf a_const(a);
+ {
+ ArrayXXf a(2,3);
+ ArrayXXf b(3,2);
+ a << 1,2,3, 4,5,6;
+ const ArrayXXf a_const(a);
- VERIFY_IS_APPROX_EVALUATOR(b, a.transpose());
+ VERIFY_IS_APPROX_EVALUATOR(b, a.transpose());
- VERIFY_IS_APPROX_EVALUATOR(b, a_const.transpose());
+ VERIFY_IS_APPROX_EVALUATOR(b, a_const.transpose());
- // Testing CwiseNullaryOp evaluator
- copy_using_evaluator(w, RowVector2d::Random());
- VERIFY((w.array() >= -1).all() && (w.array() <= 1).all()); // not easy to test ...
+ // Testing CwiseNullaryOp evaluator
+ copy_using_evaluator(w, RowVector2d::Random());
+ VERIFY((w.array() >= -1).all() && (w.array() <= 1).all()); // not easy to test ...
- VERIFY_IS_APPROX_EVALUATOR(w, RowVector2d::Zero());
+ VERIFY_IS_APPROX_EVALUATOR(w, RowVector2d::Zero());
- VERIFY_IS_APPROX_EVALUATOR(w, RowVector2d::Constant(3));
-
- // mix CwiseNullaryOp and transpose
- VERIFY_IS_APPROX_EVALUATOR(w, Vector2d::Zero().transpose());
+ VERIFY_IS_APPROX_EVALUATOR(w, RowVector2d::Constant(3));
+
+ // mix CwiseNullaryOp and transpose
+ VERIFY_IS_APPROX_EVALUATOR(w, Vector2d::Zero().transpose());
+ }
{
// test product expressions
@@ -114,164 +116,171 @@ void test_evaluators()
VERIFY_IS_APPROX_EVALUATOR2(resXX, prod(mXX,mXX), mXX*mXX);
}
- // this does not work because Random is eval-before-nested:
- // copy_using_evaluator(w, Vector2d::Random().transpose());
-
- // test CwiseUnaryOp
- VERIFY_IS_APPROX_EVALUATOR(v2, 3 * v);
- VERIFY_IS_APPROX_EVALUATOR(w, (3 * v).transpose());
- VERIFY_IS_APPROX_EVALUATOR(b, (a + 3).transpose());
- VERIFY_IS_APPROX_EVALUATOR(b, (2 * a_const + 3).transpose());
-
- // test CwiseBinaryOp
- VERIFY_IS_APPROX_EVALUATOR(v2, v + Vector2d::Ones());
- VERIFY_IS_APPROX_EVALUATOR(w, (v + Vector2d::Ones()).transpose().cwiseProduct(RowVector2d::Constant(3)));
-
- // dynamic matrices and arrays
- MatrixXd mat1(6,6), mat2(6,6);
- VERIFY_IS_APPROX_EVALUATOR(mat1, MatrixXd::Identity(6,6));
- VERIFY_IS_APPROX_EVALUATOR(mat2, mat1);
- copy_using_evaluator(mat2.transpose(), mat1);
- VERIFY_IS_APPROX(mat2.transpose(), mat1);
-
- ArrayXXd arr1(6,6), arr2(6,6);
- VERIFY_IS_APPROX_EVALUATOR(arr1, ArrayXXd::Constant(6,6, 3.0));
- VERIFY_IS_APPROX_EVALUATOR(arr2, arr1);
-
- // test automatic resizing
- mat2.resize(3,3);
- VERIFY_IS_APPROX_EVALUATOR(mat2, mat1);
- arr2.resize(9,9);
- VERIFY_IS_APPROX_EVALUATOR(arr2, arr1);
-
- // test direct traversal
- Matrix3f m3;
- Array33f a3;
- VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Identity()); // matrix, nullary
- // TODO: find a way to test direct traversal with array
- VERIFY_IS_APPROX_EVALUATOR(m3.transpose(), Matrix3f::Identity().transpose()); // transpose
- VERIFY_IS_APPROX_EVALUATOR(m3, 2 * Matrix3f::Identity()); // unary
- VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Identity() + Matrix3f::Zero()); // binary
- VERIFY_IS_APPROX_EVALUATOR(m3.block(0,0,2,2), Matrix3f::Identity().block(1,1,2,2)); // block
-
- // test linear traversal
- VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Zero()); // matrix, nullary
- VERIFY_IS_APPROX_EVALUATOR(a3, Array33f::Zero()); // array
- VERIFY_IS_APPROX_EVALUATOR(m3.transpose(), Matrix3f::Zero().transpose()); // transpose
- VERIFY_IS_APPROX_EVALUATOR(m3, 2 * Matrix3f::Zero()); // unary
- VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Zero() + m3); // binary
-
- // test inner vectorization
- Matrix4f m4, m4src = Matrix4f::Random();
- Array44f a4, a4src = Matrix4f::Random();
- VERIFY_IS_APPROX_EVALUATOR(m4, m4src); // matrix
- VERIFY_IS_APPROX_EVALUATOR(a4, a4src); // array
- VERIFY_IS_APPROX_EVALUATOR(m4.transpose(), m4src.transpose()); // transpose
- // TODO: find out why Matrix4f::Zero() does not allow inner vectorization
- VERIFY_IS_APPROX_EVALUATOR(m4, 2 * m4src); // unary
- VERIFY_IS_APPROX_EVALUATOR(m4, m4src + m4src); // binary
-
- // test linear vectorization
- MatrixXf mX(6,6), mXsrc = MatrixXf::Random(6,6);
- ArrayXXf aX(6,6), aXsrc = ArrayXXf::Random(6,6);
- VERIFY_IS_APPROX_EVALUATOR(mX, mXsrc); // matrix
- VERIFY_IS_APPROX_EVALUATOR(aX, aXsrc); // array
- VERIFY_IS_APPROX_EVALUATOR(mX.transpose(), mXsrc.transpose()); // transpose
- VERIFY_IS_APPROX_EVALUATOR(mX, MatrixXf::Zero(6,6)); // nullary
- VERIFY_IS_APPROX_EVALUATOR(mX, 2 * mXsrc); // unary
- VERIFY_IS_APPROX_EVALUATOR(mX, mXsrc + mXsrc); // binary
-
- // test blocks and slice vectorization
- VERIFY_IS_APPROX_EVALUATOR(m4, (mXsrc.block<4,4>(1,0)));
- VERIFY_IS_APPROX_EVALUATOR(aX, ArrayXXf::Constant(10, 10, 3.0).block(2, 3, 6, 6));
-
- Matrix4f m4ref = m4;
- copy_using_evaluator(m4.block(1, 1, 2, 3), m3.bottomRows(2));
- m4ref.block(1, 1, 2, 3) = m3.bottomRows(2);
- VERIFY_IS_APPROX(m4, m4ref);
-
- mX.setIdentity(20,20);
- MatrixXf mXref = MatrixXf::Identity(20,20);
- mXsrc = MatrixXf::Random(9,12);
- copy_using_evaluator(mX.block(4, 4, 9, 12), mXsrc);
- mXref.block(4, 4, 9, 12) = mXsrc;
- VERIFY_IS_APPROX(mX, mXref);
-
- // test Map
- const float raw[3] = {1,2,3};
- float buffer[3] = {0,0,0};
- Vector3f v3;
- Array3f a3f;
- VERIFY_IS_APPROX_EVALUATOR(v3, Map<const Vector3f>(raw));
- VERIFY_IS_APPROX_EVALUATOR(a3f, Map<const Array3f>(raw));
- Vector3f::Map(buffer) = 2*v3;
- VERIFY(buffer[0] == 2);
- VERIFY(buffer[1] == 4);
- VERIFY(buffer[2] == 6);
-
- // test CwiseUnaryView
- mat1.setRandom();
- mat2.setIdentity();
- MatrixXcd matXcd(6,6), matXcd_ref(6,6);
- copy_using_evaluator(matXcd.real(), mat1);
- copy_using_evaluator(matXcd.imag(), mat2);
- matXcd_ref.real() = mat1;
- matXcd_ref.imag() = mat2;
- VERIFY_IS_APPROX(matXcd, matXcd_ref);
-
- // test Select
- VERIFY_IS_APPROX_EVALUATOR(aX, (aXsrc > 0).select(aXsrc, -aXsrc));
-
- // test Replicate
- mXsrc = MatrixXf::Random(6, 6);
- VectorXf vX = VectorXf::Random(6);
- mX.resize(6, 6);
- VERIFY_IS_APPROX_EVALUATOR(mX, mXsrc.colwise() + vX);
- matXcd.resize(12, 12);
- VERIFY_IS_APPROX_EVALUATOR(matXcd, matXcd_ref.replicate(2,2));
- VERIFY_IS_APPROX_EVALUATOR(matXcd, (matXcd_ref.replicate<2,2>()));
-
- // test partial reductions
- VectorXd vec1(6);
- VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.rowwise().sum());
- VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.colwise().sum().transpose());
-
- // test MatrixWrapper and ArrayWrapper
- mat1.setRandom(6,6);
- arr1.setRandom(6,6);
- VERIFY_IS_APPROX_EVALUATOR(mat2, arr1.matrix());
- VERIFY_IS_APPROX_EVALUATOR(arr2, mat1.array());
- VERIFY_IS_APPROX_EVALUATOR(mat2, (arr1 + 2).matrix());
- VERIFY_IS_APPROX_EVALUATOR(arr2, mat1.array() + 2);
- mat2.array() = arr1 * arr1;
- VERIFY_IS_APPROX(mat2, (arr1 * arr1).matrix());
- arr2.matrix() = MatrixXd::Identity(6,6);
- VERIFY_IS_APPROX(arr2, MatrixXd::Identity(6,6).array());
-
- // test Reverse
- VERIFY_IS_APPROX_EVALUATOR(arr2, arr1.reverse());
- VERIFY_IS_APPROX_EVALUATOR(arr2, arr1.colwise().reverse());
- VERIFY_IS_APPROX_EVALUATOR(arr2, arr1.rowwise().reverse());
- arr2.reverse() = arr1;
- VERIFY_IS_APPROX(arr2, arr1.reverse());
- mat2.array() = mat1.array().reverse();
- VERIFY_IS_APPROX(mat2.array(), mat1.array().reverse());
-
- // test Diagonal
- VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.diagonal());
- vec1.resize(5);
- VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.diagonal(1));
- VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.diagonal<-1>());
- vec1.setRandom();
-
- mat2 = mat1;
- copy_using_evaluator(mat1.diagonal(1), vec1);
- mat2.diagonal(1) = vec1;
- VERIFY_IS_APPROX(mat1, mat2);
-
- copy_using_evaluator(mat1.diagonal<-1>(), mat1.diagonal(1));
- mat2.diagonal<-1>() = mat2.diagonal(1);
- VERIFY_IS_APPROX(mat1, mat2);
+ {
+ ArrayXXf a(2,3);
+ ArrayXXf b(3,2);
+ a << 1,2,3, 4,5,6;
+ const ArrayXXf a_const(a);
+
+ // this does not work because Random is eval-before-nested:
+ // copy_using_evaluator(w, Vector2d::Random().transpose());
+
+ // test CwiseUnaryOp
+ VERIFY_IS_APPROX_EVALUATOR(v2, 3 * v);
+ VERIFY_IS_APPROX_EVALUATOR(w, (3 * v).transpose());
+ VERIFY_IS_APPROX_EVALUATOR(b, (a + 3).transpose());
+ VERIFY_IS_APPROX_EVALUATOR(b, (2 * a_const + 3).transpose());
+
+ // test CwiseBinaryOp
+ VERIFY_IS_APPROX_EVALUATOR(v2, v + Vector2d::Ones());
+ VERIFY_IS_APPROX_EVALUATOR(w, (v + Vector2d::Ones()).transpose().cwiseProduct(RowVector2d::Constant(3)));
+
+ // dynamic matrices and arrays
+ MatrixXd mat1(6,6), mat2(6,6);
+ VERIFY_IS_APPROX_EVALUATOR(mat1, MatrixXd::Identity(6,6));
+ VERIFY_IS_APPROX_EVALUATOR(mat2, mat1);
+ copy_using_evaluator(mat2.transpose(), mat1);
+ VERIFY_IS_APPROX(mat2.transpose(), mat1);
+
+ ArrayXXd arr1(6,6), arr2(6,6);
+ VERIFY_IS_APPROX_EVALUATOR(arr1, ArrayXXd::Constant(6,6, 3.0));
+ VERIFY_IS_APPROX_EVALUATOR(arr2, arr1);
+
+ // test automatic resizing
+ mat2.resize(3,3);
+ VERIFY_IS_APPROX_EVALUATOR(mat2, mat1);
+ arr2.resize(9,9);
+ VERIFY_IS_APPROX_EVALUATOR(arr2, arr1);
+
+ // test direct traversal
+ Matrix3f m3;
+ Array33f a3;
+ VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Identity()); // matrix, nullary
+ // TODO: find a way to test direct traversal with array
+ VERIFY_IS_APPROX_EVALUATOR(m3.transpose(), Matrix3f::Identity().transpose()); // transpose
+ VERIFY_IS_APPROX_EVALUATOR(m3, 2 * Matrix3f::Identity()); // unary
+ VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Identity() + Matrix3f::Zero()); // binary
+ VERIFY_IS_APPROX_EVALUATOR(m3.block(0,0,2,2), Matrix3f::Identity().block(1,1,2,2)); // block
+
+ // test linear traversal
+ VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Zero()); // matrix, nullary
+ VERIFY_IS_APPROX_EVALUATOR(a3, Array33f::Zero()); // array
+ VERIFY_IS_APPROX_EVALUATOR(m3.transpose(), Matrix3f::Zero().transpose()); // transpose
+ VERIFY_IS_APPROX_EVALUATOR(m3, 2 * Matrix3f::Zero()); // unary
+ VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Zero() + m3); // binary
+
+ // test inner vectorization
+ Matrix4f m4, m4src = Matrix4f::Random();
+ Array44f a4, a4src = Matrix4f::Random();
+ VERIFY_IS_APPROX_EVALUATOR(m4, m4src); // matrix
+ VERIFY_IS_APPROX_EVALUATOR(a4, a4src); // array
+ VERIFY_IS_APPROX_EVALUATOR(m4.transpose(), m4src.transpose()); // transpose
+ // TODO: find out why Matrix4f::Zero() does not allow inner vectorization
+ VERIFY_IS_APPROX_EVALUATOR(m4, 2 * m4src); // unary
+ VERIFY_IS_APPROX_EVALUATOR(m4, m4src + m4src); // binary
+
+ // test linear vectorization
+ MatrixXf mX(6,6), mXsrc = MatrixXf::Random(6,6);
+ ArrayXXf aX(6,6), aXsrc = ArrayXXf::Random(6,6);
+ VERIFY_IS_APPROX_EVALUATOR(mX, mXsrc); // matrix
+ VERIFY_IS_APPROX_EVALUATOR(aX, aXsrc); // array
+ VERIFY_IS_APPROX_EVALUATOR(mX.transpose(), mXsrc.transpose()); // transpose
+ VERIFY_IS_APPROX_EVALUATOR(mX, MatrixXf::Zero(6,6)); // nullary
+ VERIFY_IS_APPROX_EVALUATOR(mX, 2 * mXsrc); // unary
+ VERIFY_IS_APPROX_EVALUATOR(mX, mXsrc + mXsrc); // binary
+
+ // test blocks and slice vectorization
+ VERIFY_IS_APPROX_EVALUATOR(m4, (mXsrc.block<4,4>(1,0)));
+ VERIFY_IS_APPROX_EVALUATOR(aX, ArrayXXf::Constant(10, 10, 3.0).block(2, 3, 6, 6));
+
+ Matrix4f m4ref = m4;
+ copy_using_evaluator(m4.block(1, 1, 2, 3), m3.bottomRows(2));
+ m4ref.block(1, 1, 2, 3) = m3.bottomRows(2);
+ VERIFY_IS_APPROX(m4, m4ref);
+
+ mX.setIdentity(20,20);
+ MatrixXf mXref = MatrixXf::Identity(20,20);
+ mXsrc = MatrixXf::Random(9,12);
+ copy_using_evaluator(mX.block(4, 4, 9, 12), mXsrc);
+ mXref.block(4, 4, 9, 12) = mXsrc;
+ VERIFY_IS_APPROX(mX, mXref);
+
+ // test Map
+ const float raw[3] = {1,2,3};
+ float buffer[3] = {0,0,0};
+ Vector3f v3;
+ Array3f a3f;
+ VERIFY_IS_APPROX_EVALUATOR(v3, Map<const Vector3f>(raw));
+ VERIFY_IS_APPROX_EVALUATOR(a3f, Map<const Array3f>(raw));
+ Vector3f::Map(buffer) = 2*v3;
+ VERIFY(buffer[0] == 2);
+ VERIFY(buffer[1] == 4);
+ VERIFY(buffer[2] == 6);
+
+ // test CwiseUnaryView
+ mat1.setRandom();
+ mat2.setIdentity();
+ MatrixXcd matXcd(6,6), matXcd_ref(6,6);
+ copy_using_evaluator(matXcd.real(), mat1);
+ copy_using_evaluator(matXcd.imag(), mat2);
+ matXcd_ref.real() = mat1;
+ matXcd_ref.imag() = mat2;
+ VERIFY_IS_APPROX(matXcd, matXcd_ref);
+
+ // test Select
+ VERIFY_IS_APPROX_EVALUATOR(aX, (aXsrc > 0).select(aXsrc, -aXsrc));
+
+ // test Replicate
+ mXsrc = MatrixXf::Random(6, 6);
+ VectorXf vX = VectorXf::Random(6);
+ mX.resize(6, 6);
+ VERIFY_IS_APPROX_EVALUATOR(mX, mXsrc.colwise() + vX);
+ matXcd.resize(12, 12);
+ VERIFY_IS_APPROX_EVALUATOR(matXcd, matXcd_ref.replicate(2,2));
+ VERIFY_IS_APPROX_EVALUATOR(matXcd, (matXcd_ref.replicate<2,2>()));
+
+ // test partial reductions
+ VectorXd vec1(6);
+ VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.rowwise().sum());
+ VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.colwise().sum().transpose());
+
+ // test MatrixWrapper and ArrayWrapper
+ mat1.setRandom(6,6);
+ arr1.setRandom(6,6);
+ VERIFY_IS_APPROX_EVALUATOR(mat2, arr1.matrix());
+ VERIFY_IS_APPROX_EVALUATOR(arr2, mat1.array());
+ VERIFY_IS_APPROX_EVALUATOR(mat2, (arr1 + 2).matrix());
+ VERIFY_IS_APPROX_EVALUATOR(arr2, mat1.array() + 2);
+ mat2.array() = arr1 * arr1;
+ VERIFY_IS_APPROX(mat2, (arr1 * arr1).matrix());
+ arr2.matrix() = MatrixXd::Identity(6,6);
+ VERIFY_IS_APPROX(arr2, MatrixXd::Identity(6,6).array());
+
+ // test Reverse
+ VERIFY_IS_APPROX_EVALUATOR(arr2, arr1.reverse());
+ VERIFY_IS_APPROX_EVALUATOR(arr2, arr1.colwise().reverse());
+ VERIFY_IS_APPROX_EVALUATOR(arr2, arr1.rowwise().reverse());
+ arr2.reverse() = arr1;
+ VERIFY_IS_APPROX(arr2, arr1.reverse());
+ mat2.array() = mat1.array().reverse();
+ VERIFY_IS_APPROX(mat2.array(), mat1.array().reverse());
+
+ // test Diagonal
+ VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.diagonal());
+ vec1.resize(5);
+ VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.diagonal(1));
+ VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.diagonal<-1>());
+ vec1.setRandom();
+
+ mat2 = mat1;
+ copy_using_evaluator(mat1.diagonal(1), vec1);
+ mat2.diagonal(1) = vec1;
+ VERIFY_IS_APPROX(mat1, mat2);
+
+ copy_using_evaluator(mat1.diagonal<-1>(), mat1.diagonal(1));
+ mat2.diagonal<-1>() = mat2.diagonal(1);
+ VERIFY_IS_APPROX(mat1, mat2);
+ }
{
// test swapping
diff --git a/test/geo_alignedbox.cpp b/test/geo_alignedbox.cpp
index e9fbfddf1..8e36adbe3 100644
--- a/test/geo_alignedbox.cpp
+++ b/test/geo_alignedbox.cpp
@@ -15,6 +15,10 @@
#include<iostream>
using namespace std;
+template<typename T> EIGEN_DONT_INLINE
+void kill_extra_precision(T& x) { eigen_assert(&x != 0); }
+
+
template<typename BoxType> void alignedbox(const BoxType& _box)
{
/* this test covers the following files:
@@ -36,6 +40,10 @@ template<typename BoxType> void alignedbox(const BoxType& _box)
BoxType b0(dim);
BoxType b1(VectorType::Random(dim),VectorType::Random(dim));
BoxType b2;
+
+ kill_extra_precision(b1);
+ kill_extra_precision(p0);
+ kill_extra_precision(p1);
b0.extend(p0);
b0.extend(p1);
diff --git a/test/geo_eulerangles.cpp b/test/geo_eulerangles.cpp
index 9bf149d2a..5445cd81a 100644
--- a/test/geo_eulerangles.cpp
+++ b/test/geo_eulerangles.cpp
@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
-// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2008-2012 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
@@ -12,22 +12,21 @@
#include <Eigen/LU>
#include <Eigen/SVD>
-template<typename Scalar> void eulerangles(void)
+template<typename Scalar> void check_all_var(const Matrix<Scalar,3,1>& ea)
{
typedef Matrix<Scalar,3,3> Matrix3;
typedef Matrix<Scalar,3,1> Vector3;
- typedef Quaternion<Scalar> Quaternionx;
typedef AngleAxis<Scalar> AngleAxisx;
-
- Scalar a = internal::random<Scalar>(-Scalar(M_PI), Scalar(M_PI));
- Quaternionx q1;
- q1 = AngleAxisx(a, Vector3::Random().normalized());
- Matrix3 m;
- m = q1;
-
+ using std::abs;
+
#define VERIFY_EULER(I,J,K, X,Y,Z) { \
- Vector3 ea = m.eulerAngles(I,J,K); \
- VERIFY_IS_APPROX(m, Matrix3(AngleAxisx(ea[0], Vector3::Unit##X()) * AngleAxisx(ea[1], Vector3::Unit##Y()) * AngleAxisx(ea[2], Vector3::Unit##Z()))); \
+ Matrix3 m(AngleAxisx(ea[0], Vector3::Unit##X()) * AngleAxisx(ea[1], Vector3::Unit##Y()) * AngleAxisx(ea[2], Vector3::Unit##Z())); \
+ Vector3 eabis = m.eulerAngles(I,J,K); \
+ Matrix3 mbis(AngleAxisx(eabis[0], Vector3::Unit##X()) * AngleAxisx(eabis[1], Vector3::Unit##Y()) * AngleAxisx(eabis[2], Vector3::Unit##Z())); \
+ VERIFY_IS_APPROX(m, mbis); \
+ /* If I==K, and ea[1]==0, then there no unique solution. */ \
+ /* The remark apply in the case where I!=K, and |ea[1]| is close to pi/2. */ \
+ if( (I!=K || ea[1]!=0) && (I==K || !internal::isApprox(abs(ea[1]),Scalar(M_PI/2),test_precision<Scalar>())) ) VERIFY((ea-eabis).norm() <= test_precision<Scalar>()); \
}
VERIFY_EULER(0,1,2, X,Y,Z);
VERIFY_EULER(0,1,0, X,Y,X);
@@ -45,6 +44,44 @@ template<typename Scalar> void eulerangles(void)
VERIFY_EULER(2,1,2, Z,Y,Z);
}
+template<typename Scalar> void eulerangles()
+{
+ typedef Matrix<Scalar,3,3> Matrix3;
+ typedef Matrix<Scalar,3,1> Vector3;
+ typedef Array<Scalar,3,1> Array3;
+ typedef Quaternion<Scalar> Quaternionx;
+ typedef AngleAxis<Scalar> AngleAxisx;
+
+ Scalar a = internal::random<Scalar>(-Scalar(M_PI), Scalar(M_PI));
+ Quaternionx q1;
+ q1 = AngleAxisx(a, Vector3::Random().normalized());
+ Matrix3 m;
+ m = q1;
+
+ Vector3 ea = m.eulerAngles(0,1,2);
+ check_all_var(ea);
+ ea = m.eulerAngles(0,1,0);
+ check_all_var(ea);
+
+ ea = (Array3::Random() + Array3(1,1,0))*Scalar(M_PI)*Array3(0.5,0.5,1);
+ check_all_var(ea);
+
+ ea[2] = ea[0] = internal::random<Scalar>(0,Scalar(M_PI));
+ check_all_var(ea);
+
+ ea[0] = ea[1] = internal::random<Scalar>(0,Scalar(M_PI));
+ check_all_var(ea);
+
+ ea[1] = 0;
+ check_all_var(ea);
+
+ ea.head(2).setZero();
+ check_all_var(ea);
+
+ ea.setZero();
+ check_all_var(ea);
+}
+
void test_geo_eulerangles()
{
for(int i = 0; i < g_repeat; i++) {
diff --git a/test/geo_quaternion.cpp b/test/geo_quaternion.cpp
index 06b3af7c1..1694b32c7 100644
--- a/test/geo_quaternion.cpp
+++ b/test/geo_quaternion.cpp
@@ -31,14 +31,14 @@ template<typename QuatType> void check_slerp(const QuatType& q0, const QuatType&
Scalar theta_tot = AA(q1*q0.inverse()).angle();
if(theta_tot>M_PI)
- theta_tot = 2.*M_PI-theta_tot;
- for(Scalar t=0; t<=1.001; t+=0.1)
+ theta_tot = Scalar(2.*M_PI)-theta_tot;
+ for(Scalar t=0; t<=Scalar(1.001); t+=Scalar(0.1))
{
QuatType q = q0.slerp(t,q1);
Scalar theta = AA(q*q0.inverse()).angle();
VERIFY(abs(q.norm() - 1) < largeEps);
if(theta_tot==0) VERIFY(theta_tot==0);
- else VERIFY(abs(theta/theta_tot - t) < largeEps);
+ else VERIFY(abs(theta - t * theta_tot) < largeEps);
}
}
@@ -156,7 +156,7 @@ template<typename Scalar, int Options> void quaternion(void)
check_slerp(q1,q2);
q1 = AngleAxisx(b, v1.normalized());
- q2 = AngleAxisx(b+M_PI, v1.normalized());
+ q2 = AngleAxisx(b+Scalar(M_PI), v1.normalized());
check_slerp(q1,q2);
q1 = AngleAxisx(b, v1.normalized());
diff --git a/test/householder.cpp b/test/householder.cpp
index 1dac4331f..c5f6b5e4f 100644
--- a/test/householder.cpp
+++ b/test/householder.cpp
@@ -60,8 +60,8 @@ template<typename MatrixType> void householder(const MatrixType& m)
m1.applyHouseholderOnTheLeft(essential,beta,tmp);
VERIFY_IS_APPROX(m1.norm(), m2.norm());
if(rows>=2) VERIFY_IS_MUCH_SMALLER_THAN(m1.block(1,0,rows-1,cols).norm(), m1.norm());
- VERIFY_IS_MUCH_SMALLER_THAN(internal::imag(m1(0,0)), internal::real(m1(0,0)));
- VERIFY_IS_APPROX(internal::real(m1(0,0)), alpha);
+ VERIFY_IS_MUCH_SMALLER_THAN(numext::imag(m1(0,0)), numext::real(m1(0,0)));
+ VERIFY_IS_APPROX(numext::real(m1(0,0)), alpha);
v1 = VectorType::Random(rows);
if(even) v1.tail(rows-1).setZero();
@@ -72,8 +72,8 @@ template<typename MatrixType> void householder(const MatrixType& m)
m3.applyHouseholderOnTheRight(essential,beta,tmp);
VERIFY_IS_APPROX(m3.norm(), m4.norm());
if(rows>=2) VERIFY_IS_MUCH_SMALLER_THAN(m3.block(0,1,rows,rows-1).norm(), m3.norm());
- VERIFY_IS_MUCH_SMALLER_THAN(internal::imag(m3(0,0)), internal::real(m3(0,0)));
- VERIFY_IS_APPROX(internal::real(m3(0,0)), alpha);
+ VERIFY_IS_MUCH_SMALLER_THAN(numext::imag(m3(0,0)), numext::real(m3(0,0)));
+ VERIFY_IS_APPROX(numext::real(m3(0,0)), alpha);
// test householder sequence on the left with a shift
@@ -89,12 +89,29 @@ template<typename MatrixType> void householder(const MatrixType& m)
hseq.setLength(hc.size()).setShift(shift);
VERIFY(hseq.length() == hc.size());
VERIFY(hseq.shift() == shift);
-
+
MatrixType m5 = m2;
m5.block(shift,0,brows,cols).template triangularView<StrictlyLower>().setZero();
VERIFY_IS_APPROX(hseq * m5, m1); // test applying hseq directly
m3 = hseq;
VERIFY_IS_APPROX(m3 * m5, m1); // test evaluating hseq to a dense matrix, then applying
+
+ SquareMatrixType hseq_mat = hseq;
+ SquareMatrixType hseq_mat_conj = hseq.conjugate();
+ SquareMatrixType hseq_mat_adj = hseq.adjoint();
+ SquareMatrixType hseq_mat_trans = hseq.transpose();
+ SquareMatrixType m6 = SquareMatrixType::Random(rows, rows);
+ VERIFY_IS_APPROX(hseq_mat.adjoint(), hseq_mat_adj);
+ VERIFY_IS_APPROX(hseq_mat.conjugate(), hseq_mat_conj);
+ VERIFY_IS_APPROX(hseq_mat.transpose(), hseq_mat_trans);
+ VERIFY_IS_APPROX(hseq_mat * m6, hseq_mat * m6);
+ VERIFY_IS_APPROX(hseq_mat.adjoint() * m6, hseq_mat_adj * m6);
+ VERIFY_IS_APPROX(hseq_mat.conjugate() * m6, hseq_mat_conj * m6);
+ VERIFY_IS_APPROX(hseq_mat.transpose() * m6, hseq_mat_trans * m6);
+ VERIFY_IS_APPROX(m6 * hseq_mat, m6 * hseq_mat);
+ VERIFY_IS_APPROX(m6 * hseq_mat.adjoint(), m6 * hseq_mat_adj);
+ VERIFY_IS_APPROX(m6 * hseq_mat.conjugate(), m6 * hseq_mat_conj);
+ VERIFY_IS_APPROX(m6 * hseq_mat.transpose(), m6 * hseq_mat_trans);
// test householder sequence on the right with a shift
diff --git a/test/inverse.cpp b/test/inverse.cpp
index 8978a1877..8187b088d 100644
--- a/test/inverse.cpp
+++ b/test/inverse.cpp
@@ -86,19 +86,19 @@ template<typename MatrixType> void inverse(const MatrixType& m)
void test_inverse()
{
- int s;
+ int s = 0;
for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST_1( inverse(Matrix<double,1,1>()) );
CALL_SUBTEST_2( inverse(Matrix2d()) );
CALL_SUBTEST_3( inverse(Matrix3f()) );
CALL_SUBTEST_4( inverse(Matrix4f()) );
CALL_SUBTEST_4( inverse(Matrix<float,4,4,DontAlign>()) );
- s = internal::random<int>(50,320);
+ s = internal::random<int>(50,320);
CALL_SUBTEST_5( inverse(MatrixXf(s,s)) );
s = internal::random<int>(25,100);
CALL_SUBTEST_6( inverse(MatrixXcd(s,s)) );
CALL_SUBTEST_7( inverse(Matrix4d()) );
CALL_SUBTEST_7( inverse(Matrix<double,4,4,DontAlign>()) );
}
- EIGEN_UNUSED_VARIABLE(s)
+ TEST_SET_BUT_UNUSED_VARIABLE(s)
}
diff --git a/test/jacobi.cpp b/test/jacobi.cpp
index b123b9189..7ccd4124b 100644
--- a/test/jacobi.cpp
+++ b/test/jacobi.cpp
@@ -40,8 +40,8 @@ void jacobi(const MatrixType& m = MatrixType())
MatrixType b = a;
b.applyOnTheLeft(p, q, rot);
- VERIFY_IS_APPROX(b.row(p), c * a.row(p) + internal::conj(s) * a.row(q));
- VERIFY_IS_APPROX(b.row(q), -s * a.row(p) + internal::conj(c) * a.row(q));
+ VERIFY_IS_APPROX(b.row(p), c * a.row(p) + numext::conj(s) * a.row(q));
+ VERIFY_IS_APPROX(b.row(q), -s * a.row(p) + numext::conj(c) * a.row(q));
}
{
@@ -54,7 +54,7 @@ void jacobi(const MatrixType& m = MatrixType())
MatrixType b = a;
b.applyOnTheRight(p, q, rot);
VERIFY_IS_APPROX(b.col(p), c * a.col(p) - s * a.col(q));
- VERIFY_IS_APPROX(b.col(q), internal::conj(s) * a.col(p) + internal::conj(c) * a.col(q));
+ VERIFY_IS_APPROX(b.col(q), numext::conj(s) * a.col(p) + numext::conj(c) * a.col(q));
}
}
@@ -74,7 +74,8 @@ void test_jacobi()
// complex<float> is really important to test as it is the only way to cover conjugation issues in certain unaligned paths
CALL_SUBTEST_6(( jacobi<MatrixXcf, float>(MatrixXcf(r,c)) ));
CALL_SUBTEST_6(( jacobi<MatrixXcf, std::complex<float> >(MatrixXcf(r,c)) ));
- (void) r;
- (void) c;
+
+ TEST_SET_BUT_UNUSED_VARIABLE(r);
+ TEST_SET_BUT_UNUSED_VARIABLE(c);
}
}
diff --git a/test/jacobisvd.cpp b/test/jacobisvd.cpp
index 26da05037..76157c30f 100644
--- a/test/jacobisvd.cpp
+++ b/test/jacobisvd.cpp
@@ -96,6 +96,10 @@ void jacobisvd_test_all_computation_options(const MatrixType& m)
jacobisvd_check_full(m, fullSvd);
jacobisvd_solve<MatrixType, QRPreconditioner>(m, ComputeFullU | ComputeFullV);
+ #if defined __INTEL_COMPILER
+ // remark #111: statement is unreachable
+ #pragma warning disable 111
+ #endif
if(QRPreconditioner == FullPivHouseholderQRPreconditioner)
return;
@@ -257,7 +261,7 @@ void jacobisvd_preallocate()
MatrixXf m = v.asDiagonal();
internal::set_is_malloc_allowed(false);
- VERIFY_RAISES_ASSERT(VectorXf v(10);)
+ VERIFY_RAISES_ASSERT(VectorXf tmp(10);)
JacobiSVD<MatrixXf> svd;
internal::set_is_malloc_allowed(true);
svd.compute(m);
@@ -320,6 +324,10 @@ void test_jacobisvd()
int r = internal::random<int>(1, 30),
c = internal::random<int>(1, 30);
+
+ TEST_SET_BUT_UNUSED_VARIABLE(r)
+ TEST_SET_BUT_UNUSED_VARIABLE(c)
+
CALL_SUBTEST_7(( jacobisvd<MatrixXf>(MatrixXf(r,c)) ));
CALL_SUBTEST_8(( jacobisvd<MatrixXcd>(MatrixXcd(r,c)) ));
(void) r;
diff --git a/test/main.h b/test/main.h
index 3be0f9fca..14f0d2f78 100644
--- a/test/main.h
+++ b/test/main.h
@@ -31,6 +31,10 @@
// B0 is defined in POSIX header termios.h
#define B0 FORBIDDEN_IDENTIFIER
+
+// shuts down ICC's remark #593: variable "XXX" was set but never used
+#define TEST_SET_BUT_UNUSED_VARIABLE(X) X = X + 0;
+
// the following file is automatically generated by cmake
#include "split_test_helper.h"
@@ -38,6 +42,11 @@
#undef NDEBUG
#endif
+// On windows CE, NDEBUG is automatically defined <assert.h> if NDEBUG is not defined.
+#ifndef DEBUG
+#define DEBUG
+#endif
+
// bounds integer values for AltiVec
#ifdef __ALTIVEC__
#define EIGEN_MAKING_DOCS
@@ -49,11 +58,6 @@
#define DEFAULT_REPEAT 10
-#ifdef __ICC
-// disable warning #279: controlling expression is constant
-#pragma warning disable 279
-#endif
-
namespace Eigen
{
static std::vector<std::string> g_test_stack;
@@ -170,7 +174,7 @@ namespace Eigen
#define EIGEN_INTERNAL_DEBUGGING
#include <Eigen/QR> // required for createRandomPIMatrixOfRank
-static void verify_impl(bool condition, const char *testname, const char *file, int line, const char *condition_as_string)
+inline void verify_impl(bool condition, const char *testname, const char *file, int line, const char *condition_as_string)
{
if (!condition)
{
@@ -266,6 +270,7 @@ inline bool test_isApprox(const Type1& a, const Type2& b)
// The idea behind this function is to compare the two scalars a and b where
// the scalar ref is a hint about the expected order of magnitude of a and b.
+// WARNING: the scalar a and b must be positive
// Therefore, if for some reason a and b are very small compared to ref,
// we won't issue a false negative.
// This test could be: abs(a-b) <= eps * ref
@@ -296,6 +301,10 @@ inline bool test_isUnitary(const MatrixBase<Derived>& m)
return m.isUnitary(test_precision<typename internal::traits<Derived>::Scalar>());
}
+// Forward declaration to avoid ICC warning
+template<typename T, typename U>
+bool test_is_equal(const T& actual, const U& expected);
+
template<typename T, typename U>
bool test_is_equal(const T& actual, const U& expected)
{
@@ -313,6 +322,9 @@ bool test_is_equal(const T& actual, const U& expected)
* A partial isometry is a matrix all of whose singular values are either 0 or 1.
* This is very useful to test rank-revealing algorithms.
*/
+// Forward declaration to avoid ICC warning
+template<typename MatrixType>
+void createRandomPIMatrixOfRank(typename MatrixType::Index desired_rank, typename MatrixType::Index rows, typename MatrixType::Index cols, MatrixType& m);
template<typename MatrixType>
void createRandomPIMatrixOfRank(typename MatrixType::Index desired_rank, typename MatrixType::Index rows, typename MatrixType::Index cols, MatrixType& m)
{
@@ -351,6 +363,9 @@ void createRandomPIMatrixOfRank(typename MatrixType::Index desired_rank, typenam
m = qra.householderQ() * d * qrb.householderQ();
}
+// Forward declaration to avoid ICC warning
+template<typename PermutationVectorType>
+void randomPermutationVector(PermutationVectorType& v, typename PermutationVectorType::Index size);
template<typename PermutationVectorType>
void randomPermutationVector(PermutationVectorType& v, typename PermutationVectorType::Index size)
{
@@ -377,20 +392,22 @@ 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>"; }
+// Forward declaration to avoid ICC warning
+template<typename T> std::string type_name();
+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>"; }
+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)
+inline void set_repeat_from_string(const char *str)
{
errno = 0;
g_repeat = int(strtoul(str, 0, 10));
@@ -402,7 +419,7 @@ void set_repeat_from_string(const char *str)
g_has_set_repeat = true;
}
-void set_seed_from_string(const char *str)
+inline void set_seed_from_string(const char *str)
{
errno = 0;
g_seed = int(strtoul(str, 0, 10));
@@ -474,8 +491,19 @@ int main(int argc, char *argv[])
srand(g_seed);
std::cout << "Repeating each test " << g_repeat << " times" << std::endl;
- Eigen::g_test_stack.push_back(EI_PP_MAKE_STRING(EIGEN_TEST_FUNC));
+ Eigen::g_test_stack.push_back(std::string(EI_PP_MAKE_STRING(EIGEN_TEST_FUNC)));
EIGEN_CAT(test_,EIGEN_TEST_FUNC)();
return 0;
}
+
+// These warning are disabled here such that they are still ON when parsing Eigen's header files.
+#if defined __INTEL_COMPILER
+ // remark #383: value copied to temporary, reference to temporary used
+ // -> this warning is raised even for legal usage as: g_test_stack.push_back("foo"); where g_test_stack is a std::vector<std::string>
+ // remark #1418: external function definition with no prior declaration
+ // -> this warning is raised for all our test functions. Declaring them static would fix the issue.
+ // warning #279: controlling expression is constant
+ // remark #1572: floating-point equality and inequality comparisons are unreliable
+ #pragma warning disable 279 383 1418 1572
+#endif
diff --git a/test/map.cpp b/test/mapped_matrix.cpp
index 2b52e4f38..de9dbbde3 100644
--- a/test/map.cpp
+++ b/test/mapped_matrix.cpp
@@ -114,7 +114,7 @@ template<typename PlainObjectType> void check_const_correctness(const PlainObjec
VERIFY( !(Map<ConstPlainObjectType, Aligned>::Flags & LvalueBit) );
}
-void test_map()
+void test_mapped_matrix()
{
for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST_1( map_class_vector(Matrix<float, 1, 1>()) );
diff --git a/test/mapstride.cpp b/test/mapstride.cpp
index fe35b9d23..b1dc9de2a 100644
--- a/test/mapstride.cpp
+++ b/test/mapstride.cpp
@@ -116,7 +116,7 @@ template<int Alignment,typename MatrixType> void map_class_matrix(const MatrixTy
void test_mapstride()
{
for(int i = 0; i < g_repeat; i++) {
- EIGEN_UNUSED int maxn = 30;
+ int maxn = 30;
CALL_SUBTEST_1( map_class_vector<Aligned>(Matrix<float, 1, 1>()) );
CALL_SUBTEST_1( map_class_vector<Unaligned>(Matrix<float, 1, 1>()) );
CALL_SUBTEST_2( map_class_vector<Aligned>(Vector4d()) );
@@ -142,5 +142,7 @@ void test_mapstride()
CALL_SUBTEST_5( map_class_matrix<Unaligned>(MatrixXi(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
CALL_SUBTEST_6( map_class_matrix<Aligned>(MatrixXcd(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
CALL_SUBTEST_6( map_class_matrix<Unaligned>(MatrixXcd(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
+
+ TEST_SET_BUT_UNUSED_VARIABLE(maxn);
}
}
diff --git a/test/nesting_ops.cpp b/test/nesting_ops.cpp
index a92000f15..1e8523283 100644
--- a/test/nesting_ops.cpp
+++ b/test/nesting_ops.cpp
@@ -13,15 +13,8 @@ template <typename MatrixType> void run_nesting_ops(const MatrixType& _m)
{
typename MatrixType::Nested m(_m);
-#ifdef NDEBUG
- const bool is_debug = false;
-#else
- const bool is_debug = true;
-#endif
-
- // Make really sure that we are in debug mode! We don't want any type of
- // inlining for these tests to pass.
- VERIFY(is_debug);
+ // Make really sure that we are in debug mode!
+ VERIFY_RAISES_ASSERT(eigen_assert(false));
// The only intention of these tests is to ensure that this code does
// not trigger any asserts or segmentation faults... more to come.
diff --git a/test/packetmath.cpp b/test/packetmath.cpp
index 9cdebd376..2c0519c41 100644
--- a/test/packetmath.cpp
+++ b/test/packetmath.cpp
@@ -156,7 +156,7 @@ template<typename Scalar> void packetmath()
CHECK_CWISE2(REF_DIV, internal::pdiv);
#endif
CHECK_CWISE1(internal::negate, internal::pnegate);
- CHECK_CWISE1(internal::conj, internal::pconj);
+ CHECK_CWISE1(numext::conj, internal::pconj);
for(int offset=0;offset<3;++offset)
{
@@ -218,8 +218,8 @@ template<typename Scalar> void packetmath_real()
for (int i=0; i<size; ++i)
{
- data1[i] = internal::random<Scalar>(-1e3,1e3);
- data2[i] = internal::random<Scalar>(-1e3,1e3);
+ data1[i] = internal::random<Scalar>(-1,1) * std::pow(Scalar(10), internal::random<Scalar>(-3,3));
+ data2[i] = internal::random<Scalar>(-1,1) * std::pow(Scalar(10), internal::random<Scalar>(-3,3));
}
CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasSin, std::sin, internal::psin);
CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasCos, std::cos, internal::pcos);
@@ -242,8 +242,8 @@ template<typename Scalar> void packetmath_real()
for (int i=0; i<size; ++i)
{
- data1[i] = internal::random<Scalar>(0,1e6);
- data2[i] = internal::random<Scalar>(0,1e6);
+ data1[i] = internal::random<Scalar>(0,1) * std::pow(Scalar(10), internal::random<Scalar>(-6,6));
+ data2[i] = internal::random<Scalar>(0,1) * std::pow(Scalar(10), internal::random<Scalar>(-6,6));
}
if(internal::random<float>(0,1)<0.1)
data1[internal::random<int>(0, PacketSize)] = 0;
diff --git a/test/product_extra.cpp b/test/product_extra.cpp
index 53493bdd6..744a1ef7f 100644
--- a/test/product_extra.cpp
+++ b/test/product_extra.cpp
@@ -42,7 +42,7 @@ template<typename MatrixType> void product_extra(const MatrixType& m)
VERIFY_IS_APPROX(m3.noalias() = m1.adjoint() * square.adjoint(), m1.adjoint().eval() * square.adjoint().eval());
VERIFY_IS_APPROX(m3.noalias() = m1.adjoint() * m2, m1.adjoint().eval() * m2);
VERIFY_IS_APPROX(m3.noalias() = (s1 * m1.adjoint()) * m2, (s1 * m1.adjoint()).eval() * m2);
- VERIFY_IS_APPROX(m3.noalias() = ((s1 * m1).adjoint()) * m2, (internal::conj(s1) * m1.adjoint()).eval() * m2);
+ VERIFY_IS_APPROX(m3.noalias() = ((s1 * m1).adjoint()) * m2, (numext::conj(s1) * m1.adjoint()).eval() * m2);
VERIFY_IS_APPROX(m3.noalias() = (- m1.adjoint() * s1) * (s3 * m2), (- m1.adjoint() * s1).eval() * (s3 * m2).eval());
VERIFY_IS_APPROX(m3.noalias() = (s2 * m1.adjoint() * s1) * m2, (s2 * m1.adjoint() * s1).eval() * m2);
VERIFY_IS_APPROX(m3.noalias() = (-m1*s2) * s1*m2.adjoint(), (-m1*s2).eval() * (s1*m2.adjoint()).eval());
diff --git a/test/product_notemporary.cpp b/test/product_notemporary.cpp
index a30a8b4c7..258d238e2 100644
--- a/test/product_notemporary.cpp
+++ b/test/product_notemporary.cpp
@@ -9,7 +9,7 @@
static int nb_temporaries;
-void on_temporary_creation(int size) {
+inline void on_temporary_creation(int size) {
// here's a great place to set a breakpoint when debugging failures in this test!
if(size!=0) nb_temporaries++;
}
diff --git a/test/product_selfadjoint.cpp b/test/product_selfadjoint.cpp
index aede15053..374e2393b 100644
--- a/test/product_selfadjoint.cpp
+++ b/test/product_selfadjoint.cpp
@@ -44,11 +44,11 @@ template<typename MatrixType> void product_selfadjoint(const MatrixType& m)
m2 = m1.template triangularView<Upper>();
m2.template selfadjointView<Upper>().rankUpdate(-v1,s2*v2,s3);
- VERIFY_IS_APPROX(m2, (m1 + (s3*(-v1)*(s2*v2).adjoint()+internal::conj(s3)*(s2*v2)*(-v1).adjoint())).template triangularView<Upper>().toDenseMatrix());
+ VERIFY_IS_APPROX(m2, (m1 + (s3*(-v1)*(s2*v2).adjoint()+numext::conj(s3)*(s2*v2)*(-v1).adjoint())).template triangularView<Upper>().toDenseMatrix());
m2 = m1.template triangularView<Upper>();
m2.template selfadjointView<Upper>().rankUpdate(-s2*r1.adjoint(),r2.adjoint()*s3,s1);
- VERIFY_IS_APPROX(m2, (m1 + s1*(-s2*r1.adjoint())*(r2.adjoint()*s3).adjoint() + internal::conj(s1)*(r2.adjoint()*s3) * (-s2*r1.adjoint()).adjoint()).template triangularView<Upper>().toDenseMatrix());
+ VERIFY_IS_APPROX(m2, (m1 + s1*(-s2*r1.adjoint())*(r2.adjoint()*s3).adjoint() + numext::conj(s1)*(r2.adjoint()*s3) * (-s2*r1.adjoint()).adjoint()).template triangularView<Upper>().toDenseMatrix());
if (rows>1)
{
@@ -62,7 +62,7 @@ template<typename MatrixType> void product_selfadjoint(const MatrixType& m)
void test_product_selfadjoint()
{
- int s;
+ int s = 0;
for(int i = 0; i < g_repeat ; i++) {
CALL_SUBTEST_1( product_selfadjoint(Matrix<float, 1, 1>()) );
CALL_SUBTEST_2( product_selfadjoint(Matrix<float, 2, 2>()) );
@@ -76,5 +76,5 @@ void test_product_selfadjoint()
s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);
CALL_SUBTEST_7( product_selfadjoint(Matrix<float,Dynamic,Dynamic,RowMajor>(s,s)) );
}
- EIGEN_UNUSED_VARIABLE(s)
+ TEST_SET_BUT_UNUSED_VARIABLE(s)
}
diff --git a/test/product_trmm.cpp b/test/product_trmm.cpp
index 31ac1b22e..506a1aeb9 100644
--- a/test/product_trmm.cpp
+++ b/test/product_trmm.cpp
@@ -54,7 +54,7 @@ void trmm(int rows=internal::random<int>(1,EIGEN_TEST_MAX_SIZE),
ge_sx_save = ge_sx;
VERIFY_IS_APPROX( ge_sx_save - (ge_right.adjoint() * (-s1 * triTr).conjugate()).eval(), ge_sx.noalias() -= (ge_right.adjoint() * (-s1 * mat).adjoint().template triangularView<Mode>()).eval());
- VERIFY_IS_APPROX( ge_xs = (s1*mat).adjoint().template triangularView<Mode>() * ge_left.adjoint(), internal::conj(s1) * triTr.conjugate() * ge_left.adjoint());
+ VERIFY_IS_APPROX( ge_xs = (s1*mat).adjoint().template triangularView<Mode>() * ge_left.adjoint(), numext::conj(s1) * triTr.conjugate() * ge_left.adjoint());
// TODO check with sub-matrix expressions ?
}
diff --git a/test/product_trmv.cpp b/test/product_trmv.cpp
index 435018e8e..4c3c435c2 100644
--- a/test/product_trmv.cpp
+++ b/test/product_trmv.cpp
@@ -73,7 +73,7 @@ template<typename MatrixType> void trmv(const MatrixType& m)
void test_product_trmv()
{
- int s;
+ int s = 0;
for(int i = 0; i < g_repeat ; i++) {
CALL_SUBTEST_1( trmv(Matrix<float, 1, 1>()) );
CALL_SUBTEST_2( trmv(Matrix<float, 2, 2>()) );
@@ -85,5 +85,5 @@ void test_product_trmv()
s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);
CALL_SUBTEST_6( trmv(Matrix<float,Dynamic,Dynamic,RowMajor>(s, s)) );
}
- EIGEN_UNUSED_VARIABLE(s);
+ TEST_SET_BUT_UNUSED_VARIABLE(s);
}
diff --git a/test/real_qz.cpp b/test/real_qz.cpp
index b48bac361..7d743a734 100644
--- a/test/real_qz.cpp
+++ b/test/real_qz.cpp
@@ -48,7 +48,7 @@ template<typename MatrixType> void real_qz(const MatrixType& m)
void test_real_qz()
{
- int s;
+ int s = 0;
for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST_1( real_qz(Matrix4f()) );
s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);
@@ -61,5 +61,5 @@ void test_real_qz()
CALL_SUBTEST_4( real_qz(Matrix2d()) );
}
- EIGEN_UNUSED_VARIABLE(s)
+ TEST_SET_BUT_UNUSED_VARIABLE(s)
}
diff --git a/test/redux.cpp b/test/redux.cpp
index dd6edd1bd..0d176e500 100644
--- a/test/redux.cpp
+++ b/test/redux.cpp
@@ -22,26 +22,26 @@ template<typename MatrixType> void matrixRedux(const MatrixType& m)
// The entries of m1 are uniformly distributed in [0,1], so m1.prod() is very small. This may lead to test
// failures if we underflow into denormals. Thus, we scale so that entires are close to 1.
- MatrixType m1_for_prod = MatrixType::Ones(rows, cols) + Scalar(0.2) * m1;
+ MatrixType m1_for_prod = MatrixType::Ones(rows, cols) + RealScalar(0.2) * m1;
VERIFY_IS_MUCH_SMALLER_THAN(MatrixType::Zero(rows, cols).sum(), Scalar(1));
VERIFY_IS_APPROX(MatrixType::Ones(rows, cols).sum(), Scalar(float(rows*cols))); // the float() here to shut up excessive MSVC warning about int->complex conversion being lossy
- Scalar s(0), p(1), minc(internal::real(m1.coeff(0))), maxc(internal::real(m1.coeff(0)));
+ Scalar s(0), p(1), minc(numext::real(m1.coeff(0))), maxc(numext::real(m1.coeff(0)));
for(int j = 0; j < cols; j++)
for(int i = 0; i < rows; i++)
{
s += m1(i,j);
p *= m1_for_prod(i,j);
- minc = (std::min)(internal::real(minc), internal::real(m1(i,j)));
- maxc = (std::max)(internal::real(maxc), internal::real(m1(i,j)));
+ minc = (std::min)(numext::real(minc), numext::real(m1(i,j)));
+ maxc = (std::max)(numext::real(maxc), numext::real(m1(i,j)));
}
const Scalar mean = s/Scalar(RealScalar(rows*cols));
VERIFY_IS_APPROX(m1.sum(), s);
VERIFY_IS_APPROX(m1.mean(), mean);
VERIFY_IS_APPROX(m1_for_prod.prod(), p);
- VERIFY_IS_APPROX(m1.real().minCoeff(), internal::real(minc));
- VERIFY_IS_APPROX(m1.real().maxCoeff(), internal::real(maxc));
+ VERIFY_IS_APPROX(m1.real().minCoeff(), numext::real(minc));
+ VERIFY_IS_APPROX(m1.real().maxCoeff(), numext::real(maxc));
// test slice vectorization assuming assign is ok
Index r0 = internal::random<Index>(0,rows-1);
@@ -73,13 +73,13 @@ template<typename VectorType> void vectorRedux(const VectorType& w)
for(int i = 1; i < size; i++)
{
Scalar s(0), p(1);
- RealScalar minc(internal::real(v.coeff(0))), maxc(internal::real(v.coeff(0)));
+ RealScalar minc(numext::real(v.coeff(0))), maxc(numext::real(v.coeff(0)));
for(int j = 0; j < i; j++)
{
s += v[j];
p *= v_for_prod[j];
- minc = (std::min)(minc, internal::real(v[j]));
- maxc = (std::max)(maxc, internal::real(v[j]));
+ minc = (std::min)(minc, numext::real(v[j]));
+ maxc = (std::max)(maxc, numext::real(v[j]));
}
VERIFY_IS_MUCH_SMALLER_THAN(abs(s - v.head(i).sum()), Scalar(1));
VERIFY_IS_APPROX(p, v_for_prod.head(i).prod());
@@ -90,13 +90,13 @@ template<typename VectorType> void vectorRedux(const VectorType& w)
for(int i = 0; i < size-1; i++)
{
Scalar s(0), p(1);
- RealScalar minc(internal::real(v.coeff(i))), maxc(internal::real(v.coeff(i)));
+ RealScalar minc(numext::real(v.coeff(i))), maxc(numext::real(v.coeff(i)));
for(int j = i; j < size; j++)
{
s += v[j];
p *= v_for_prod[j];
- minc = (std::min)(minc, internal::real(v[j]));
- maxc = (std::max)(maxc, internal::real(v[j]));
+ minc = (std::min)(minc, numext::real(v[j]));
+ maxc = (std::max)(maxc, numext::real(v[j]));
}
VERIFY_IS_MUCH_SMALLER_THAN(abs(s - v.tail(size-i).sum()), Scalar(1));
VERIFY_IS_APPROX(p, v_for_prod.tail(size-i).prod());
@@ -107,13 +107,13 @@ template<typename VectorType> void vectorRedux(const VectorType& w)
for(int i = 0; i < size/2; i++)
{
Scalar s(0), p(1);
- RealScalar minc(internal::real(v.coeff(i))), maxc(internal::real(v.coeff(i)));
+ RealScalar minc(numext::real(v.coeff(i))), maxc(numext::real(v.coeff(i)));
for(int j = i; j < size-i; j++)
{
s += v[j];
p *= v_for_prod[j];
- minc = (std::min)(minc, internal::real(v[j]));
- maxc = (std::max)(maxc, internal::real(v[j]));
+ minc = (std::min)(minc, numext::real(v[j]));
+ maxc = (std::max)(maxc, numext::real(v[j]));
}
VERIFY_IS_MUCH_SMALLER_THAN(abs(s - v.segment(i, size-2*i).sum()), Scalar(1));
VERIFY_IS_APPROX(p, v_for_prod.segment(i, size-2*i).prod());
@@ -133,7 +133,7 @@ void test_redux()
{
// the max size cannot be too large, otherwise reduxion operations obviously generate large errors.
int maxsize = (std::min)(100,EIGEN_TEST_MAX_SIZE);
- EIGEN_UNUSED_VARIABLE(maxsize);
+ TEST_SET_BUT_UNUSED_VARIABLE(maxsize);
for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST_1( matrixRedux(Matrix<float, 1, 1>()) );
CALL_SUBTEST_1( matrixRedux(Array<float, 1, 1>()) );
diff --git a/test/ref.cpp b/test/ref.cpp
index 7c0ccafcf..65b4f5a3e 100644
--- a/test/ref.cpp
+++ b/test/ref.cpp
@@ -14,7 +14,7 @@
static int nb_temporaries;
-void on_temporary_creation(int size) {
+inline void on_temporary_creation(int size) {
// here's a great place to set a breakpoint when debugging failures in this test!
if(size!=0) nb_temporaries++;
}
diff --git a/test/selfadjoint.cpp b/test/selfadjoint.cpp
index 32791eeb5..76dab6d64 100644
--- a/test/selfadjoint.cpp
+++ b/test/selfadjoint.cpp
@@ -46,7 +46,7 @@ void test_selfadjoint()
{
for(int i = 0; i < g_repeat ; i++)
{
- int s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE); EIGEN_UNUSED_VARIABLE(s);
+ int s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);
CALL_SUBTEST_1( selfadjoint(Matrix<float, 1, 1>()) );
CALL_SUBTEST_2( selfadjoint(Matrix<float, 2, 2>()) );
@@ -54,7 +54,7 @@ void test_selfadjoint()
CALL_SUBTEST_4( selfadjoint(MatrixXcd(s,s)) );
CALL_SUBTEST_5( selfadjoint(Matrix<float,Dynamic,Dynamic,RowMajor>(s, s)) );
- EIGEN_UNUSED_VARIABLE(s)
+ TEST_SET_BUT_UNUSED_VARIABLE(s)
}
CALL_SUBTEST_1( bug_159() );
diff --git a/test/sizeof.cpp b/test/sizeof.cpp
index 68463c9b6..d9ad35620 100644
--- a/test/sizeof.cpp
+++ b/test/sizeof.cpp
@@ -13,7 +13,7 @@ template<typename MatrixType> void verifySizeOf(const MatrixType&)
{
typedef typename MatrixType::Scalar Scalar;
if (MatrixType::RowsAtCompileTime!=Dynamic && MatrixType::ColsAtCompileTime!=Dynamic)
- VERIFY(sizeof(MatrixType)==sizeof(Scalar)*size_t(MatrixType::SizeAtCompileTime));
+ VERIFY(std::ptrdiff_t(sizeof(MatrixType))==std::ptrdiff_t(sizeof(Scalar))*std::ptrdiff_t(MatrixType::SizeAtCompileTime));
else
VERIFY(sizeof(MatrixType)==sizeof(Scalar*) + 2 * sizeof(typename MatrixType::Index));
}
diff --git a/test/sparse.h b/test/sparse.h
index b6f6e6fce..a09c65e5f 100644
--- a/test/sparse.h
+++ b/test/sparse.h
@@ -58,18 +58,18 @@ initSparse(double density,
Matrix<Scalar,Dynamic,Dynamic,Opt1>& refMat,
SparseMatrix<Scalar,Opt2,Index>& sparseMat,
int flags = 0,
- std::vector<Vector2i>* zeroCoords = 0,
- std::vector<Vector2i>* nonzeroCoords = 0)
+ std::vector<Matrix<Index,2,1> >* zeroCoords = 0,
+ std::vector<Matrix<Index,2,1> >* nonzeroCoords = 0)
{
enum { IsRowMajor = SparseMatrix<Scalar,Opt2,Index>::IsRowMajor };
sparseMat.setZero();
//sparseMat.reserve(int(refMat.rows()*refMat.cols()*density));
sparseMat.reserve(VectorXi::Constant(IsRowMajor ? refMat.rows() : refMat.cols(), int((1.5*density)*(IsRowMajor?refMat.cols():refMat.rows()))));
- for(int j=0; j<sparseMat.outerSize(); j++)
+ for(Index j=0; j<sparseMat.outerSize(); j++)
{
//sparseMat.startVec(j);
- for(int i=0; i<sparseMat.innerSize(); i++)
+ for(Index i=0; i<sparseMat.innerSize(); i++)
{
int ai(i), aj(j);
if(IsRowMajor)
@@ -86,18 +86,18 @@ initSparse(double density,
v = Scalar(0);
if ((flags&ForceRealDiag) && (i==j))
- v = internal::real(v);
+ v = numext::real(v);
if (v!=Scalar(0))
{
//sparseMat.insertBackByOuterInner(j,i) = v;
sparseMat.insertByOuterInner(j,i) = v;
if (nonzeroCoords)
- nonzeroCoords->push_back(Vector2i(ai,aj));
+ nonzeroCoords->push_back(Matrix<Index,2,1> (ai,aj));
}
else if (zeroCoords)
{
- zeroCoords->push_back(Vector2i(ai,aj));
+ zeroCoords->push_back(Matrix<Index,2,1> (ai,aj));
}
refMat(ai,aj) = v;
}
@@ -110,8 +110,8 @@ initSparse(double density,
Matrix<Scalar,Dynamic,Dynamic, Opt1>& refMat,
DynamicSparseMatrix<Scalar, Opt2, Index>& sparseMat,
int flags = 0,
- std::vector<Vector2i>* zeroCoords = 0,
- std::vector<Vector2i>* nonzeroCoords = 0)
+ std::vector<Matrix<Index,2,1> >* zeroCoords = 0,
+ std::vector<Matrix<Index,2,1> >* nonzeroCoords = 0)
{
enum { IsRowMajor = DynamicSparseMatrix<Scalar,Opt2,Index>::IsRowMajor };
sparseMat.setZero();
@@ -136,17 +136,17 @@ initSparse(double density,
v = Scalar(0);
if ((flags&ForceRealDiag) && (i==j))
- v = internal::real(v);
+ v = numext::real(v);
if (v!=Scalar(0))
{
sparseMat.insertBackByOuterInner(j,i) = v;
if (nonzeroCoords)
- nonzeroCoords->push_back(Vector2i(ai,aj));
+ nonzeroCoords->push_back(Matrix<Index,2,1> (ai,aj));
}
else if (zeroCoords)
{
- zeroCoords->push_back(Vector2i(ai,aj));
+ zeroCoords->push_back(Matrix<Index,2,1> (ai,aj));
}
refMat(ai,aj) = v;
}
diff --git a/test/sparse_basic.cpp b/test/sparse_basic.cpp
index c573ae517..498ecfe29 100644
--- a/test/sparse_basic.cpp
+++ b/test/sparse_basic.cpp
@@ -3,6 +3,7 @@
//
// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2008 Daniel Gomez Ferro <dgomezferro@gmail.com>
+// Copyright (C) 2013 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
@@ -13,7 +14,8 @@
template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& ref)
{
typedef typename SparseMatrixType::Index Index;
-
+ typedef Matrix<Index,2,1> Vector2;
+
const Index rows = ref.rows();
const Index cols = ref.cols();
typedef typename SparseMatrixType::Scalar Scalar;
@@ -24,71 +26,77 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
typedef Matrix<Scalar,Dynamic,1> DenseVector;
Scalar eps = 1e-6;
- SparseMatrixType m(rows, cols);
- DenseMatrix refMat = DenseMatrix::Zero(rows, cols);
- DenseVector vec1 = DenseVector::Random(rows);
Scalar s1 = internal::random<Scalar>();
-
- std::vector<Vector2i> zeroCoords;
- std::vector<Vector2i> nonzeroCoords;
- initSparse<Scalar>(density, refMat, m, 0, &zeroCoords, &nonzeroCoords);
-
- if (zeroCoords.size()==0 || nonzeroCoords.size()==0)
- return;
-
- // test coeff and coeffRef
- for (int i=0; i<(int)zeroCoords.size(); ++i)
{
- VERIFY_IS_MUCH_SMALLER_THAN( m.coeff(zeroCoords[i].x(),zeroCoords[i].y()), eps );
- if(internal::is_same<SparseMatrixType,SparseMatrix<Scalar,Flags> >::value)
- VERIFY_RAISES_ASSERT( m.coeffRef(zeroCoords[0].x(),zeroCoords[0].y()) = 5 );
- }
- VERIFY_IS_APPROX(m, refMat);
+ SparseMatrixType m(rows, cols);
+ DenseMatrix refMat = DenseMatrix::Zero(rows, cols);
+ DenseVector vec1 = DenseVector::Random(rows);
- m.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5);
- refMat.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5);
+ std::vector<Vector2> zeroCoords;
+ std::vector<Vector2> nonzeroCoords;
+ initSparse<Scalar>(density, refMat, m, 0, &zeroCoords, &nonzeroCoords);
- VERIFY_IS_APPROX(m, refMat);
- /*
- // test InnerIterators and Block expressions
- for (int t=0; t<10; ++t)
- {
- int j = internal::random<int>(0,cols-1);
- int i = internal::random<int>(0,rows-1);
- int w = internal::random<int>(1,cols-j-1);
- int h = internal::random<int>(1,rows-i-1);
+ if (zeroCoords.size()==0 || nonzeroCoords.size()==0)
+ return;
-// VERIFY_IS_APPROX(m.block(i,j,h,w), refMat.block(i,j,h,w));
- for(int c=0; c<w; c++)
+ // test coeff and coeffRef
+ for (int i=0; i<(int)zeroCoords.size(); ++i)
{
- VERIFY_IS_APPROX(m.block(i,j,h,w).col(c), refMat.block(i,j,h,w).col(c));
- for(int r=0; r<h; r++)
+ VERIFY_IS_MUCH_SMALLER_THAN( m.coeff(zeroCoords[i].x(),zeroCoords[i].y()), eps );
+ if(internal::is_same<SparseMatrixType,SparseMatrix<Scalar,Flags> >::value)
+ VERIFY_RAISES_ASSERT( m.coeffRef(zeroCoords[0].x(),zeroCoords[0].y()) = 5 );
+ }
+ VERIFY_IS_APPROX(m, refMat);
+
+ m.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5);
+ refMat.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5);
+
+ VERIFY_IS_APPROX(m, refMat);
+ /*
+ // test InnerIterators and Block expressions
+ for (int t=0; t<10; ++t)
{
-// VERIFY_IS_APPROX(m.block(i,j,h,w).col(c).coeff(r), refMat.block(i,j,h,w).col(c).coeff(r));
+ int j = internal::random<int>(0,cols-1);
+ int i = internal::random<int>(0,rows-1);
+ int w = internal::random<int>(1,cols-j-1);
+ int h = internal::random<int>(1,rows-i-1);
+
+ // VERIFY_IS_APPROX(m.block(i,j,h,w), refMat.block(i,j,h,w));
+ for(int c=0; c<w; c++)
+ {
+ VERIFY_IS_APPROX(m.block(i,j,h,w).col(c), refMat.block(i,j,h,w).col(c));
+ for(int r=0; r<h; r++)
+ {
+ // VERIFY_IS_APPROX(m.block(i,j,h,w).col(c).coeff(r), refMat.block(i,j,h,w).col(c).coeff(r));
+ }
+ }
+ // for(int r=0; r<h; r++)
+ // {
+ // VERIFY_IS_APPROX(m.block(i,j,h,w).row(r), refMat.block(i,j,h,w).row(r));
+ // for(int c=0; c<w; c++)
+ // {
+ // VERIFY_IS_APPROX(m.block(i,j,h,w).row(r).coeff(c), refMat.block(i,j,h,w).row(r).coeff(c));
+ // }
+ // }
}
- }
-// for(int r=0; r<h; r++)
-// {
-// VERIFY_IS_APPROX(m.block(i,j,h,w).row(r), refMat.block(i,j,h,w).row(r));
-// for(int c=0; c<w; c++)
-// {
-// VERIFY_IS_APPROX(m.block(i,j,h,w).row(r).coeff(c), refMat.block(i,j,h,w).row(r).coeff(c));
-// }
-// }
- }
- for(int c=0; c<cols; c++)
- {
- VERIFY_IS_APPROX(m.col(c) + m.col(c), (m + m).col(c));
- VERIFY_IS_APPROX(m.col(c) + m.col(c), refMat.col(c) + refMat.col(c));
- }
+ for(int c=0; c<cols; c++)
+ {
+ VERIFY_IS_APPROX(m.col(c) + m.col(c), (m + m).col(c));
+ VERIFY_IS_APPROX(m.col(c) + m.col(c), refMat.col(c) + refMat.col(c));
+ }
- for(int r=0; r<rows; r++)
- {
- VERIFY_IS_APPROX(m.row(r) + m.row(r), (m + m).row(r));
- VERIFY_IS_APPROX(m.row(r) + m.row(r), refMat.row(r) + refMat.row(r));
- }
- */
+ for(int r=0; r<rows; r++)
+ {
+ VERIFY_IS_APPROX(m.row(r) + m.row(r), (m + m).row(r));
+ VERIFY_IS_APPROX(m.row(r) + m.row(r), refMat.row(r) + refMat.row(r));
+ }
+ */
+
+ // test assertion
+ VERIFY_RAISES_ASSERT( m.coeffRef(-1,1) = 0 );
+ VERIFY_RAISES_ASSERT( m.coeffRef(0,m.cols()) = 0 );
+ }
// test insert (inner random)
{
@@ -97,11 +105,11 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
SparseMatrixType m2(rows,cols);
if(internal::random<int>()%2)
m2.reserve(VectorXi::Constant(m2.outerSize(), 2));
- for (int j=0; j<cols; ++j)
+ for (Index j=0; j<cols; ++j)
{
- for (int k=0; k<rows/2; ++k)
+ for (Index k=0; k<rows/2; ++k)
{
- int i = internal::random<int>(0,rows-1);
+ Index i = internal::random<Index>(0,rows-1);
if (m1.coeff(i,j)==Scalar(0))
m2.insert(i,j) = m1(i,j) = internal::random<Scalar>();
}
@@ -119,8 +127,8 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
m2.reserve(VectorXi::Constant(m2.outerSize(), 2));
for (int k=0; k<rows*cols; ++k)
{
- int i = internal::random<int>(0,rows-1);
- int j = internal::random<int>(0,cols-1);
+ Index i = internal::random<Index>(0,rows-1);
+ Index j = internal::random<Index>(0,cols-1);
if ((m1.coeff(i,j)==Scalar(0)) && (internal::random<int>()%2))
m2.insert(i,j) = m1(i,j) = internal::random<Scalar>();
else
@@ -143,8 +151,8 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
m2.reserve(r);
for (int k=0; k<rows*cols; ++k)
{
- int i = internal::random<int>(0,rows-1);
- int j = internal::random<int>(0,cols-1);
+ Index i = internal::random<Index>(0,rows-1);
+ Index j = internal::random<Index>(0,cols-1);
if (m1.coeff(i,j)==Scalar(0))
m2.insert(i,j) = m1(i,j) = internal::random<Scalar>();
if(mode==3)
@@ -160,8 +168,8 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);
SparseMatrixType m2(rows, rows);
initSparse<Scalar>(density, refMat2, m2);
- int j0 = internal::random<int>(0,rows-1);
- int j1 = internal::random<int>(0,rows-1);
+ Index j0 = internal::random<Index>(0,rows-1);
+ Index j1 = internal::random<Index>(0,rows-1);
if(SparseMatrixType::IsRowMajor)
VERIFY_IS_APPROX(m2.innerVector(j0), refMat2.row(j0));
else
@@ -174,21 +182,21 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
SparseMatrixType m3(rows,rows);
m3.reserve(VectorXi::Constant(rows,rows/2));
- for(int j=0; j<rows; ++j)
- for(int k=0; k<j; ++k)
+ for(Index j=0; j<rows; ++j)
+ for(Index k=0; k<j; ++k)
m3.insertByOuterInner(j,k) = k+1;
- for(int j=0; j<rows; ++j)
+ for(Index j=0; j<rows; ++j)
{
- VERIFY(j==internal::real(m3.innerVector(j).nonZeros()));
+ VERIFY(j==numext::real(m3.innerVector(j).nonZeros()));
if(j>0)
- VERIFY(j==internal::real(m3.innerVector(j).lastCoeff()));
+ VERIFY(j==numext::real(m3.innerVector(j).lastCoeff()));
}
m3.makeCompressed();
- for(int j=0; j<rows; ++j)
+ for(Index j=0; j<rows; ++j)
{
- VERIFY(j==internal::real(m3.innerVector(j).nonZeros()));
+ VERIFY(j==numext::real(m3.innerVector(j).nonZeros()));
if(j>0)
- VERIFY(j==internal::real(m3.innerVector(j).lastCoeff()));
+ VERIFY(j==numext::real(m3.innerVector(j).lastCoeff()));
}
//m2.innerVector(j0) = 2*m2.innerVector(j1);
@@ -203,9 +211,9 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
initSparse<Scalar>(density, refMat2, m2);
if(internal::random<float>(0,1)>0.5) m2.makeCompressed();
- int j0 = internal::random<int>(0,rows-2);
- int j1 = internal::random<int>(0,rows-2);
- int n0 = internal::random<int>(1,rows-(std::max)(j0,j1));
+ Index j0 = internal::random<Index>(0,rows-2);
+ Index j1 = internal::random<Index>(0,rows-2);
+ Index n0 = internal::random<Index>(1,rows-(std::max)(j0,j1));
if(SparseMatrixType::IsRowMajor)
VERIFY_IS_APPROX(m2.innerVectors(j0,n0), refMat2.block(j0,0,n0,cols));
else
@@ -293,9 +301,9 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);
SparseMatrixType m2(rows, rows);
initSparse<Scalar>(density, refMat2, m2);
- int j0 = internal::random<int>(0,rows-2);
- int j1 = internal::random<int>(0,rows-2);
- int n0 = internal::random<int>(1,rows-(std::max)(j0,j1));
+ Index j0 = internal::random<Index>(0,rows-2);
+ Index j1 = internal::random<Index>(0,rows-2);
+ Index n0 = internal::random<Index>(1,rows-(std::max)(j0,j1));
if(SparseMatrixType::IsRowMajor)
VERIFY_IS_APPROX(m2.block(j0,0,n0,cols), refMat2.block(j0,0,n0,cols));
else
@@ -307,6 +315,17 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
else
VERIFY_IS_APPROX(m2.block(0,j0,rows,n0)+m2.block(0,j1,rows,n0),
refMat2.block(0,j0,rows,n0)+refMat2.block(0,j1,rows,n0));
+
+ Index i = internal::random<Index>(0,m2.outerSize()-1);
+ if(SparseMatrixType::IsRowMajor) {
+ m2.innerVector(i) = m2.innerVector(i) * s1;
+ refMat2.row(i) = refMat2.row(i) * s1;
+ VERIFY_IS_APPROX(m2,refMat2);
+ } else {
+ m2.innerVector(i) = m2.innerVector(i) * s1;
+ refMat2.col(i) = refMat2.col(i) * s1;
+ VERIFY_IS_APPROX(m2,refMat2);
+ }
}
// test prune
@@ -316,10 +335,10 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
refM2.setZero();
int countFalseNonZero = 0;
int countTrueNonZero = 0;
- for (int j=0; j<m2.outerSize(); ++j)
+ for (Index j=0; j<m2.outerSize(); ++j)
{
m2.startVec(j);
- for (int i=0; i<m2.innerSize(); ++i)
+ for (Index i=0; i<m2.innerSize(); ++i)
{
float x = internal::random<float>(0,1);
if (x<0.1)
@@ -360,8 +379,8 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
refMat.setZero();
for(int i=0;i<ntriplets;++i)
{
- int r = internal::random<int>(0,rows-1);
- int c = internal::random<int>(0,cols-1);
+ Index r = internal::random<Index>(0,rows-1);
+ Index c = internal::random<Index>(0,cols-1);
Scalar v = internal::random<Scalar>();
triplets.push_back(TripletType(r,c,v));
refMat(r,c) += v;
@@ -391,6 +410,14 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
refMat3 = refMat2.template triangularView<UnitLower>();
m3 = m2.template triangularView<UnitLower>();
VERIFY_IS_APPROX(m3, refMat3);
+
+ refMat3 = refMat2.template triangularView<StrictlyUpper>();
+ m3 = m2.template triangularView<StrictlyUpper>();
+ VERIFY_IS_APPROX(m3, refMat3);
+
+ refMat3 = refMat2.template triangularView<StrictlyLower>();
+ m3 = m2.template triangularView<StrictlyLower>();
+ VERIFY_IS_APPROX(m3, refMat3);
}
// test selfadjointView
@@ -422,16 +449,16 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
// test conservative resize
{
- std::vector< std::pair<int,int> > inc;
- inc.push_back(std::pair<int,int>(-3,-2));
- inc.push_back(std::pair<int,int>(0,0));
- inc.push_back(std::pair<int,int>(3,2));
- inc.push_back(std::pair<int,int>(3,0));
- inc.push_back(std::pair<int,int>(0,3));
+ std::vector< std::pair<Index,Index> > inc;
+ inc.push_back(std::pair<Index,Index>(-3,-2));
+ inc.push_back(std::pair<Index,Index>(0,0));
+ inc.push_back(std::pair<Index,Index>(3,2));
+ inc.push_back(std::pair<Index,Index>(3,0));
+ inc.push_back(std::pair<Index,Index>(0,3));
for(size_t i = 0; i< inc.size(); i++) {
- int incRows = inc[i].first;
- int incCols = inc[i].second;
+ Index incRows = inc[i].first;
+ Index incCols = inc[i].second;
SparseMatrixType m1(rows, cols);
DenseMatrix refMat1 = DenseMatrix::Zero(rows, cols);
initSparse<Scalar>(density, refMat1, m1);
@@ -445,15 +472,23 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
// Insert new values
if (incRows > 0)
- m1.insert(refMat1.rows()-1, 0) = refMat1(refMat1.rows()-1, 0) = 1;
+ m1.insert(m1.rows()-1, 0) = refMat1(refMat1.rows()-1, 0) = 1;
if (incCols > 0)
- m1.insert(0, refMat1.cols()-1) = refMat1(0, refMat1.cols()-1) = 1;
+ m1.insert(0, m1.cols()-1) = refMat1(0, refMat1.cols()-1) = 1;
VERIFY_IS_APPROX(m1, refMat1);
}
}
+
+ // test Identity matrix
+ {
+ DenseMatrix refMat1 = DenseMatrix::Identity(rows, rows);
+ SparseMatrixType m1(rows, rows);
+ m1.setIdentity();
+ VERIFY_IS_APPROX(m1, refMat1);
+ }
}
void test_sparse_basic()
@@ -467,5 +502,8 @@ void test_sparse_basic()
CALL_SUBTEST_1(( sparse_basic(SparseMatrix<double>(s, s)) ));
CALL_SUBTEST_1(( sparse_basic(SparseMatrix<double,ColMajor,long int>(s, s)) ));
CALL_SUBTEST_1(( sparse_basic(SparseMatrix<double,RowMajor,long int>(s, s)) ));
+
+ CALL_SUBTEST_1(( sparse_basic(SparseMatrix<double,ColMajor,short int>(short(s), short(s))) ));
+ CALL_SUBTEST_1(( sparse_basic(SparseMatrix<double,RowMajor,short int>(short(s), short(s))) ));
}
}
diff --git a/test/sparse_product.cpp b/test/sparse_product.cpp
index 67a59ecd8..664e33887 100644
--- a/test/sparse_product.cpp
+++ b/test/sparse_product.cpp
@@ -153,6 +153,16 @@ template<typename SparseMatrixType> void sparse_product()
VERIFY_IS_APPROX(m3=d2*m2, refM3=d2*refM2);
VERIFY_IS_APPROX(m3=d1*m2.transpose(), refM3=d1*refM2.transpose());
+ // also check with a SparseWrapper:
+ DenseVector v1 = DenseVector::Random(cols);
+ DenseVector v2 = DenseVector::Random(rows);
+ VERIFY_IS_APPROX(m3=m2*v1.asDiagonal(), refM3=refM2*v1.asDiagonal());
+ VERIFY_IS_APPROX(m3=m2.transpose()*v2.asDiagonal(), refM3=refM2.transpose()*v2.asDiagonal());
+ VERIFY_IS_APPROX(m3=v2.asDiagonal()*m2, refM3=v2.asDiagonal()*refM2);
+ VERIFY_IS_APPROX(m3=v1.asDiagonal()*m2.transpose(), refM3=v1.asDiagonal()*refM2.transpose());
+
+ VERIFY_IS_APPROX(m3=v2.asDiagonal()*m2*v1.asDiagonal(), refM3=v2.asDiagonal()*refM2*v1.asDiagonal());
+
// evaluate to a dense matrix to check the .row() and .col() iterator functions
VERIFY_IS_APPROX(d3=m2*d1, refM3=refM2*d1);
VERIFY_IS_APPROX(d3=m2.transpose()*d2, refM3=refM2.transpose()*d2);
@@ -193,7 +203,16 @@ template<typename SparseMatrixType> void sparse_product()
VERIFY_IS_APPROX(x=mUp.template selfadjointView<Upper>()*b, refX=refS*b);
VERIFY_IS_APPROX(x=mLo.template selfadjointView<Lower>()*b, refX=refS*b);
VERIFY_IS_APPROX(x=mS.template selfadjointView<Upper|Lower>()*b, refX=refS*b);
+
+ // sparse selfadjointView * sparse
+ SparseMatrixType mSres(rows,rows);
+ VERIFY_IS_APPROX(mSres = mLo.template selfadjointView<Lower>()*mS,
+ refX = refLo.template selfadjointView<Lower>()*refS);
+ // sparse * sparse selfadjointview
+ VERIFY_IS_APPROX(mSres = mS * mLo.template selfadjointView<Lower>(),
+ refX = refS * refLo.template selfadjointView<Lower>());
}
+
}
// New test for Bug in SparseTimeDenseProduct
diff --git a/test/sparse_solver.h b/test/sparse_solver.h
index 645a965bb..d84aff070 100644
--- a/test/sparse_solver.h
+++ b/test/sparse_solver.h
@@ -17,53 +17,54 @@ void check_sparse_solving(Solver& solver, const typename Solver::MatrixType& A,
typedef typename Mat::Scalar Scalar;
DenseRhs refX = dA.lu().solve(db);
+ {
+ Rhs x(b.rows(), b.cols());
+ Rhs oldb = b;
- Rhs x(b.rows(), b.cols());
- Rhs oldb = b;
+ solver.compute(A);
+ if (solver.info() != Success)
+ {
+ std::cerr << "sparse solver testing: factorization failed (check_sparse_solving)\n";
+ exit(0);
+ return;
+ }
+ x = solver.solve(b);
+ if (solver.info() != Success)
+ {
+ std::cerr << "sparse solver testing: solving failed\n";
+ return;
+ }
+ VERIFY(oldb.isApprox(b) && "sparse solver testing: the rhs should not be modified!");
- solver.compute(A);
- if (solver.info() != Success)
- {
- std::cerr << "sparse solver testing: factorization failed (check_sparse_solving)\n";
- exit(0);
- return;
- }
- x = solver.solve(b);
- if (solver.info() != Success)
- {
- std::cerr << "sparse solver testing: solving failed\n";
- return;
- }
- VERIFY(oldb.isApprox(b) && "sparse solver testing: the rhs should not be modified!");
+ VERIFY(x.isApprox(refX,test_precision<Scalar>()));
+ x.setZero();
+ // test the analyze/factorize API
+ solver.analyzePattern(A);
+ solver.factorize(A);
+ if (solver.info() != Success)
+ {
+ std::cerr << "sparse solver testing: factorization failed (check_sparse_solving)\n";
+ exit(0);
+ return;
+ }
+ x = solver.solve(b);
+ if (solver.info() != Success)
+ {
+ std::cerr << "sparse solver testing: solving failed\n";
+ return;
+ }
+ VERIFY(oldb.isApprox(b) && "sparse solver testing: the rhs should not be modified!");
- VERIFY(x.isApprox(refX,test_precision<Scalar>()));
- x.setZero();
- // test the analyze/factorize API
- solver.analyzePattern(A);
- solver.factorize(A);
- if (solver.info() != Success)
- {
- std::cerr << "sparse solver testing: factorization failed (check_sparse_solving)\n";
- exit(0);
- return;
- }
- x = solver.solve(b);
- if (solver.info() != Success)
- {
- std::cerr << "sparse solver testing: solving failed\n";
- return;
+ VERIFY(x.isApprox(refX,test_precision<Scalar>()));
}
- VERIFY(oldb.isApprox(b) && "sparse solver testing: the rhs should not be modified!");
-
- VERIFY(x.isApprox(refX,test_precision<Scalar>()));
- // test Block as the result and rhs:
+ // test dense Block as the result and rhs:
{
DenseRhs x(db.rows(), db.cols());
- DenseRhs b(db), oldb(db);
+ DenseRhs oldb(db);
x.setZero();
- x.block(0,0,x.rows(),x.cols()) = solver.solve(b.block(0,0,b.rows(),b.cols()));
- VERIFY(oldb.isApprox(b) && "sparse solver testing: the rhs should not be modified!");
+ x.block(0,0,x.rows(),x.cols()) = solver.solve(db.block(0,0,db.rows(),db.cols()));
+ VERIFY(oldb.isApprox(db) && "sparse solver testing: the rhs should not be modified!");
VERIFY(x.isApprox(refX,test_precision<Scalar>()));
}
}
diff --git a/test/sparse_vector.cpp b/test/sparse_vector.cpp
index d16d42f59..ec5877b6a 100644
--- a/test/sparse_vector.cpp
+++ b/test/sparse_vector.cpp
@@ -90,6 +90,11 @@ template<typename Scalar> void sparse_vector(int rows, int cols)
VERIFY_IS_APPROX((mv1=v1),v1);
VERIFY_IS_APPROX(mv1,(v1=mv1));
VERIFY_IS_APPROX(mv1,(v1=mv1.transpose()));
+
+ // check copy to dense vector with transpose
+ refV3.resize(0);
+ VERIFY_IS_APPROX(refV3 = v1.transpose(),v1.toDense());
+ VERIFY_IS_APPROX(DenseVector(v1),v1.toDense());
}
diff --git a/test/sparselu.cpp b/test/sparselu.cpp
index 6a9eac065..37980defc 100644
--- a/test/sparselu.cpp
+++ b/test/sparselu.cpp
@@ -26,7 +26,7 @@
// SparseLU solve does not accept column major matrices for the destination.
// However, as expected, the generic check_sparse_square_solving routines produces row-major
// rhs and destination matrices when compiled with EIGEN_DEFAULT_TO_ROW_MAJOR
-//
+
#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
#undef EIGEN_DEFAULT_TO_ROW_MAJOR
#endif
@@ -37,7 +37,7 @@
template<typename T> void test_sparselu_T()
{
- SparseLU<SparseMatrix<T, ColMajor>, COLAMDOrdering<int> > sparselu_colamd;
+ SparseLU<SparseMatrix<T, ColMajor> /*, COLAMDOrdering<int>*/ > sparselu_colamd; // COLAMDOrdering is the default
SparseLU<SparseMatrix<T, ColMajor>, AMDOrdering<int> > sparselu_amd;
SparseLU<SparseMatrix<T, ColMajor, long int>, NaturalOrdering<long int> > sparselu_natural;
diff --git a/test/sparseqr.cpp b/test/sparseqr.cpp
index 66c7c005e..6edba30b2 100644
--- a/test/sparseqr.cpp
+++ b/test/sparseqr.cpp
@@ -71,6 +71,14 @@ template<typename Scalar> void test_sparseqr_scalar()
VERIFY((dA * refX - b).norm() * 2 > (A * x - b).norm() );
else
VERIFY_IS_APPROX(x, refX);
+
+ // Compute explicitly the matrix Q
+ MatrixType Q, QtQ, idM;
+ Q = solver.matrixQ();
+ //Check ||Q' * Q - I ||
+ QtQ = Q * Q.adjoint();
+ idM.resize(Q.rows(), Q.rows()); idM.setIdentity();
+ VERIFY(idM.isApprox(QtQ));
}
void test_sparseqr()
{
diff --git a/test/special_numbers.cpp b/test/special_numbers.cpp
index a5936184e..910ddf21c 100644
--- a/test/special_numbers.cpp
+++ b/test/special_numbers.cpp
@@ -11,13 +11,12 @@
template<typename Scalar> void special_numbers()
{
- typedef typename NumTraits<Scalar>::Real RealScalar;
typedef Matrix<Scalar, Dynamic,Dynamic> MatType;
int rows = internal::random<int>(1,300);
int cols = internal::random<int>(1,300);
- Scalar nan = Scalar(0)/Scalar(0);
- Scalar inf = Scalar(1)/Scalar(0);
+ Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
+ Scalar inf = std::numeric_limits<Scalar>::infinity();
Scalar s1 = internal::random<Scalar>();
MatType m1 = MatType::Random(rows,cols),
diff --git a/test/spqr_support.cpp b/test/spqr_support.cpp
index 7e4b6e18a..b8980e081 100644
--- a/test/spqr_support.cpp
+++ b/test/spqr_support.cpp
@@ -59,4 +59,4 @@ void test_spqr_support()
{
CALL_SUBTEST_1(test_spqr_scalar<double>());
CALL_SUBTEST_2(test_spqr_scalar<std::complex<double> >());
-} \ No newline at end of file
+}
diff --git a/test/triangular.cpp b/test/triangular.cpp
index 7e1723af5..54320390b 100644
--- a/test/triangular.cpp
+++ b/test/triangular.cpp
@@ -65,7 +65,7 @@ template<typename MatrixType> void triangular_square(const MatrixType& m)
m1 = MatrixType::Random(rows, cols);
for (int i=0; i<rows; ++i)
- while (internal::abs2(m1(i,i))<1e-1) m1(i,i) = internal::random<Scalar>();
+ while (numext::abs2(m1(i,i))<1e-1) m1(i,i) = internal::random<Scalar>();
Transpose<MatrixType> trm4(m4);
// test back and forward subsitution with a vector as the rhs
@@ -211,8 +211,8 @@ void test_triangular()
int maxsize = (std::min)(EIGEN_TEST_MAX_SIZE,20);
for(int i = 0; i < g_repeat ; i++)
{
- int r = internal::random<int>(2,maxsize); EIGEN_UNUSED_VARIABLE(r);
- int c = internal::random<int>(2,maxsize); EIGEN_UNUSED_VARIABLE(c);
+ int r = internal::random<int>(2,maxsize); TEST_SET_BUT_UNUSED_VARIABLE(r)
+ int c = internal::random<int>(2,maxsize); TEST_SET_BUT_UNUSED_VARIABLE(c)
CALL_SUBTEST_1( triangular_square(Matrix<float, 1, 1>()) );
CALL_SUBTEST_2( triangular_square(Matrix<float, 2, 2>()) );
diff --git a/test/umeyama.cpp b/test/umeyama.cpp
index 814d19d01..738d0af70 100644
--- a/test/umeyama.cpp
+++ b/test/umeyama.cpp
@@ -82,7 +82,7 @@ Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> randMatrixSpecialUnitary(int si
MatrixType Q = randMatrixUnitary<Scalar>(size);
// tweak the first column to make the determinant be 1
- Q.col(0) *= internal::conj(Q.determinant());
+ Q.col(0) *= numext::conj(Q.determinant());
return Q;
}
diff --git a/test/upperbidiagonalization.cpp b/test/upperbidiagonalization.cpp
index 5897cffab..d15bf588b 100644
--- a/test/upperbidiagonalization.cpp
+++ b/test/upperbidiagonalization.cpp
@@ -16,6 +16,7 @@ template<typename MatrixType> void upperbidiag(const MatrixType& m)
const typename MatrixType::Index cols = m.cols();
typedef Matrix<typename MatrixType::RealScalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime> RealMatrixType;
+ typedef Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, MatrixType::RowsAtCompileTime> TransposeMatrixType;
MatrixType a = MatrixType::Random(rows,cols);
internal::UpperBidiagonalization<MatrixType> ubd(a);
@@ -24,6 +25,8 @@ template<typename MatrixType> void upperbidiag(const MatrixType& m)
b.block(0,0,cols,cols) = ubd.bidiagonal();
MatrixType c = ubd.householderU() * b * ubd.householderV().adjoint();
VERIFY_IS_APPROX(a,c);
+ TransposeMatrixType d = ubd.householderV() * b.adjoint() * ubd.householderU().adjoint();
+ VERIFY_IS_APPROX(a.adjoint(),d);
}
void test_upperbidiagonalization()
diff --git a/unsupported/Eigen/ArpackSupport b/unsupported/Eigen/ArpackSupport
index 98f8e886b..37a2799ef 100644
--- a/unsupported/Eigen/ArpackSupport
+++ b/unsupported/Eigen/ArpackSupport
@@ -23,7 +23,7 @@
*/
#include <Eigen/SparseCholesky>
-#include "src/Eigenvalues/ArpackGeneralizedSelfAdjointEigenSolver.h"
+#include "src/Eigenvalues/ArpackSelfAdjointEigenSolver.h"
#include <Eigen/src/Core/util/ReenableStupidWarnings.h>
diff --git a/unsupported/Eigen/MatrixFunctions b/unsupported/Eigen/MatrixFunctions
index 124175841..0991817d5 100644
--- a/unsupported/Eigen/MatrixFunctions
+++ b/unsupported/Eigen/MatrixFunctions
@@ -59,7 +59,6 @@
#include "src/MatrixFunctions/MatrixFunction.h"
#include "src/MatrixFunctions/MatrixSquareRoot.h"
#include "src/MatrixFunctions/MatrixLogarithm.h"
-#include "src/MatrixFunctions/MatrixPowerBase.h"
#include "src/MatrixFunctions/MatrixPower.h"
diff --git a/unsupported/Eigen/NonLinearOptimization b/unsupported/Eigen/NonLinearOptimization
index 2e4d4df37..600ab4c12 100644
--- a/unsupported/Eigen/NonLinearOptimization
+++ b/unsupported/Eigen/NonLinearOptimization
@@ -1,4 +1,4 @@
-// This file is part of Eugenio, a lightweight C++ template library
+// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>
diff --git a/unsupported/Eigen/SVD b/unsupported/Eigen/SVD
new file mode 100644
index 000000000..7cc059280
--- /dev/null
+++ b/unsupported/Eigen/SVD
@@ -0,0 +1,39 @@
+#ifndef EIGEN_SVD_MODULE_H
+#define EIGEN_SVD_MODULE_H
+
+#include <Eigen/QR>
+#include <Eigen/Householder>
+#include <Eigen/Jacobi>
+
+#include "../../Eigen/src/Core/util/DisableStupidWarnings.h"
+
+/** \defgroup SVD_Module SVD module
+ *
+ *
+ *
+ * This module provides SVD decomposition for matrices (both real and complex).
+ * This decomposition is accessible via the following MatrixBase method:
+ * - MatrixBase::jacobiSvd()
+ *
+ * \code
+ * #include <Eigen/SVD>
+ * \endcode
+ */
+
+#include "../../Eigen/src/misc/Solve.h"
+#include "../../Eigen/src/SVD/UpperBidiagonalization.h"
+#include "src/SVD/SVDBase.h"
+#include "src/SVD/JacobiSVD.h"
+#include "src/SVD/BDCSVD.h"
+#if defined(EIGEN_USE_LAPACKE) && !defined(EIGEN_USE_LAPACKE_STRICT)
+#include "../../Eigen/src/SVD/JacobiSVD_MKL.h"
+#endif
+
+#ifdef EIGEN2_SUPPORT
+#include "../../Eigen/src/Eigen2Support/SVD.h"
+#endif
+
+#include "../../Eigen/src/Core/util/ReenableStupidWarnings.h"
+
+#endif // EIGEN_SVD_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h b/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
index bb49191b7..8d42e69b9 100644
--- a/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
+++ b/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
@@ -47,8 +47,8 @@ template<typename _DerType, bool Enable> struct auto_diff_special_op;
*
* It supports the following list of global math function:
* - std::abs, std::sqrt, std::pow, std::exp, std::log, std::sin, std::cos,
- * - internal::abs, internal::sqrt, internal::pow, internal::exp, internal::log, internal::sin, internal::cos,
- * - internal::conj, internal::real, internal::imag, internal::abs2.
+ * - internal::abs, internal::sqrt, numext::pow, internal::exp, internal::log, internal::sin, internal::cos,
+ * - internal::conj, internal::real, internal::imag, numext::abs2.
*
* AutoDiffScalar can be used as the scalar type of an Eigen::Matrix object. However,
* in that case, the expression template mechanism only occurs at the top Matrix level,
@@ -549,7 +549,7 @@ EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs,
return ReturnType(abs(x.value()), x.derivatives() * (x.value()<0 ? -1 : 1) );)
EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs2,
- using internal::abs2;
+ using numext::abs2;
return ReturnType(abs2(x.value()), x.derivatives() * (Scalar(2)*x.value()));)
EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sqrt,
@@ -612,17 +612,17 @@ atan2(const AutoDiffScalar<DerTypeA>& a, const AutoDiffScalar<DerTypeB>& b)
EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(tan,
using std::tan;
using std::cos;
- return ReturnType(tan(x.value()),x.derivatives() * (Scalar(1)/internal::abs2(cos(x.value()))));)
+ return ReturnType(tan(x.value()),x.derivatives() * (Scalar(1)/numext::abs2(cos(x.value()))));)
EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(asin,
using std::sqrt;
using std::asin;
- return ReturnType(asin(x.value()),x.derivatives() * (Scalar(1)/sqrt(1-internal::abs2(x.value()))));)
+ return ReturnType(asin(x.value()),x.derivatives() * (Scalar(1)/sqrt(1-numext::abs2(x.value()))));)
EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(acos,
using std::sqrt;
using std::acos;
- return ReturnType(acos(x.value()),x.derivatives() * (Scalar(-1)/sqrt(1-internal::abs2(x.value()))));)
+ return ReturnType(acos(x.value()),x.derivatives() * (Scalar(-1)/sqrt(1-numext::abs2(x.value()))));)
#undef EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY
diff --git a/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h b/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h
index 0540add0a..8c2d04830 100644
--- a/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h
+++ b/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h
@@ -21,8 +21,8 @@ namespace Eigen {
*
* It supports the following list of global math function:
* - std::abs, std::sqrt, std::pow, std::exp, std::log, std::sin, std::cos,
- * - internal::abs, internal::sqrt, internal::pow, internal::exp, internal::log, internal::sin, internal::cos,
- * - internal::conj, internal::real, internal::imag, internal::abs2.
+ * - internal::abs, internal::sqrt, numext::pow, internal::exp, internal::log, internal::sin, internal::cos,
+ * - internal::conj, internal::real, internal::imag, numext::abs2.
*
* AutoDiffScalar can be used as the scalar type of an Eigen::Matrix object. However,
* in that case, the expression template mechanism only occurs at the top Matrix level,
diff --git a/unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h b/unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h
index 68b5dd5cc..3b6a69aff 100644
--- a/unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h
+++ b/unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h
@@ -25,7 +25,7 @@
#ifndef EIGEN_ARPACKGENERALIZEDSELFADJOINTEIGENSOLVER_H
#define EIGEN_ARPACKGENERALIZEDSELFADJOINTEIGENSOLVER_H
-
+#include <Eigen/Dense>
namespace Eigen {
@@ -337,6 +337,8 @@ ArpackGeneralizedSelfAdjointEigenSolver<MatrixType, MatrixSolver, BisSPD>&
{
MatrixType B(0,0);
compute(A, B, nbrEigenvalues, eigs_sigma, options, tol);
+
+ return *this;
}
@@ -681,7 +683,9 @@ template<typename Scalar, typename RealScalar> struct arpack_wrapper
int *nev, RealScalar *tol, Scalar *resid, int *ncv,
Scalar *v, int *ldv, int *iparam, int *ipntr,
Scalar *workd, Scalar *workl, int *lworkl, int *info)
- { EIGEN_STATIC_ASSERT(false, static_assertion<true>::NUMERIC_TYPE_MUST_BE_REAL); }
+ {
+ EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::IsComplex, NUMERIC_TYPE_MUST_BE_REAL)
+ }
static inline void seupd(int *rvec, char *All, int *select, Scalar *d,
Scalar *z, int *ldz, RealScalar *sigma,
@@ -689,7 +693,9 @@ template<typename Scalar, typename RealScalar> struct arpack_wrapper
RealScalar *tol, Scalar *resid, int *ncv, Scalar *v,
int *ldv, int *iparam, int *ipntr, Scalar *workd,
Scalar *workl, int *lworkl, int *ierr)
- { EIGEN_STATIC_ASSERT(false, static_assertion<true>::NUMERIC_TYPE_MUST_BE_REAL); }
+ {
+ EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::IsComplex, NUMERIC_TYPE_MUST_BE_REAL)
+ }
};
template <> struct arpack_wrapper<float, float>
diff --git a/unsupported/Eigen/src/IterativeSolvers/DGMRES.h b/unsupported/Eigen/src/IterativeSolvers/DGMRES.h
index 7b5b5a91b..9fcc8a8d9 100644
--- a/unsupported/Eigen/src/IterativeSolvers/DGMRES.h
+++ b/unsupported/Eigen/src/IterativeSolvers/DGMRES.h
@@ -539,4 +539,4 @@ struct solve_retval<DGMRES<_MatrixType, _Preconditioner>, Rhs>
} // end namespace internal
} // end namespace Eigen
-#endif \ No newline at end of file
+#endif
diff --git a/unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h b/unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h
index 60584c523..25b32ec5b 100644
--- a/unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h
+++ b/unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h
@@ -109,13 +109,13 @@ LevenbergMarquardt<FunctorType>::minimizeOneStep(FVectorType &x)
/* compute the scaled actual reduction. */
actred = -1.;
if (Scalar(.1) * fnorm1 < m_fnorm)
- actred = 1. - internal::abs2(fnorm1 / m_fnorm);
+ actred = 1. - numext::abs2(fnorm1 / m_fnorm);
/* compute the scaled predicted reduction and */
/* the scaled directional derivative. */
m_wa3 = m_rfactor.template triangularView<Upper>() * (m_permutation.inverse() *m_wa1);
- temp1 = internal::abs2(m_wa3.stableNorm() / m_fnorm);
- temp2 = internal::abs2(sqrt(m_par) * pnorm / m_fnorm);
+ temp1 = numext::abs2(m_wa3.stableNorm() / m_fnorm);
+ temp2 = numext::abs2(sqrt(m_par) * pnorm / m_fnorm);
prered = temp1 + temp2 / Scalar(.5);
dirder = -(temp1 + temp2);
diff --git a/unsupported/Eigen/src/LevenbergMarquardt/LevenbergMarquardt.h b/unsupported/Eigen/src/LevenbergMarquardt/LevenbergMarquardt.h
index 8d5538d69..51dd1d3c4 100644
--- a/unsupported/Eigen/src/LevenbergMarquardt/LevenbergMarquardt.h
+++ b/unsupported/Eigen/src/LevenbergMarquardt/LevenbergMarquardt.h
@@ -107,7 +107,7 @@ void lmpar2(const QRSolver &qr, const VectorType &diag, const VectorType &qtb,
* http://en.wikipedia.org/wiki/Levenberg%E2%80%93Marquardt_algorithm
*/
template<typename _FunctorType>
-class LevenbergMarquardt
+class LevenbergMarquardt : internal::no_assignment_operator
{
public:
typedef _FunctorType FunctorType;
@@ -302,8 +302,8 @@ LevenbergMarquardt<FunctorType>::minimizeInit(FVectorType &x)
for (Index j = 0; j < n; ++j)
if (m_diag[j] <= 0.)
{
- return LevenbergMarquardtSpace::ImproperInputParameters;
m_info = InvalidInput;
+ return LevenbergMarquardtSpace::ImproperInputParameters;
}
/* evaluate the function at the starting point */
diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h b/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h
index b00e5e921..c744fc05f 100644
--- a/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h
+++ b/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h
@@ -116,7 +116,7 @@ void MatrixLogarithmAtomic<MatrixType>::compute2x2(const MatrixType& A, MatrixTy
// computation in previous branch is inaccurate if A(1,1) \approx A(0,0)
int unwindingNumber = static_cast<int>(ceil((imag(logA11 - logA00) - M_PI) / (2*M_PI)));
Scalar y = A(1,1) - A(0,0), x = A(1,1) + A(0,0);
- result(0,1) = A(0,1) * (Scalar(2) * internal::atanh2(y,x) + Scalar(0,2*M_PI*unwindingNumber)) / y;
+ result(0,1) = A(0,1) * (Scalar(2) * numext::atanh2(y,x) + Scalar(0,2*M_PI*unwindingNumber)) / y;
}
}
diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h b/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h
index e75fc25b4..c32437281 100644
--- a/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h
+++ b/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h
@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
-// Copyright (C) 2012 Chen-Pang He <jdh8@ms63.hinet.net>
+// Copyright (C) 2012, 2013 Chen-Pang He <jdh8@ms63.hinet.net>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
@@ -12,221 +12,244 @@
namespace Eigen {
-/**
- * \ingroup MatrixFunctions_Module
- *
- * \brief Class for computing matrix powers.
- *
- * \tparam MatrixType type of the base, expected to be an instantiation
- * of the Matrix class template.
- *
- * This class is capable of computing upper triangular matrices raised
- * to an arbitrary real power.
- */
+template<typename MatrixType> class MatrixPower;
+
template<typename MatrixType>
-class MatrixPowerTriangular : public MatrixPowerBase<MatrixPowerTriangular<MatrixType>,MatrixType>
+class MatrixPowerRetval : public ReturnByValue< MatrixPowerRetval<MatrixType> >
{
public:
- EIGEN_MATRIX_POWER_PUBLIC_INTERFACE(MatrixPowerTriangular)
+ typedef typename MatrixType::RealScalar RealScalar;
+ typedef typename MatrixType::Index Index;
- /**
- * \brief Constructor.
- *
- * \param[in] A the base of the matrix power.
- *
- * The class stores a reference to A, so it should not be changed
- * (or destroyed) before evaluation.
- */
- explicit MatrixPowerTriangular(const MatrixType& A) : Base(A), m_T(Base::m_A)
+ MatrixPowerRetval(MatrixPower<MatrixType>& pow, RealScalar p) : m_pow(pow), m_p(p)
{ }
- #ifdef EIGEN_PARSED_BY_DOXYGEN
- /**
- * \brief Returns the matrix power.
- *
- * \param[in] p exponent, a real scalar.
- * \return The expression \f$ A^p \f$, where A is specified in the
- * constructor.
- */
- const MatrixPowerBaseReturnValue<MatrixPowerTriangular<MatrixType>,MatrixType> operator()(RealScalar p);
- #endif
-
- /**
- * \brief Compute the matrix power.
- *
- * \param[in] p exponent, a real scalar.
- * \param[out] res \f$ A^p \f$ where A is specified in the
- * constructor.
- */
- void compute(MatrixType& res, RealScalar p);
+ template<typename ResultType>
+ inline void evalTo(ResultType& res) const
+ { m_pow.compute(res, m_p); }
- /**
- * \brief Compute the matrix power multiplied by another matrix.
- *
- * \param[in] b a matrix with the same rows as A.
- * \param[in] p exponent, a real scalar.
- * \param[out] res \f$ A^p b \f$, where A is specified in the
- * constructor.
- */
- template<typename Derived, typename ResultType>
- void compute(const Derived& b, ResultType& res, RealScalar p);
+ Index rows() const { return m_pow.rows(); }
+ Index cols() const { return m_pow.cols(); }
private:
- EIGEN_MATRIX_POWER_PROTECTED_MEMBERS(MatrixPowerTriangular)
-
- const TriangularView<MatrixType,Upper> m_T;
-
- RealScalar modfAndInit(RealScalar, RealScalar*);
-
- template<typename Derived, typename ResultType>
- void apply(const Derived&, ResultType&, bool&);
-
- template<typename ResultType>
- void computeIntPower(ResultType&, RealScalar);
+ MatrixPower<MatrixType>& m_pow;
+ const RealScalar m_p;
+ MatrixPowerRetval& operator=(const MatrixPowerRetval&);
+};
- template<typename Derived, typename ResultType>
- void computeIntPower(const Derived&, ResultType&, RealScalar);
+template<typename MatrixType>
+class MatrixPowerAtomic
+{
+ private:
+ enum {
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime
+ };
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::RealScalar RealScalar;
+ typedef std::complex<RealScalar> ComplexScalar;
+ typedef typename MatrixType::Index Index;
+ typedef Array<Scalar, RowsAtCompileTime, 1, ColMajor, MaxRowsAtCompileTime> ArrayType;
+
+ const MatrixType& m_A;
+ RealScalar m_p;
+
+ void computePade(int degree, const MatrixType& IminusT, MatrixType& res) const;
+ void compute2x2(MatrixType& res, RealScalar p) const;
+ void computeBig(MatrixType& res) const;
+ static int getPadeDegree(float normIminusT);
+ static int getPadeDegree(double normIminusT);
+ static int getPadeDegree(long double normIminusT);
+ static ComplexScalar computeSuperDiag(const ComplexScalar&, const ComplexScalar&, RealScalar p);
+ static RealScalar computeSuperDiag(RealScalar, RealScalar, RealScalar p);
- template<typename ResultType>
- void computeFracPower(ResultType&, RealScalar);
+ public:
+ MatrixPowerAtomic(const MatrixType& T, RealScalar p);
+ void compute(MatrixType& res) const;
};
template<typename MatrixType>
-void MatrixPowerTriangular<MatrixType>::compute(MatrixType& res, RealScalar p)
+MatrixPowerAtomic<MatrixType>::MatrixPowerAtomic(const MatrixType& T, RealScalar p) :
+ m_A(T), m_p(p)
+{ eigen_assert(T.rows() == T.cols()); }
+
+template<typename MatrixType>
+void MatrixPowerAtomic<MatrixType>::compute(MatrixType& res) const
{
- switch (m_A.cols()) {
+ res.resizeLike(m_A);
+ switch (m_A.rows()) {
case 0:
break;
case 1:
- res(0,0) = std::pow(m_T.coeff(0,0), p);
+ res(0,0) = std::pow(m_A(0,0), m_p);
+ break;
+ case 2:
+ compute2x2(res, m_p);
break;
default:
- RealScalar intpart, x = modfAndInit(p, &intpart);
- res = MatrixType::Identity(m_A.rows(), m_A.cols());
- computeIntPower(res, intpart);
- computeFracPower(res, x);
+ computeBig(res);
}
}
template<typename MatrixType>
-template<typename Derived, typename ResultType>
-void MatrixPowerTriangular<MatrixType>::compute(const Derived& b, ResultType& res, RealScalar p)
+void MatrixPowerAtomic<MatrixType>::computePade(int degree, const MatrixType& IminusT, MatrixType& res) const
{
- switch (m_A.cols()) {
- case 0:
- break;
- case 1:
- res = std::pow(m_T.coeff(0,0), p) * b;
- break;
- default:
- RealScalar intpart, x = modfAndInit(p, &intpart);
- computeIntPower(b, res, intpart);
- computeFracPower(res, x);
+ int i = degree<<1;
+ res = (m_p-degree) / ((i-1)<<1) * IminusT;
+ for (--i; i; --i) {
+ res = (MatrixType::Identity(IminusT.rows(), IminusT.cols()) + res).template triangularView<Upper>()
+ .solve((i==1 ? -m_p : i&1 ? (-m_p-(i>>1))/(i<<1) : (m_p-(i>>1))/((i-1)<<1)) * IminusT).eval();
}
+ res += MatrixType::Identity(IminusT.rows(), IminusT.cols());
}
+// This function assumes that res has the correct size (see bug 614)
template<typename MatrixType>
-typename MatrixPowerTriangular<MatrixType>::RealScalar
-MatrixPowerTriangular<MatrixType>::modfAndInit(RealScalar x, RealScalar* intpart)
+void MatrixPowerAtomic<MatrixType>::compute2x2(MatrixType& res, RealScalar p) const
{
- *intpart = std::floor(x);
- RealScalar res = x - *intpart;
+ using std::abs;
+ using std::pow;
+
+ ArrayType logTdiag = m_A.diagonal().array().log();
+ res.coeffRef(0,0) = pow(m_A.coeff(0,0), p);
+
+ for (Index i=1; i < m_A.cols(); ++i) {
+ res.coeffRef(i,i) = pow(m_A.coeff(i,i), p);
+ if (m_A.coeff(i-1,i-1) == m_A.coeff(i,i))
+ res.coeffRef(i-1,i) = p * pow(m_A.coeff(i,i), p-1);
+ else if (2*abs(m_A.coeff(i-1,i-1)) < abs(m_A.coeff(i,i)) || 2*abs(m_A.coeff(i,i)) < abs(m_A.coeff(i-1,i-1)))
+ res.coeffRef(i-1,i) = (res.coeff(i,i)-res.coeff(i-1,i-1)) / (m_A.coeff(i,i)-m_A.coeff(i-1,i-1));
+ else
+ res.coeffRef(i-1,i) = computeSuperDiag(m_A.coeff(i,i), m_A.coeff(i-1,i-1), p);
+ res.coeffRef(i-1,i) *= m_A.coeff(i-1,i);
+ }
+}
- if (!m_conditionNumber && res) {
- const RealArray absTdiag = m_A.diagonal().array().abs();
- m_conditionNumber = absTdiag.maxCoeff() / absTdiag.minCoeff();
+template<typename MatrixType>
+void MatrixPowerAtomic<MatrixType>::computeBig(MatrixType& res) const
+{
+ const int digits = std::numeric_limits<RealScalar>::digits;
+ const RealScalar maxNormForPade = digits <= 24? 4.3386528e-1f: // sigle precision
+ digits <= 53? 2.789358995219730e-1: // double precision
+ digits <= 64? 2.4471944416607995472e-1L: // extended precision
+ digits <= 106? 1.1016843812851143391275867258512e-1L: // double-double
+ 9.134603732914548552537150753385375e-2L; // quadruple precision
+ MatrixType IminusT, sqrtT, T = m_A.template triangularView<Upper>();
+ RealScalar normIminusT;
+ int degree, degree2, numberOfSquareRoots = 0;
+ bool hasExtraSquareRoot = false;
+
+ /* FIXME
+ * For singular T, norm(I - T) >= 1 but maxNormForPade < 1, leads to infinite
+ * loop. We should move 0 eigenvalues to bottom right corner. We need not
+ * worry about tiny values (e.g. 1e-300) because they will reach 1 if
+ * repetitively sqrt'ed.
+ *
+ * If the 0 eigenvalues are semisimple, they can form a 0 matrix at the
+ * bottom right corner.
+ *
+ * [ T A ]^p [ T^p (T^-1 T^p A) ]
+ * [ ] = [ ]
+ * [ 0 0 ] [ 0 0 ]
+ */
+ for (Index i=0; i < m_A.cols(); ++i)
+ eigen_assert(m_A(i,i) != RealScalar(0));
+
+ while (true) {
+ IminusT = MatrixType::Identity(m_A.rows(), m_A.cols()) - T;
+ normIminusT = IminusT.cwiseAbs().colwise().sum().maxCoeff();
+ if (normIminusT < maxNormForPade) {
+ degree = getPadeDegree(normIminusT);
+ degree2 = getPadeDegree(normIminusT/2);
+ if (degree - degree2 <= 1 || hasExtraSquareRoot)
+ break;
+ hasExtraSquareRoot = true;
+ }
+ MatrixSquareRootTriangular<MatrixType>(T).compute(sqrtT);
+ T = sqrtT.template triangularView<Upper>();
+ ++numberOfSquareRoots;
}
+ computePade(degree, IminusT, res);
- if (res>RealScalar(0.5) && res>(1-res)*std::pow(m_conditionNumber,res)) {
- --res;
- ++*intpart;
+ for (; numberOfSquareRoots; --numberOfSquareRoots) {
+ compute2x2(res, std::ldexp(m_p, -numberOfSquareRoots));
+ res = res.template triangularView<Upper>() * res;
}
- return res;
+ compute2x2(res, m_p);
}
-
+
template<typename MatrixType>
-template<typename Derived, typename ResultType>
-void MatrixPowerTriangular<MatrixType>::apply(const Derived& b, ResultType& res, bool& init)
+inline int MatrixPowerAtomic<MatrixType>::getPadeDegree(float normIminusT)
{
- if (init)
- res = m_tmp1.template triangularView<Upper>() * res;
- else {
- init = true;
- res.noalias() = m_tmp1.template triangularView<Upper>() * b;
- }
+ const float maxNormForPade[] = { 2.8064004e-1f /* degree = 3 */ , 4.3386528e-1f };
+ int degree = 3;
+ for (; degree <= 4; ++degree)
+ if (normIminusT <= maxNormForPade[degree - 3])
+ break;
+ return degree;
}
template<typename MatrixType>
-template<typename ResultType>
-void MatrixPowerTriangular<MatrixType>::computeIntPower(ResultType& res, RealScalar p)
+inline int MatrixPowerAtomic<MatrixType>::getPadeDegree(double normIminusT)
{
- RealScalar pp = std::abs(p);
-
- if (p<0) m_tmp1 = m_T.solve(MatrixType::Identity(m_A.rows(), m_A.cols()));
- else m_tmp1 = m_T;
-
- while (pp >= 1) {
- if (std::fmod(pp, 2) >= 1)
- res = m_tmp1.template triangularView<Upper>() * res;
- m_tmp1 = m_tmp1.template triangularView<Upper>() * m_tmp1;
- pp /= 2;
- }
+ const double maxNormForPade[] = { 1.884160592658218e-2 /* degree = 3 */ , 6.038881904059573e-2, 1.239917516308172e-1,
+ 1.999045567181744e-1, 2.789358995219730e-1 };
+ int degree = 3;
+ for (; degree <= 7; ++degree)
+ if (normIminusT <= maxNormForPade[degree - 3])
+ break;
+ return degree;
}
template<typename MatrixType>
-template<typename Derived, typename ResultType>
-void MatrixPowerTriangular<MatrixType>::computeIntPower(const Derived& b, ResultType& res, RealScalar p)
+inline int MatrixPowerAtomic<MatrixType>::getPadeDegree(long double normIminusT)
{
- if (b.cols() >= m_A.cols()) {
- m_tmp2 = MatrixType::Identity(m_A.rows(), m_A.cols());
- computeIntPower(m_tmp2, p);
- res.noalias() = m_tmp2.template triangularView<Upper>() * b;
- }
- else {
- RealScalar pp = std::abs(p);
- int squarings, applyings = internal::binary_powering_cost(pp, &squarings);
- bool init = false;
-
- if (p==0) {
- res = b;
- return;
- }
- else if (p>0) {
- m_tmp1 = m_T;
- }
- else if (b.cols()*(pp-applyings) <= m_A.cols()*squarings) {
- res = m_T.solve(b);
- for (--pp; pp >= 1; --pp)
- res = m_T.solve(res);
- return;
- }
- else {
- m_tmp1 = m_T.solve(MatrixType::Identity(m_A.rows(), m_A.cols()));
- }
+#if LDBL_MANT_DIG == 53
+ const int maxPadeDegree = 7;
+ const double maxNormForPade[] = { 1.884160592658218e-2L /* degree = 3 */ , 6.038881904059573e-2L, 1.239917516308172e-1L,
+ 1.999045567181744e-1L, 2.789358995219730e-1L };
+#elif LDBL_MANT_DIG <= 64
+ const int maxPadeDegree = 8;
+ const double maxNormForPade[] = { 6.3854693117491799460e-3L /* degree = 3 */ , 2.6394893435456973676e-2L,
+ 6.4216043030404063729e-2L, 1.1701165502926694307e-1L, 1.7904284231268670284e-1L, 2.4471944416607995472e-1L };
+#elif LDBL_MANT_DIG <= 106
+ const int maxPadeDegree = 10;
+ const double maxNormForPade[] = { 1.0007161601787493236741409687186e-4L /* degree = 3 */ ,
+ 1.0007161601787493236741409687186e-3L, 4.7069769360887572939882574746264e-3L, 1.3220386624169159689406653101695e-2L,
+ 2.8063482381631737920612944054906e-2L, 4.9625993951953473052385361085058e-2L, 7.7367040706027886224557538328171e-2L,
+ 1.1016843812851143391275867258512e-1L };
+#else
+ const int maxPadeDegree = 10;
+ const double maxNormForPade[] = { 5.524506147036624377378713555116378e-5L /* degree = 3 */ ,
+ 6.640600568157479679823602193345995e-4L, 3.227716520106894279249709728084626e-3L,
+ 9.619593944683432960546978734646284e-3L, 2.134595382433742403911124458161147e-2L,
+ 3.908166513900489428442993794761185e-2L, 6.266780814639442865832535460550138e-2L,
+ 9.134603732914548552537150753385375e-2L };
+#endif
+ int degree = 3;
+ for (; degree <= maxPadeDegree; ++degree)
+ if (normIminusT <= maxNormForPade[degree - 3])
+ break;
+ return degree;
+}
- while (b.cols()*(pp-applyings) > m_A.cols()*squarings) {
- if (std::fmod(pp, 2) >= 1) {
- apply(b, res, init);
- --applyings;
- }
- m_tmp1 = m_tmp1.template triangularView<Upper>() * m_tmp1;
- --squarings;
- pp /= 2;
- }
- for (; pp >= 1; --pp)
- apply(b, res, init);
- }
+template<typename MatrixType>
+inline typename MatrixPowerAtomic<MatrixType>::ComplexScalar
+MatrixPowerAtomic<MatrixType>::computeSuperDiag(const ComplexScalar& curr, const ComplexScalar& prev, RealScalar p)
+{
+ ComplexScalar logCurr = std::log(curr);
+ ComplexScalar logPrev = std::log(prev);
+ int unwindingNumber = std::ceil((numext::imag(logCurr - logPrev) - M_PI) / (2*M_PI));
+ ComplexScalar w = numext::atanh2(curr - prev, curr + prev) + ComplexScalar(0, M_PI*unwindingNumber);
+ return RealScalar(2) * std::exp(RealScalar(0.5) * p * (logCurr + logPrev)) * std::sinh(p * w) / (curr - prev);
}
template<typename MatrixType>
-template<typename ResultType>
-void MatrixPowerTriangular<MatrixType>::computeFracPower(ResultType& res, RealScalar p)
+inline typename MatrixPowerAtomic<MatrixType>::RealScalar
+MatrixPowerAtomic<MatrixType>::computeSuperDiag(RealScalar curr, RealScalar prev, RealScalar p)
{
- if (p) {
- eigen_assert(m_conditionNumber);
- MatrixPowerTriangularAtomic<MatrixType>(m_A).compute(m_tmp1, p);
- res = m_tmp1.template triangularView<Upper>() * res;
- }
+ RealScalar w = numext::atanh2(curr - prev, curr + prev);
+ return 2 * std::exp(p * (std::log(curr) + std::log(prev)) / 2) * std::sinh(p * w) / (curr - prev);
}
/**
@@ -249,11 +272,20 @@ void MatrixPowerTriangular<MatrixType>::computeFracPower(ResultType& res, RealSc
* Output: \verbinclude MatrixPower_optimal.out
*/
template<typename MatrixType>
-class MatrixPower : public MatrixPowerBase<MatrixPower<MatrixType>,MatrixType>
+class MatrixPower
{
- public:
- EIGEN_MATRIX_POWER_PUBLIC_INTERFACE(MatrixPower)
+ private:
+ enum {
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
+ ColsAtCompileTime = MatrixType::ColsAtCompileTime,
+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
+ };
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::RealScalar RealScalar;
+ typedef typename MatrixType::Index Index;
+ public:
/**
* \brief Constructor.
*
@@ -262,10 +294,9 @@ class MatrixPower : public MatrixPowerBase<MatrixPower<MatrixType>,MatrixType>
* The class stores a reference to A, so it should not be changed
* (or destroyed) before evaluation.
*/
- explicit MatrixPower(const MatrixType& A) : Base(A)
- { }
+ explicit MatrixPower(const MatrixType& A) : m_A(A), m_conditionNumber(0)
+ { eigen_assert(A.rows() == A.cols()); }
- #ifdef EIGEN_PARSED_BY_DOXYGEN
/**
* \brief Returns the matrix power.
*
@@ -273,8 +304,8 @@ class MatrixPower : public MatrixPowerBase<MatrixPower<MatrixType>,MatrixType>
* \return The expression \f$ A^p \f$, where A is specified in the
* constructor.
*/
- const MatrixPowerBaseReturnValue<MatrixPower<MatrixType>,MatrixType> operator()(RealScalar p);
- #endif
+ const MatrixPowerRetval<MatrixType> operator()(RealScalar p)
+ { return MatrixPowerRetval<MatrixType>(*this, p); }
/**
* \brief Compute the matrix power.
@@ -283,46 +314,48 @@ class MatrixPower : public MatrixPowerBase<MatrixPower<MatrixType>,MatrixType>
* \param[out] res \f$ A^p \f$ where A is specified in the
* constructor.
*/
- void compute(MatrixType& res, RealScalar p);
-
- /**
- * \brief Compute the matrix power multiplied by another matrix.
- *
- * \param[in] b a matrix with the same rows as A.
- * \param[in] p exponent, a real scalar.
- * \param[out] res \f$ A^p b \f$, where A is specified in the
- * constructor.
- */
- template<typename Derived, typename ResultType>
- void compute(const Derived& b, ResultType& res, RealScalar p);
+ template<typename ResultType>
+ void compute(ResultType& res, RealScalar p);
+
+ Index rows() const { return m_A.rows(); }
+ Index cols() const { return m_A.cols(); }
private:
- EIGEN_MATRIX_POWER_PROTECTED_MEMBERS(MatrixPower)
+ typedef std::complex<RealScalar> ComplexScalar;
+ typedef Matrix<ComplexScalar, RowsAtCompileTime, ColsAtCompileTime, MatrixType::Options,
+ MaxRowsAtCompileTime, MaxColsAtCompileTime> ComplexMatrix;
- typedef Matrix<std::complex<RealScalar>, RowsAtCompileTime, ColsAtCompileTime,
- Options,MaxRowsAtCompileTime,MaxColsAtCompileTime> ComplexMatrix;
- static const bool m_OKforLU = RowsAtCompileTime == Dynamic || RowsAtCompileTime > 4;
+ typename MatrixType::Nested m_A;
+ MatrixType m_tmp;
ComplexMatrix m_T, m_U, m_fT;
+ RealScalar m_conditionNumber;
RealScalar modfAndInit(RealScalar, RealScalar*);
- template<typename Derived, typename ResultType>
- void apply(const Derived&, ResultType&, bool&);
-
template<typename ResultType>
void computeIntPower(ResultType&, RealScalar);
- template<typename Derived, typename ResultType>
- void computeIntPower(const Derived&, ResultType&, RealScalar);
-
template<typename ResultType>
void computeFracPower(ResultType&, RealScalar);
+
+ template<int Rows, int Cols, int Options, int MaxRows, int MaxCols>
+ static void revertSchur(
+ Matrix<ComplexScalar, Rows, Cols, Options, MaxRows, MaxCols>& res,
+ const ComplexMatrix& T,
+ const ComplexMatrix& U);
+
+ template<int Rows, int Cols, int Options, int MaxRows, int MaxCols>
+ static void revertSchur(
+ Matrix<RealScalar, Rows, Cols, Options, MaxRows, MaxCols>& res,
+ const ComplexMatrix& T,
+ const ComplexMatrix& U);
};
template<typename MatrixType>
-void MatrixPower<MatrixType>::compute(MatrixType& res, RealScalar p)
+template<typename ResultType>
+void MatrixPower<MatrixType>::compute(ResultType& res, RealScalar p)
{
- switch (m_A.cols()) {
+ switch (cols()) {
case 0:
break;
case 1:
@@ -330,32 +363,17 @@ void MatrixPower<MatrixType>::compute(MatrixType& res, RealScalar p)
break;
default:
RealScalar intpart, x = modfAndInit(p, &intpart);
- res = MatrixType::Identity(m_A.rows(), m_A.cols());
computeIntPower(res, intpart);
computeFracPower(res, x);
}
}
template<typename MatrixType>
-template<typename Derived, typename ResultType>
-void MatrixPower<MatrixType>::compute(const Derived& b, ResultType& res, RealScalar p)
+typename MatrixPower<MatrixType>::RealScalar
+MatrixPower<MatrixType>::modfAndInit(RealScalar x, RealScalar* intpart)
{
- switch (m_A.cols()) {
- case 0:
- break;
- case 1:
- res = std::pow(m_A.coeff(0,0), p) * b;
- break;
- default:
- RealScalar intpart, x = modfAndInit(p, &intpart);
- computeIntPower(b, res, intpart);
- computeFracPower(res, x);
- }
-}
+ typedef Array<RealScalar, RowsAtCompileTime, 1, ColMajor, MaxRowsAtCompileTime> RealArray;
-template<typename MatrixType>
-typename MatrixPower<MatrixType>::RealScalar MatrixPower<MatrixType>::modfAndInit(RealScalar x, RealScalar* intpart)
-{
*intpart = std::floor(x);
RealScalar res = x - *intpart;
@@ -376,99 +394,50 @@ typename MatrixPower<MatrixType>::RealScalar MatrixPower<MatrixType>::modfAndIni
}
template<typename MatrixType>
-template<typename Derived, typename ResultType>
-void MatrixPower<MatrixType>::apply(const Derived& b, ResultType& res, bool& init)
-{
- if (init)
- res = m_tmp1 * res;
- else {
- init = true;
- res.noalias() = m_tmp1 * b;
- }
-}
-
-template<typename MatrixType>
template<typename ResultType>
void MatrixPower<MatrixType>::computeIntPower(ResultType& res, RealScalar p)
{
RealScalar pp = std::abs(p);
- if (p<0) m_tmp1 = m_A.inverse();
- else m_tmp1 = m_A;
+ if (p<0) m_tmp = m_A.inverse();
+ else m_tmp = m_A;
+ res = MatrixType::Identity(rows(), cols());
while (pp >= 1) {
if (std::fmod(pp, 2) >= 1)
- res = m_tmp1 * res;
- m_tmp1 *= m_tmp1;
+ res = m_tmp * res;
+ m_tmp *= m_tmp;
pp /= 2;
}
}
template<typename MatrixType>
-template<typename Derived, typename ResultType>
-void MatrixPower<MatrixType>::computeIntPower(const Derived& b, ResultType& res, RealScalar p)
-{
- if (b.cols() >= m_A.cols()) {
- m_tmp2 = MatrixType::Identity(m_A.rows(), m_A.cols());
- computeIntPower(m_tmp2, p);
- res.noalias() = m_tmp2 * b;
- }
- else {
- RealScalar pp = std::abs(p);
- int squarings, applyings = internal::binary_powering_cost(pp, &squarings);
- bool init = false;
-
- if (p==0) {
- res = b;
- return;
- }
- else if (p>0) {
- m_tmp1 = m_A;
- }
- else if (m_OKforLU && b.cols()*(pp-applyings) <= m_A.cols()*squarings) {
- PartialPivLU<MatrixType> A(m_A);
- res = A.solve(b);
- for (--pp; pp >= 1; --pp)
- res = A.solve(res);
- return;
- }
- else {
- m_tmp1 = m_A.inverse();
- }
-
- while (b.cols()*(pp-applyings) > m_A.cols()*squarings) {
- if (std::fmod(pp, 2) >= 1) {
- apply(b, res, init);
- --applyings;
- }
- m_tmp1 *= m_tmp1;
- --squarings;
- pp /= 2;
- }
- for (; pp >= 1; --pp)
- apply(b, res, init);
- }
-}
-
-template<typename MatrixType>
template<typename ResultType>
void MatrixPower<MatrixType>::computeFracPower(ResultType& res, RealScalar p)
{
if (p) {
eigen_assert(m_conditionNumber);
- MatrixPowerTriangularAtomic<ComplexMatrix>(m_T).compute(m_fT, p);
- internal::recompose_complex_schur<NumTraits<Scalar>::IsComplex>::run(m_tmp1, m_fT, m_U);
- res = m_tmp1 * res;
+ MatrixPowerAtomic<ComplexMatrix>(m_T, p).compute(m_fT);
+ revertSchur(m_tmp, m_fT, m_U);
+ res = m_tmp * res;
}
}
-namespace internal {
-
-template<typename Derived>
-struct traits<MatrixPowerReturnValue<Derived> >
-{ typedef typename Derived::PlainObject ReturnType; };
+template<typename MatrixType>
+template<int Rows, int Cols, int Options, int MaxRows, int MaxCols>
+inline void MatrixPower<MatrixType>::revertSchur(
+ Matrix<ComplexScalar, Rows, Cols, Options, MaxRows, MaxCols>& res,
+ const ComplexMatrix& T,
+ const ComplexMatrix& U)
+{ res.noalias() = U * (T.template triangularView<Upper>() * U.adjoint()); }
-} // namespace internal
+template<typename MatrixType>
+template<int Rows, int Cols, int Options, int MaxRows, int MaxCols>
+inline void MatrixPower<MatrixType>::revertSchur(
+ Matrix<RealScalar, Rows, Cols, Options, MaxRows, MaxCols>& res,
+ const ComplexMatrix& T,
+ const ComplexMatrix& U)
+{ res.noalias() = (U * (T.template triangularView<Upper>() * U.adjoint())).real(); }
/**
* \ingroup MatrixFunctions_Module
@@ -484,7 +453,7 @@ struct traits<MatrixPowerReturnValue<Derived> >
* time this is the only way it is used.
*/
template<typename Derived>
-class MatrixPowerReturnValue : public ReturnByValue<MatrixPowerReturnValue<Derived> >
+class MatrixPowerReturnValue : public ReturnByValue< MatrixPowerReturnValue<Derived> >
{
public:
typedef typename Derived::PlainObject PlainObject;
@@ -510,21 +479,6 @@ class MatrixPowerReturnValue : public ReturnByValue<MatrixPowerReturnValue<Deriv
inline void evalTo(ResultType& res) const
{ MatrixPower<PlainObject>(m_A.eval()).compute(res, m_p); }
- /**
- * \brief Return the expression \f$ A^p b \f$.
- *
- * \p A and \p p are specified in the constructor.
- *
- * \param[in] b the matrix (expression) to be applied.
- */
- template<typename OtherDerived>
- const MatrixPowerProduct<MatrixPower<PlainObject>,PlainObject,OtherDerived>
- operator*(const MatrixBase<OtherDerived>& b) const
- {
- MatrixPower<PlainObject> Apow(m_A.eval());
- return MatrixPowerProduct<MatrixPower<PlainObject>,PlainObject,OtherDerived>(Apow, b.derived(), m_p);
- }
-
Index rows() const { return m_A.rows(); }
Index cols() const { return m_A.cols(); }
@@ -534,6 +488,18 @@ class MatrixPowerReturnValue : public ReturnByValue<MatrixPowerReturnValue<Deriv
MatrixPowerReturnValue& operator=(const MatrixPowerReturnValue&);
};
+namespace internal {
+
+template<typename MatrixPowerType>
+struct traits< MatrixPowerRetval<MatrixPowerType> >
+{ typedef typename MatrixPowerType::PlainObject ReturnType; };
+
+template<typename Derived>
+struct traits< MatrixPowerReturnValue<Derived> >
+{ typedef typename Derived::PlainObject ReturnType; };
+
+}
+
template<typename Derived>
const MatrixPowerReturnValue<Derived> MatrixBase<Derived>::pow(const RealScalar& p) const
{ return MatrixPowerReturnValue<Derived>(derived(), p); }
diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixPowerBase.h b/unsupported/Eigen/src/MatrixFunctions/MatrixPowerBase.h
deleted file mode 100644
index 890225744..000000000
--- a/unsupported/Eigen/src/MatrixFunctions/MatrixPowerBase.h
+++ /dev/null
@@ -1,388 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2012 Chen-Pang He <jdh8@ms63.hinet.net>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_MATRIX_POWER_BASE
-#define EIGEN_MATRIX_POWER_BASE
-
-namespace Eigen {
-
-#define EIGEN_MATRIX_POWER_PUBLIC_INTERFACE(Derived) \
- typedef MatrixPowerBase<Derived, MatrixType> Base; \
- using Base::RowsAtCompileTime; \
- using Base::ColsAtCompileTime; \
- using Base::Options; \
- using Base::MaxRowsAtCompileTime; \
- using Base::MaxColsAtCompileTime; \
- typedef typename Base::Scalar Scalar; \
- typedef typename Base::RealScalar RealScalar; \
- typedef typename Base::RealArray RealArray;
-
-#define EIGEN_MATRIX_POWER_PROTECTED_MEMBERS(Derived) \
- using Base::m_A; \
- using Base::m_tmp1; \
- using Base::m_tmp2; \
- using Base::m_conditionNumber;
-
-template<typename Derived, typename MatrixType>
-class MatrixPowerBaseReturnValue : public ReturnByValue<MatrixPowerBaseReturnValue<Derived,MatrixType> >
-{
- public:
- typedef typename MatrixType::RealScalar RealScalar;
- typedef typename MatrixType::Index Index;
-
- MatrixPowerBaseReturnValue(Derived& pow, RealScalar p) : m_pow(pow), m_p(p)
- { }
-
- template<typename ResultType>
- inline void evalTo(ResultType& res) const
- { m_pow.compute(res, m_p); }
-
- template<typename OtherDerived>
- const MatrixPowerProduct<Derived,MatrixType,OtherDerived> operator*(const MatrixBase<OtherDerived>& b) const
- { return MatrixPowerProduct<Derived,MatrixType,OtherDerived>(m_pow, b.derived(), m_p); }
-
- Index rows() const { return m_pow.rows(); }
- Index cols() const { return m_pow.cols(); }
-
- private:
- Derived& m_pow;
- const RealScalar m_p;
- MatrixPowerBaseReturnValue& operator=(const MatrixPowerBaseReturnValue&);
-};
-
-template<typename Derived, typename MatrixType>
-class MatrixPowerBase
-{
- private:
- Derived& derived() { return *static_cast<Derived*>(this); }
-
- public:
- enum {
- RowsAtCompileTime = MatrixType::RowsAtCompileTime,
- ColsAtCompileTime = MatrixType::ColsAtCompileTime,
- Options = MatrixType::Options,
- MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
- MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
- };
- typedef typename MatrixType::Scalar Scalar;
- typedef typename MatrixType::RealScalar RealScalar;
- typedef typename MatrixType::Index Index;
-
- explicit MatrixPowerBase(const MatrixType& A) :
- m_A(A),
- m_conditionNumber(0)
- { eigen_assert(A.rows() == A.cols()); }
-
- #ifndef EIGEN_PARSED_BY_DOXYGEN
- const MatrixPowerBaseReturnValue<Derived,MatrixType> operator()(RealScalar p)
- { return MatrixPowerBaseReturnValue<Derived,MatrixType>(derived(), p); }
- #endif
-
- void compute(MatrixType& res, RealScalar p)
- { derived().compute(res,p); }
-
- template<typename OtherDerived, typename ResultType>
- void compute(const OtherDerived& b, ResultType& res, RealScalar p)
- { derived().compute(b,res,p); }
-
- Index rows() const { return m_A.rows(); }
- Index cols() const { return m_A.cols(); }
-
- protected:
- typedef Array<RealScalar,RowsAtCompileTime,1,ColMajor,MaxRowsAtCompileTime> RealArray;
-
- typename MatrixType::Nested m_A;
- MatrixType m_tmp1, m_tmp2;
- RealScalar m_conditionNumber;
-};
-
-template<typename Derived, typename Lhs, typename Rhs>
-class MatrixPowerProduct : public MatrixBase<MatrixPowerProduct<Derived,Lhs,Rhs> >
-{
- public:
- typedef MatrixBase<MatrixPowerProduct> Base;
- EIGEN_DENSE_PUBLIC_INTERFACE(MatrixPowerProduct)
-
- MatrixPowerProduct(Derived& pow, const Rhs& b, RealScalar p) :
- m_pow(pow),
- m_b(b),
- m_p(p)
- { eigen_assert(pow.cols() == b.rows()); }
-
- template<typename ResultType>
- inline void evalTo(ResultType& res) const
- { m_pow.compute(m_b, res, m_p); }
-
- inline Index rows() const { return m_pow.rows(); }
- inline Index cols() const { return m_b.cols(); }
-
- private:
- Derived& m_pow;
- typename Rhs::Nested m_b;
- const RealScalar m_p;
-};
-
-template<typename Derived>
-template<typename MatrixPower, typename Lhs, typename Rhs>
-Derived& MatrixBase<Derived>::lazyAssign(const MatrixPowerProduct<MatrixPower,Lhs,Rhs>& other)
-{
- other.evalTo(derived());
- return derived();
-}
-
-namespace internal {
-
-template<typename Derived, typename MatrixType>
-struct traits<MatrixPowerBaseReturnValue<Derived, MatrixType> >
-{ typedef MatrixType ReturnType; };
-
-template<typename Derived, typename _Lhs, typename _Rhs>
-struct traits<MatrixPowerProduct<Derived,_Lhs,_Rhs> >
-{
- typedef MatrixXpr XprKind;
- typedef typename remove_all<_Lhs>::type Lhs;
- typedef typename remove_all<_Rhs>::type Rhs;
- typedef typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType Scalar;
- typedef Dense StorageKind;
- typedef typename promote_index_type<typename Lhs::Index, typename Rhs::Index>::type Index;
-
- enum {
- RowsAtCompileTime = traits<Lhs>::RowsAtCompileTime,
- ColsAtCompileTime = traits<Rhs>::ColsAtCompileTime,
- MaxRowsAtCompileTime = traits<Lhs>::MaxRowsAtCompileTime,
- MaxColsAtCompileTime = traits<Rhs>::MaxColsAtCompileTime,
- Flags = (MaxRowsAtCompileTime==1 ? RowMajorBit : 0)
- | EvalBeforeNestingBit | EvalBeforeAssigningBit | NestByRefBit,
- CoeffReadCost = 0
- };
-};
-
-template<int IsComplex>
-struct recompose_complex_schur
-{
- template<typename ResultType, typename MatrixType>
- static inline void run(ResultType& res, const MatrixType& T, const MatrixType& U)
- { res.noalias() = U * (T.template triangularView<Upper>() * U.adjoint()); }
-};
-
-template<>
-struct recompose_complex_schur<0>
-{
- template<typename ResultType, typename MatrixType>
- static inline void run(ResultType& res, const MatrixType& T, const MatrixType& U)
- { res.noalias() = (U * (T.template triangularView<Upper>() * U.adjoint())).real(); }
-};
-
-template<typename Scalar, int IsComplex = NumTraits<Scalar>::IsComplex>
-struct matrix_power_unwinder
-{
- static inline Scalar run(const Scalar& eival, const Scalar& eival0, int unwindingNumber)
- { return internal::atanh2(eival-eival0, eival+eival0) + Scalar(0, M_PI*unwindingNumber); }
-};
-
-template<typename Scalar>
-struct matrix_power_unwinder<Scalar,0>
-{
- static inline Scalar run(Scalar eival, Scalar eival0, int)
- { return internal::atanh2(eival-eival0, eival+eival0); }
-};
-
-template<typename T>
-inline int binary_powering_cost(T p, int* squarings)
-{
- int applyings=0, tmp;
-
- frexp(p, squarings);
- --*squarings;
-
- while (std::frexp(p, &tmp), tmp > 0) {
- p -= std::ldexp(static_cast<T>(0.5), tmp);
- ++applyings;
- }
- return applyings;
-}
-
-inline int matrix_power_get_pade_degree(float normIminusT)
-{
- const float maxNormForPade[] = { 2.8064004e-1f /* degree = 3 */ , 4.3386528e-1f };
- int degree = 3;
- for (; degree <= 4; ++degree)
- if (normIminusT <= maxNormForPade[degree - 3])
- break;
- return degree;
-}
-
-inline int matrix_power_get_pade_degree(double normIminusT)
-{
- const double maxNormForPade[] = { 1.884160592658218e-2 /* degree = 3 */ , 6.038881904059573e-2, 1.239917516308172e-1,
- 1.999045567181744e-1, 2.789358995219730e-1 };
- int degree = 3;
- for (; degree <= 7; ++degree)
- if (normIminusT <= maxNormForPade[degree - 3])
- break;
- return degree;
-}
-
-inline int matrix_power_get_pade_degree(long double normIminusT)
-{
-#if LDBL_MANT_DIG == 53
- const int maxPadeDegree = 7;
- const double maxNormForPade[] = { 1.884160592658218e-2L /* degree = 3 */ , 6.038881904059573e-2L, 1.239917516308172e-1L,
- 1.999045567181744e-1L, 2.789358995219730e-1L };
-#elif LDBL_MANT_DIG <= 64
- const int maxPadeDegree = 8;
- const double maxNormForPade[] = { 6.3854693117491799460e-3L /* degree = 3 */ , 2.6394893435456973676e-2L,
- 6.4216043030404063729e-2L, 1.1701165502926694307e-1L, 1.7904284231268670284e-1L, 2.4471944416607995472e-1L };
-#elif LDBL_MANT_DIG <= 106
- const int maxPadeDegree = 10;
- const double maxNormForPade[] = { 1.0007161601787493236741409687186e-4L /* degree = 3 */ ,
- 1.0007161601787493236741409687186e-3L, 4.7069769360887572939882574746264e-3L, 1.3220386624169159689406653101695e-2L,
- 2.8063482381631737920612944054906e-2L, 4.9625993951953473052385361085058e-2L, 7.7367040706027886224557538328171e-2L,
- 1.1016843812851143391275867258512e-1L };
-#else
- const int maxPadeDegree = 10;
- const double maxNormForPade[] = { 5.524506147036624377378713555116378e-5L /* degree = 3 */ ,
- 6.640600568157479679823602193345995e-4L, 3.227716520106894279249709728084626e-3L,
- 9.619593944683432960546978734646284e-3L, 2.134595382433742403911124458161147e-2L,
- 3.908166513900489428442993794761185e-2L, 6.266780814639442865832535460550138e-2L,
- 9.134603732914548552537150753385375e-2L };
-#endif
- int degree = 3;
- for (; degree <= maxPadeDegree; ++degree)
- if (normIminusT <= maxNormForPade[degree - 3])
- break;
- return degree;
-}
-
-} // namespace internal
-
-template<typename MatrixType>
-class MatrixPowerTriangularAtomic
-{
- private:
- enum {
- RowsAtCompileTime = MatrixType::RowsAtCompileTime,
- MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime
- };
- typedef typename MatrixType::Scalar Scalar;
- typedef typename MatrixType::RealScalar RealScalar;
- typedef typename MatrixType::Index Index;
- typedef Array<Scalar,RowsAtCompileTime,1,ColMajor,MaxRowsAtCompileTime> ArrayType;
-
- const MatrixType& m_A;
-
- static void computePade(int degree, const MatrixType& IminusT, MatrixType& res, RealScalar p);
- void compute2x2(MatrixType& res, RealScalar p) const;
- void computeBig(MatrixType& res, RealScalar p) const;
-
- public:
- explicit MatrixPowerTriangularAtomic(const MatrixType& T);
- void compute(MatrixType& res, RealScalar p) const;
-};
-
-template<typename MatrixType>
-MatrixPowerTriangularAtomic<MatrixType>::MatrixPowerTriangularAtomic(const MatrixType& T) :
- m_A(T)
-{ eigen_assert(T.rows() == T.cols()); }
-
-template<typename MatrixType>
-void MatrixPowerTriangularAtomic<MatrixType>::compute(MatrixType& res, RealScalar p) const
-{
- switch (m_A.rows()) {
- case 0:
- break;
- case 1:
- res(0,0) = std::pow(m_A(0,0), p);
- break;
- case 2:
- compute2x2(res, p);
- break;
- default:
- computeBig(res, p);
- }
-}
-
-template<typename MatrixType>
-void MatrixPowerTriangularAtomic<MatrixType>::computePade(int degree, const MatrixType& IminusT, MatrixType& res, RealScalar p)
-{
- int i = degree<<1;
- res = (p-degree) / ((i-1)<<1) * IminusT;
- for (--i; i; --i) {
- res = (MatrixType::Identity(IminusT.rows(), IminusT.cols()) + res).template triangularView<Upper>()
- .solve((i==1 ? -p : i&1 ? (-p-(i>>1))/(i<<1) : (p-(i>>1))/((i-1)<<1)) * IminusT).eval();
- }
- res += MatrixType::Identity(IminusT.rows(), IminusT.cols());
-}
-
-template<typename MatrixType>
-void MatrixPowerTriangularAtomic<MatrixType>::compute2x2(MatrixType& res, RealScalar p) const
-{
- using std::abs;
- using std::pow;
-
- ArrayType logTdiag = m_A.diagonal().array().log();
- res.coeffRef(0,0) = pow(m_A.coeff(0,0), p);
-
- for (Index i=1; i < m_A.cols(); ++i) {
- res.coeffRef(i,i) = pow(m_A.coeff(i,i), p);
- if (m_A.coeff(i-1,i-1) == m_A.coeff(i,i)) {
- res.coeffRef(i-1,i) = p * pow(m_A.coeff(i-1,i), p-1);
- }
- else if (2*abs(m_A.coeff(i-1,i-1)) < abs(m_A.coeff(i,i)) || 2*abs(m_A.coeff(i,i)) < abs(m_A.coeff(i-1,i-1))) {
- res.coeffRef(i-1,i) = m_A.coeff(i-1,i) * (res.coeff(i,i)-res.coeff(i-1,i-1)) / (m_A.coeff(i,i)-m_A.coeff(i-1,i-1));
- }
- else {
- int unwindingNumber = std::ceil((internal::imag(logTdiag[i]-logTdiag[i-1]) - M_PI) / (2*M_PI));
- Scalar w = internal::matrix_power_unwinder<Scalar>::run(m_A.coeff(i,i), m_A.coeff(i-1,i-1), unwindingNumber);
- res.coeffRef(i-1,i) = m_A.coeff(i-1,i) * RealScalar(2) * std::exp(RealScalar(0.5)*p*(logTdiag[i]+logTdiag[i-1])) *
- std::sinh(p * w) / (m_A.coeff(i,i) - m_A.coeff(i-1,i-1));
- }
- }
-}
-
-template<typename MatrixType>
-void MatrixPowerTriangularAtomic<MatrixType>::computeBig(MatrixType& res, RealScalar p) const
-{
- const int digits = std::numeric_limits<RealScalar>::digits;
- const RealScalar maxNormForPade = digits <= 24? 4.3386528e-1f: // sigle precision
- digits <= 53? 2.789358995219730e-1: // double precision
- digits <= 64? 2.4471944416607995472e-1L: // extended precision
- digits <= 106? 1.1016843812851143391275867258512e-1L: // double-double
- 9.134603732914548552537150753385375e-2L; // quadruple precision
- MatrixType IminusT, sqrtT, T = m_A.template triangularView<Upper>();
- RealScalar normIminusT;
- int degree, degree2, numberOfSquareRoots = 0;
- bool hasExtraSquareRoot = false;
-
- while (true) {
- IminusT = MatrixType::Identity(m_A.rows(), m_A.cols()) - T;
- normIminusT = IminusT.cwiseAbs().colwise().sum().maxCoeff();
- if (normIminusT < maxNormForPade) {
- degree = internal::matrix_power_get_pade_degree(normIminusT);
- degree2 = internal::matrix_power_get_pade_degree(normIminusT/2);
- if (degree - degree2 <= 1 || hasExtraSquareRoot)
- break;
- hasExtraSquareRoot = true;
- }
- MatrixSquareRootTriangular<MatrixType>(T).compute(sqrtT);
- T = sqrtT.template triangularView<Upper>();
- ++numberOfSquareRoots;
- }
- computePade(degree, IminusT, res, p);
-
- for (; numberOfSquareRoots; --numberOfSquareRoots) {
- compute2x2(res, std::ldexp(p,-numberOfSquareRoots));
- res = res.template triangularView<Upper>() * res;
- }
- compute2x2(res, p);
-}
-
-} // namespace Eigen
-
-#endif // EIGEN_MATRIX_POWER
diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h b/unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h
index c1a04036b..b48ea9d46 100644
--- a/unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h
+++ b/unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h
@@ -94,7 +94,7 @@ void MatrixSquareRootQuasiTriangular<MatrixType>::computeDiagonalPartOfSqrt(Matr
const Index size = m_A.rows();
for (Index i = 0; i < size; i++) {
if (i == size - 1 || T.coeff(i+1, i) == 0) {
- eigen_assert(T(i,i) > 0);
+ eigen_assert(T(i,i) >= 0);
sqrtT.coeffRef(i,i) = sqrt(T.coeff(i,i));
}
else {
diff --git a/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h b/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h
index 5b24b4619..b8ba6ddcb 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h
@@ -254,14 +254,14 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveOneStep(FVectorType &x)
/* compute the scaled actual reduction. */
actred = -1.;
if (fnorm1 < fnorm) /* Computing 2nd power */
- actred = 1. - internal::abs2(fnorm1 / fnorm);
+ actred = 1. - numext::abs2(fnorm1 / fnorm);
/* compute the scaled predicted reduction. */
wa3 = R.template triangularView<Upper>()*wa1 + qtf;
temp = wa3.stableNorm();
prered = 0.;
if (temp < fnorm) /* Computing 2nd power */
- prered = 1. - internal::abs2(temp / fnorm);
+ prered = 1. - numext::abs2(temp / fnorm);
/* compute the ratio of the actual to the predicted reduction. */
ratio = 0.;
@@ -497,14 +497,14 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffOneStep(FVectorType
/* compute the scaled actual reduction. */
actred = -1.;
if (fnorm1 < fnorm) /* Computing 2nd power */
- actred = 1. - internal::abs2(fnorm1 / fnorm);
+ actred = 1. - numext::abs2(fnorm1 / fnorm);
/* compute the scaled predicted reduction. */
wa3 = R.template triangularView<Upper>()*wa1 + qtf;
temp = wa3.stableNorm();
prered = 0.;
if (temp < fnorm) /* Computing 2nd power */
- prered = 1. - internal::abs2(temp / fnorm);
+ prered = 1. - numext::abs2(temp / fnorm);
/* compute the ratio of the actual to the predicted reduction. */
ratio = 0.;
diff --git a/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h b/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
index 3d0a9c8fc..bfeb26fc9 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
@@ -285,13 +285,13 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeOneStep(FVectorType &x)
/* compute the scaled actual reduction. */
actred = -1.;
if (Scalar(.1) * fnorm1 < fnorm)
- actred = 1. - internal::abs2(fnorm1 / fnorm);
+ actred = 1. - numext::abs2(fnorm1 / fnorm);
/* compute the scaled predicted reduction and */
/* the scaled directional derivative. */
wa3 = fjac.template triangularView<Upper>() * (qrfac.colsPermutation().inverse() *wa1);
- temp1 = internal::abs2(wa3.stableNorm() / fnorm);
- temp2 = internal::abs2(sqrt(par) * pnorm / fnorm);
+ temp1 = numext::abs2(wa3.stableNorm() / fnorm);
+ temp2 = numext::abs2(sqrt(par) * pnorm / fnorm);
prered = temp1 + temp2 / Scalar(.5);
dirder = -(temp1 + temp2);
@@ -535,13 +535,13 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageOneStep(FVectorTyp
/* compute the scaled actual reduction. */
actred = -1.;
if (Scalar(.1) * fnorm1 < fnorm)
- actred = 1. - internal::abs2(fnorm1 / fnorm);
+ actred = 1. - numext::abs2(fnorm1 / fnorm);
/* compute the scaled predicted reduction and */
/* the scaled directional derivative. */
wa3 = fjac.topLeftCorner(n,n).template triangularView<Upper>() * (permutation.inverse() * wa1);
- temp1 = internal::abs2(wa3.stableNorm() / fnorm);
- temp2 = internal::abs2(sqrt(par) * pnorm / fnorm);
+ temp1 = numext::abs2(wa3.stableNorm() / fnorm);
+ temp2 = numext::abs2(sqrt(par) * pnorm / fnorm);
prered = temp1 + temp2 / Scalar(.5);
dirder = -(temp1 + temp2);
diff --git a/unsupported/Eigen/src/NonLinearOptimization/dogleg.h b/unsupported/Eigen/src/NonLinearOptimization/dogleg.h
index 4210958e7..80c5d277b 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/dogleg.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/dogleg.h
@@ -92,8 +92,8 @@ void dogleg(
/* at which the quadratic is minimized. */
bnorm = qtb.stableNorm();
temp = bnorm / gnorm * (bnorm / qnorm) * (sgnorm / delta);
- temp = temp - delta / qnorm * abs2(sgnorm / delta) + sqrt(abs2(temp - delta / qnorm) + (1.-abs2(delta / qnorm)) * (1.-abs2(sgnorm / delta)));
- alpha = delta / qnorm * (1. - abs2(sgnorm / delta)) / temp;
+ temp = temp - delta / qnorm * numext::abs2(sgnorm / delta) + sqrt(numext::abs2(temp - delta / qnorm) + (1.-numext::abs2(delta / qnorm)) * (1.-numext::abs2(sgnorm / delta)));
+ alpha = delta / qnorm * (1. - numext::abs2(sgnorm / delta)) / temp;
algo_end:
/* form appropriate convex combination of the gauss-newton */
diff --git a/unsupported/Eigen/src/Polynomials/PolynomialSolver.h b/unsupported/Eigen/src/Polynomials/PolynomialSolver.h
index ad486f08e..cd5c04bbf 100644
--- a/unsupported/Eigen/src/Polynomials/PolynomialSolver.h
+++ b/unsupported/Eigen/src/Polynomials/PolynomialSolver.h
@@ -83,10 +83,10 @@ class PolynomialSolverBase
inline const RootType& selectComplexRoot_withRespectToNorm( squaredNormBinaryPredicate& pred ) const
{
Index res=0;
- RealScalar norm2 = internal::abs2( m_roots[0] );
+ RealScalar norm2 = numext::abs2( m_roots[0] );
for( Index i=1; i<m_roots.size(); ++i )
{
- const RealScalar currNorm2 = internal::abs2( m_roots[i] );
+ const RealScalar currNorm2 = numext::abs2( m_roots[i] );
if( pred( currNorm2, norm2 ) ){
res=i; norm2=currNorm2; }
}
@@ -150,7 +150,7 @@ class PolynomialSolverBase
res = i; }
}
}
- return internal::real_ref(m_roots[res]);
+ return numext::real_ref(m_roots[res]);
}
@@ -191,7 +191,7 @@ class PolynomialSolverBase
res = i; }
}
}
- return internal::real_ref(m_roots[res]);
+ return numext::real_ref(m_roots[res]);
}
public:
diff --git a/unsupported/Eigen/src/Polynomials/PolynomialUtils.h b/unsupported/Eigen/src/Polynomials/PolynomialUtils.h
index 27d4e9f91..2bb8bc84a 100644
--- a/unsupported/Eigen/src/Polynomials/PolynomialUtils.h
+++ b/unsupported/Eigen/src/Polynomials/PolynomialUtils.h
@@ -47,7 +47,7 @@ T poly_eval( const Polynomials& poly, const T& x )
{
typedef typename NumTraits<T>::Real Real;
- if( internal::abs2( x ) <= Real(1) ){
+ if( numext::abs2( x ) <= Real(1) ){
return poly_eval_horner( poly, x ); }
else
{
diff --git a/unsupported/Eigen/src/SVD/BDCSVD.h b/unsupported/Eigen/src/SVD/BDCSVD.h
new file mode 100644
index 000000000..11d4882e4
--- /dev/null
+++ b/unsupported/Eigen/src/SVD/BDCSVD.h
@@ -0,0 +1,748 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// We used the "A Divide-And-Conquer Algorithm for the Bidiagonal SVD"
+// research report written by Ming Gu and Stanley C.Eisenstat
+// The code variable names correspond to the names they used in their
+// report
+//
+// Copyright (C) 2013 Gauthier Brun <brun.gauthier@gmail.com>
+// Copyright (C) 2013 Nicolas Carre <nicolas.carre@ensimag.fr>
+// Copyright (C) 2013 Jean Ceccato <jean.ceccato@ensimag.fr>
+// Copyright (C) 2013 Pierre Zoppitelli <pierre.zoppitelli@ensimag.fr>
+//
+// Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_BDCSVD_H
+#define EIGEN_BDCSVD_H
+
+#define EPSILON 0.0000000000000001
+
+#define ALGOSWAP 32
+
+namespace Eigen {
+/** \ingroup SVD_Module
+ *
+ *
+ * \class BDCSVD
+ *
+ * \brief class Bidiagonal Divide and Conquer SVD
+ *
+ * \param MatrixType the type of the matrix of which we are computing the SVD decomposition
+ * We plan to have a very similar interface to JacobiSVD on this class.
+ * It should be used to speed up the calcul of SVD for big matrices.
+ */
+template<typename _MatrixType>
+class BDCSVD : public SVDBase<_MatrixType>
+{
+ typedef SVDBase<_MatrixType> Base;
+
+public:
+ using Base::rows;
+ using Base::cols;
+
+ typedef _MatrixType MatrixType;
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
+ typedef typename MatrixType::Index Index;
+ enum {
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
+ ColsAtCompileTime = MatrixType::ColsAtCompileTime,
+ DiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime, ColsAtCompileTime),
+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
+ MaxDiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(MaxRowsAtCompileTime, MaxColsAtCompileTime),
+ MatrixOptions = MatrixType::Options
+ };
+
+ typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime,
+ MatrixOptions, MaxRowsAtCompileTime, MaxRowsAtCompileTime>
+ MatrixUType;
+ typedef Matrix<Scalar, ColsAtCompileTime, ColsAtCompileTime,
+ MatrixOptions, MaxColsAtCompileTime, MaxColsAtCompileTime>
+ MatrixVType;
+ typedef typename internal::plain_diag_type<MatrixType, RealScalar>::type SingularValuesType;
+ typedef typename internal::plain_row_type<MatrixType>::type RowType;
+ typedef typename internal::plain_col_type<MatrixType>::type ColType;
+ typedef Matrix<Scalar, Dynamic, Dynamic> MatrixX;
+ typedef Matrix<RealScalar, Dynamic, Dynamic> MatrixXr;
+ typedef Matrix<RealScalar, Dynamic, 1> VectorType;
+
+ /** \brief Default Constructor.
+ *
+ * The default constructor is useful in cases in which the user intends to
+ * perform decompositions via BDCSVD::compute(const MatrixType&).
+ */
+ BDCSVD()
+ : SVDBase<_MatrixType>::SVDBase(),
+ algoswap(ALGOSWAP)
+ {}
+
+
+ /** \brief Default Constructor with memory preallocation
+ *
+ * Like the default constructor but with preallocation of the internal data
+ * according to the specified problem size.
+ * \sa BDCSVD()
+ */
+ BDCSVD(Index rows, Index cols, unsigned int computationOptions = 0)
+ : SVDBase<_MatrixType>::SVDBase(),
+ algoswap(ALGOSWAP)
+ {
+ allocate(rows, cols, computationOptions);
+ }
+
+ /** \brief Constructor performing the decomposition of given matrix.
+ *
+ * \param matrix the matrix to decompose
+ * \param computationOptions optional parameter allowing to specify if you want full or thin U or V unitaries to be computed.
+ * By default, none is computed. This is a bit - field, the possible bits are #ComputeFullU, #ComputeThinU,
+ * #ComputeFullV, #ComputeThinV.
+ *
+ * Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not
+ * available with the (non - default) FullPivHouseholderQR preconditioner.
+ */
+ BDCSVD(const MatrixType& matrix, unsigned int computationOptions = 0)
+ : SVDBase<_MatrixType>::SVDBase(),
+ algoswap(ALGOSWAP)
+ {
+ compute(matrix, computationOptions);
+ }
+
+ ~BDCSVD()
+ {
+ }
+ /** \brief Method performing the decomposition of given matrix using custom options.
+ *
+ * \param matrix the matrix to decompose
+ * \param computationOptions optional parameter allowing to specify if you want full or thin U or V unitaries to be computed.
+ * By default, none is computed. This is a bit - field, the possible bits are #ComputeFullU, #ComputeThinU,
+ * #ComputeFullV, #ComputeThinV.
+ *
+ * Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not
+ * available with the (non - default) FullPivHouseholderQR preconditioner.
+ */
+ SVDBase<MatrixType>& compute(const MatrixType& matrix, unsigned int computationOptions);
+
+ /** \brief Method performing the decomposition of given matrix using current options.
+ *
+ * \param matrix the matrix to decompose
+ *
+ * This method uses the current \a computationOptions, as already passed to the constructor or to compute(const MatrixType&, unsigned int).
+ */
+ SVDBase<MatrixType>& compute(const MatrixType& matrix)
+ {
+ return compute(matrix, this->m_computationOptions);
+ }
+
+ void setSwitchSize(int s)
+ {
+ eigen_assert(s>3 && "BDCSVD the size of the algo switch has to be greater than 4");
+ algoswap = s;
+ }
+
+
+ /** \returns a (least squares) solution of \f$ A x = b \f$ using the current SVD decomposition of A.
+ *
+ * \param b the right - hand - side of the equation to solve.
+ *
+ * \note Solving requires both U and V to be computed. Thin U and V are enough, there is no need for full U or V.
+ *
+ * \note SVD solving is implicitly least - squares. Thus, this method serves both purposes of exact solving and least - squares solving.
+ * In other words, the returned solution is guaranteed to minimize the Euclidean norm \f$ \Vert A x - b \Vert \f$.
+ */
+ template<typename Rhs>
+ inline const internal::solve_retval<BDCSVD, Rhs>
+ solve(const MatrixBase<Rhs>& b) const
+ {
+ eigen_assert(this->m_isInitialized && "BDCSVD is not initialized.");
+ eigen_assert(SVDBase<_MatrixType>::computeU() && SVDBase<_MatrixType>::computeV() &&
+ "BDCSVD::solve() requires both unitaries U and V to be computed (thin unitaries suffice).");
+ return internal::solve_retval<BDCSVD, Rhs>(*this, b.derived());
+ }
+
+
+ const MatrixUType& matrixU() const
+ {
+ eigen_assert(this->m_isInitialized && "SVD is not initialized.");
+ if (isTranspose){
+ eigen_assert(this->computeV() && "This SVD decomposition didn't compute U. Did you ask for it?");
+ return this->m_matrixV;
+ }
+ else
+ {
+ eigen_assert(this->computeU() && "This SVD decomposition didn't compute U. Did you ask for it?");
+ return this->m_matrixU;
+ }
+
+ }
+
+
+ const MatrixVType& matrixV() const
+ {
+ eigen_assert(this->m_isInitialized && "SVD is not initialized.");
+ if (isTranspose){
+ eigen_assert(this->computeU() && "This SVD decomposition didn't compute V. Did you ask for it?");
+ return this->m_matrixU;
+ }
+ else
+ {
+ eigen_assert(this->computeV() && "This SVD decomposition didn't compute V. Did you ask for it?");
+ return this->m_matrixV;
+ }
+ }
+
+private:
+ void allocate(Index rows, Index cols, unsigned int computationOptions);
+ void divide (Index firstCol, Index lastCol, Index firstRowW,
+ Index firstColW, Index shift);
+ void deflation43(Index firstCol, Index shift, Index i, Index size);
+ void deflation44(Index firstColu , Index firstColm, Index firstRowW, Index firstColW, Index i, Index j, Index size);
+ void deflation(Index firstCol, Index lastCol, Index k, Index firstRowW, Index firstColW, Index shift);
+ void copyUV(MatrixXr naiveU, MatrixXr naiveV, MatrixX householderU, MatrixX houseHolderV);
+
+protected:
+ MatrixXr m_naiveU, m_naiveV;
+ MatrixXr m_computed;
+ Index nRec;
+ int algoswap;
+ bool isTranspose, compU, compV;
+
+}; //end class BDCSVD
+
+
+// Methode to allocate ans initialize matrix and attributs
+template<typename MatrixType>
+void BDCSVD<MatrixType>::allocate(Index rows, Index cols, unsigned int computationOptions)
+{
+ isTranspose = (cols > rows);
+ if (SVDBase<MatrixType>::allocate(rows, cols, computationOptions)) return;
+ m_computed = MatrixXr::Zero(this->m_diagSize + 1, this->m_diagSize );
+ if (isTranspose){
+ compU = this->computeU();
+ compV = this->computeV();
+ }
+ else
+ {
+ compV = this->computeU();
+ compU = this->computeV();
+ }
+ if (compU) m_naiveU = MatrixXr::Zero(this->m_diagSize + 1, this->m_diagSize + 1 );
+ else m_naiveU = MatrixXr::Zero(2, this->m_diagSize + 1 );
+
+ if (compV) m_naiveV = MatrixXr::Zero(this->m_diagSize, this->m_diagSize);
+
+
+ //should be changed for a cleaner implementation
+ if (isTranspose){
+ bool aux;
+ if (this->computeU()||this->computeV()){
+ aux = this->m_computeFullU;
+ this->m_computeFullU = this->m_computeFullV;
+ this->m_computeFullV = aux;
+ aux = this->m_computeThinU;
+ this->m_computeThinU = this->m_computeThinV;
+ this->m_computeThinV = aux;
+ }
+ }
+}// end allocate
+
+// Methode which compute the BDCSVD for the int
+template<>
+SVDBase<Matrix<int, Dynamic, Dynamic> >&
+BDCSVD<Matrix<int, Dynamic, Dynamic> >::compute(const MatrixType& matrix, unsigned int computationOptions) {
+ allocate(matrix.rows(), matrix.cols(), computationOptions);
+ this->m_nonzeroSingularValues = 0;
+ m_computed = Matrix<int, Dynamic, Dynamic>::Zero(rows(), cols());
+ for (int i=0; i<this->m_diagSize; i++) {
+ this->m_singularValues.coeffRef(i) = 0;
+ }
+ if (this->m_computeFullU) this->m_matrixU = Matrix<int, Dynamic, Dynamic>::Zero(rows(), rows());
+ if (this->m_computeFullV) this->m_matrixV = Matrix<int, Dynamic, Dynamic>::Zero(cols(), cols());
+ this->m_isInitialized = true;
+ return *this;
+}
+
+
+// Methode which compute the BDCSVD
+template<typename MatrixType>
+SVDBase<MatrixType>&
+BDCSVD<MatrixType>::compute(const MatrixType& matrix, unsigned int computationOptions)
+{
+ allocate(matrix.rows(), matrix.cols(), computationOptions);
+ using std::abs;
+
+ //**** step 1 Bidiagonalization isTranspose = (matrix.cols()>matrix.rows()) ;
+ MatrixType copy;
+ if (isTranspose) copy = matrix.adjoint();
+ else copy = matrix;
+
+ internal::UpperBidiagonalization<MatrixX > bid(copy);
+
+ //**** step 2 Divide
+ // this is ugly and has to be redone (care of complex cast)
+ MatrixXr temp;
+ temp = bid.bidiagonal().toDenseMatrix().transpose();
+ m_computed.setZero();
+ for (int i=0; i<this->m_diagSize - 1; i++) {
+ m_computed(i, i) = temp(i, i);
+ m_computed(i + 1, i) = temp(i + 1, i);
+ }
+ m_computed(this->m_diagSize - 1, this->m_diagSize - 1) = temp(this->m_diagSize - 1, this->m_diagSize - 1);
+ divide(0, this->m_diagSize - 1, 0, 0, 0);
+
+ //**** step 3 copy
+ for (int i=0; i<this->m_diagSize; i++) {
+ RealScalar a = abs(m_computed.coeff(i, i));
+ this->m_singularValues.coeffRef(i) = a;
+ if (a == 0){
+ this->m_nonzeroSingularValues = i;
+ break;
+ }
+ else if (i == this->m_diagSize - 1)
+ {
+ this->m_nonzeroSingularValues = i + 1;
+ break;
+ }
+ }
+ copyUV(m_naiveV, m_naiveU, bid.householderU(), bid.householderV());
+ this->m_isInitialized = true;
+ return *this;
+}// end compute
+
+
+template<typename MatrixType>
+void BDCSVD<MatrixType>::copyUV(MatrixXr naiveU, MatrixXr naiveV, MatrixX householderU, MatrixX householderV){
+ if (this->computeU()){
+ MatrixX temp = MatrixX::Zero(naiveU.rows(), naiveU.cols());
+ temp.real() = naiveU;
+ if (this->m_computeThinU){
+ this->m_matrixU = MatrixX::Identity(householderU.cols(), this->m_nonzeroSingularValues );
+ this->m_matrixU.block(0, 0, this->m_diagSize, this->m_nonzeroSingularValues) =
+ temp.block(0, 0, this->m_diagSize, this->m_nonzeroSingularValues);
+ this->m_matrixU = householderU * this->m_matrixU ;
+ }
+ else
+ {
+ this->m_matrixU = MatrixX::Identity(householderU.cols(), householderU.cols());
+ this->m_matrixU.block(0, 0, this->m_diagSize, this->m_diagSize) = temp.block(0, 0, this->m_diagSize, this->m_diagSize);
+ this->m_matrixU = householderU * this->m_matrixU ;
+ }
+ }
+ if (this->computeV()){
+ MatrixX temp = MatrixX::Zero(naiveV.rows(), naiveV.cols());
+ temp.real() = naiveV;
+ if (this->m_computeThinV){
+ this->m_matrixV = MatrixX::Identity(householderV.cols(),this->m_nonzeroSingularValues );
+ this->m_matrixV.block(0, 0, this->m_nonzeroSingularValues, this->m_nonzeroSingularValues) =
+ temp.block(0, 0, this->m_nonzeroSingularValues, this->m_nonzeroSingularValues);
+ this->m_matrixV = householderV * this->m_matrixV ;
+ }
+ else
+ {
+ this->m_matrixV = MatrixX::Identity(householderV.cols(), householderV.cols());
+ this->m_matrixV.block(0, 0, this->m_diagSize, this->m_diagSize) = temp.block(0, 0, this->m_diagSize, this->m_diagSize);
+ this->m_matrixV = householderV * this->m_matrixV;
+ }
+ }
+}
+
+// The divide algorithm is done "in place", we are always working on subsets of the same matrix. The divide methods takes as argument the
+// place of the submatrix we are currently working on.
+
+//@param firstCol : The Index of the first column of the submatrix of m_computed and for m_naiveU;
+//@param lastCol : The Index of the last column of the submatrix of m_computed and for m_naiveU;
+// lastCol + 1 - firstCol is the size of the submatrix.
+//@param firstRowW : The Index of the first row of the matrix W that we are to change. (see the reference paper section 1 for more information on W)
+//@param firstRowW : Same as firstRowW with the column.
+//@param shift : Each time one takes the left submatrix, one must add 1 to the shift. Why? Because! We actually want the last column of the U submatrix
+// to become the first column (*coeff) and to shift all the other columns to the right. There are more details on the reference paper.
+template<typename MatrixType>
+void BDCSVD<MatrixType>::divide (Index firstCol, Index lastCol, Index firstRowW,
+ Index firstColW, Index shift)
+{
+ // requires nbRows = nbCols + 1;
+ using std::pow;
+ using std::sqrt;
+ using std::abs;
+ const Index n = lastCol - firstCol + 1;
+ const Index k = n/2;
+ RealScalar alphaK;
+ RealScalar betaK;
+ RealScalar r0;
+ RealScalar lambda, phi, c0, s0;
+ MatrixXr l, f;
+ // We use the other algorithm which is more efficient for small
+ // matrices.
+ if (n < algoswap){
+ JacobiSVD<MatrixXr> b(m_computed.block(firstCol, firstCol, n + 1, n),
+ ComputeFullU | (ComputeFullV * compV)) ;
+ if (compU) m_naiveU.block(firstCol, firstCol, n + 1, n + 1).real() << b.matrixU();
+ else
+ {
+ m_naiveU.row(0).segment(firstCol, n + 1).real() << b.matrixU().row(0);
+ m_naiveU.row(1).segment(firstCol, n + 1).real() << b.matrixU().row(n);
+ }
+ if (compV) m_naiveV.block(firstRowW, firstColW, n, n).real() << b.matrixV();
+ m_computed.block(firstCol + shift, firstCol + shift, n + 1, n).setZero();
+ for (int i=0; i<n; i++)
+ {
+ m_computed(firstCol + shift + i, firstCol + shift +i) = b.singularValues().coeffRef(i);
+ }
+ return;
+ }
+ // We use the divide and conquer algorithm
+ alphaK = m_computed(firstCol + k, firstCol + k);
+ betaK = m_computed(firstCol + k + 1, firstCol + k);
+ // The divide must be done in that order in order to have good results. Divide change the data inside the submatrices
+ // and the divide of the right submatrice reads one column of the left submatrice. That's why we need to treat the
+ // right submatrix before the left one.
+ divide(k + 1 + firstCol, lastCol, k + 1 + firstRowW, k + 1 + firstColW, shift);
+ divide(firstCol, k - 1 + firstCol, firstRowW, firstColW + 1, shift + 1);
+ if (compU)
+ {
+ lambda = m_naiveU(firstCol + k, firstCol + k);
+ phi = m_naiveU(firstCol + k + 1, lastCol + 1);
+ }
+ else
+ {
+ lambda = m_naiveU(1, firstCol + k);
+ phi = m_naiveU(0, lastCol + 1);
+ }
+ r0 = sqrt((abs(alphaK * lambda) * abs(alphaK * lambda))
+ + abs(betaK * phi) * abs(betaK * phi));
+ if (compU)
+ {
+ l = m_naiveU.row(firstCol + k).segment(firstCol, k);
+ f = m_naiveU.row(firstCol + k + 1).segment(firstCol + k + 1, n - k - 1);
+ }
+ else
+ {
+ l = m_naiveU.row(1).segment(firstCol, k);
+ f = m_naiveU.row(0).segment(firstCol + k + 1, n - k - 1);
+ }
+ if (compV) m_naiveV(firstRowW+k, firstColW) = 1;
+ if (r0 == 0)
+ {
+ c0 = 1;
+ s0 = 0;
+ }
+ else
+ {
+ c0 = alphaK * lambda / r0;
+ s0 = betaK * phi / r0;
+ }
+ if (compU)
+ {
+ MatrixXr q1 (m_naiveU.col(firstCol + k).segment(firstCol, k + 1));
+ // we shiftW Q1 to the right
+ for (Index i = firstCol + k - 1; i >= firstCol; i--)
+ {
+ m_naiveU.col(i + 1).segment(firstCol, k + 1) << m_naiveU.col(i).segment(firstCol, k + 1);
+ }
+ // we shift q1 at the left with a factor c0
+ m_naiveU.col(firstCol).segment( firstCol, k + 1) << (q1 * c0);
+ // last column = q1 * - s0
+ m_naiveU.col(lastCol + 1).segment(firstCol, k + 1) << (q1 * ( - s0));
+ // first column = q2 * s0
+ m_naiveU.col(firstCol).segment(firstCol + k + 1, n - k) <<
+ m_naiveU.col(lastCol + 1).segment(firstCol + k + 1, n - k) *s0;
+ // q2 *= c0
+ m_naiveU.col(lastCol + 1).segment(firstCol + k + 1, n - k) *= c0;
+ }
+ else
+ {
+ RealScalar q1 = (m_naiveU(0, firstCol + k));
+ // we shift Q1 to the right
+ for (Index i = firstCol + k - 1; i >= firstCol; i--)
+ {
+ m_naiveU(0, i + 1) = m_naiveU(0, i);
+ }
+ // we shift q1 at the left with a factor c0
+ m_naiveU(0, firstCol) = (q1 * c0);
+ // last column = q1 * - s0
+ m_naiveU(0, lastCol + 1) = (q1 * ( - s0));
+ // first column = q2 * s0
+ m_naiveU(1, firstCol) = m_naiveU(1, lastCol + 1) *s0;
+ // q2 *= c0
+ m_naiveU(1, lastCol + 1) *= c0;
+ m_naiveU.row(1).segment(firstCol + 1, k).setZero();
+ m_naiveU.row(0).segment(firstCol + k + 1, n - k - 1).setZero();
+ }
+ m_computed(firstCol + shift, firstCol + shift) = r0;
+ m_computed.col(firstCol + shift).segment(firstCol + shift + 1, k) << alphaK * l.transpose().real();
+ m_computed.col(firstCol + shift).segment(firstCol + shift + k + 1, n - k - 1) << betaK * f.transpose().real();
+
+
+ // the line below do the deflation of the matrix for the third part of the algorithm
+ // Here the deflation is commented because the third part of the algorithm is not implemented
+ // the third part of the algorithm is a fast SVD on the matrix m_computed which works thanks to the deflation
+
+ deflation(firstCol, lastCol, k, firstRowW, firstColW, shift);
+
+ // Third part of the algorithm, since the real third part of the algorithm is not implemeted we use a JacobiSVD
+ JacobiSVD<MatrixXr> res= JacobiSVD<MatrixXr>(m_computed.block(firstCol + shift, firstCol +shift, n + 1, n),
+ ComputeFullU | (ComputeFullV * compV)) ;
+ if (compU) m_naiveU.block(firstCol, firstCol, n + 1, n + 1) *= res.matrixU();
+ else m_naiveU.block(0, firstCol, 2, n + 1) *= res.matrixU();
+
+ if (compV) m_naiveV.block(firstRowW, firstColW, n, n) *= res.matrixV();
+ m_computed.block(firstCol + shift, firstCol + shift, n, n) << MatrixXr::Zero(n, n);
+ for (int i=0; i<n; i++)
+ m_computed(firstCol + shift + i, firstCol + shift +i) = res.singularValues().coeffRef(i);
+ // end of the third part
+
+
+}// end divide
+
+
+// page 12_13
+// i >= 1, di almost null and zi non null.
+// We use a rotation to zero out zi applied to the left of M
+template <typename MatrixType>
+void BDCSVD<MatrixType>::deflation43(Index firstCol, Index shift, Index i, Index size){
+ using std::abs;
+ using std::sqrt;
+ using std::pow;
+ RealScalar c = m_computed(firstCol + shift, firstCol + shift);
+ RealScalar s = m_computed(i, firstCol + shift);
+ RealScalar r = sqrt(pow(abs(c), 2) + pow(abs(s), 2));
+ if (r == 0){
+ m_computed(i, i)=0;
+ return;
+ }
+ c/=r;
+ s/=r;
+ m_computed(firstCol + shift, firstCol + shift) = r;
+ m_computed(i, firstCol + shift) = 0;
+ m_computed(i, i) = 0;
+ if (compU){
+ m_naiveU.col(firstCol).segment(firstCol,size) =
+ c * m_naiveU.col(firstCol).segment(firstCol, size) -
+ s * m_naiveU.col(i).segment(firstCol, size) ;
+
+ m_naiveU.col(i).segment(firstCol, size) =
+ (c + s*s/c) * m_naiveU.col(i).segment(firstCol, size) +
+ (s/c) * m_naiveU.col(firstCol).segment(firstCol,size);
+ }
+}// end deflation 43
+
+
+// page 13
+// i,j >= 1, i != j and |di - dj| < epsilon * norm2(M)
+// We apply two rotations to have zj = 0;
+template <typename MatrixType>
+void BDCSVD<MatrixType>::deflation44(Index firstColu , Index firstColm, Index firstRowW, Index firstColW, Index i, Index j, Index size){
+ using std::abs;
+ using std::sqrt;
+ using std::conj;
+ using std::pow;
+ RealScalar c = m_computed(firstColm, firstColm + j - 1);
+ RealScalar s = m_computed(firstColm, firstColm + i - 1);
+ RealScalar r = sqrt(pow(abs(c), 2) + pow(abs(s), 2));
+ if (r==0){
+ m_computed(firstColm + i, firstColm + i) = m_computed(firstColm + j, firstColm + j);
+ return;
+ }
+ c/=r;
+ s/=r;
+ m_computed(firstColm + i, firstColm) = r;
+ m_computed(firstColm + i, firstColm + i) = m_computed(firstColm + j, firstColm + j);
+ m_computed(firstColm + j, firstColm) = 0;
+ if (compU){
+ m_naiveU.col(firstColu + i).segment(firstColu, size) =
+ c * m_naiveU.col(firstColu + i).segment(firstColu, size) -
+ s * m_naiveU.col(firstColu + j).segment(firstColu, size) ;
+
+ m_naiveU.col(firstColu + j).segment(firstColu, size) =
+ (c + s*s/c) * m_naiveU.col(firstColu + j).segment(firstColu, size) +
+ (s/c) * m_naiveU.col(firstColu + i).segment(firstColu, size);
+ }
+ if (compV){
+ m_naiveV.col(firstColW + i).segment(firstRowW, size - 1) =
+ c * m_naiveV.col(firstColW + i).segment(firstRowW, size - 1) +
+ s * m_naiveV.col(firstColW + j).segment(firstRowW, size - 1) ;
+
+ m_naiveV.col(firstColW + j).segment(firstRowW, size - 1) =
+ (c + s*s/c) * m_naiveV.col(firstColW + j).segment(firstRowW, size - 1) -
+ (s/c) * m_naiveV.col(firstColW + i).segment(firstRowW, size - 1);
+ }
+}// end deflation 44
+
+
+
+template <typename MatrixType>
+void BDCSVD<MatrixType>::deflation(Index firstCol, Index lastCol, Index k, Index firstRowW, Index firstColW, Index shift){
+ //condition 4.1
+ RealScalar EPS = EPSILON * (std::max<RealScalar>(m_computed(firstCol + shift + 1, firstCol + shift + 1), m_computed(firstCol + k, firstCol + k)));
+ const Index length = lastCol + 1 - firstCol;
+ if (m_computed(firstCol + shift, firstCol + shift) < EPS){
+ m_computed(firstCol + shift, firstCol + shift) = EPS;
+ }
+ //condition 4.2
+ for (Index i=firstCol + shift + 1;i<=lastCol + shift;i++){
+ if (std::abs(m_computed(i, firstCol + shift)) < EPS){
+ m_computed(i, firstCol + shift) = 0;
+ }
+ }
+
+ //condition 4.3
+ for (Index i=firstCol + shift + 1;i<=lastCol + shift; i++){
+ if (m_computed(i, i) < EPS){
+ deflation43(firstCol, shift, i, length);
+ }
+ }
+
+ //condition 4.4
+
+ Index i=firstCol + shift + 1, j=firstCol + shift + k + 1;
+ //we stock the final place of each line
+ Index *permutation = new Index[length];
+
+ for (Index p =1; p < length; p++) {
+ if (i> firstCol + shift + k){
+ permutation[p] = j;
+ j++;
+ } else if (j> lastCol + shift)
+ {
+ permutation[p] = i;
+ i++;
+ }
+ else
+ {
+ if (m_computed(i, i) < m_computed(j, j)){
+ permutation[p] = j;
+ j++;
+ }
+ else
+ {
+ permutation[p] = i;
+ i++;
+ }
+ }
+ }
+ //we do the permutation
+ RealScalar aux;
+ //we stock the current index of each col
+ //and the column of each index
+ Index *realInd = new Index[length];
+ Index *realCol = new Index[length];
+ for (int pos = 0; pos< length; pos++){
+ realCol[pos] = pos + firstCol + shift;
+ realInd[pos] = pos;
+ }
+ const Index Zero = firstCol + shift;
+ VectorType temp;
+ for (int i = 1; i < length - 1; i++){
+ const Index I = i + Zero;
+ const Index realI = realInd[i];
+ const Index j = permutation[length - i] - Zero;
+ const Index J = realCol[j];
+
+ //diag displace
+ aux = m_computed(I, I);
+ m_computed(I, I) = m_computed(J, J);
+ m_computed(J, J) = aux;
+
+ //firstrow displace
+ aux = m_computed(I, Zero);
+ m_computed(I, Zero) = m_computed(J, Zero);
+ m_computed(J, Zero) = aux;
+
+ // change columns
+ if (compU) {
+ temp = m_naiveU.col(I - shift).segment(firstCol, length + 1);
+ m_naiveU.col(I - shift).segment(firstCol, length + 1) <<
+ m_naiveU.col(J - shift).segment(firstCol, length + 1);
+ m_naiveU.col(J - shift).segment(firstCol, length + 1) << temp;
+ }
+ else
+ {
+ temp = m_naiveU.col(I - shift).segment(0, 2);
+ m_naiveU.col(I - shift).segment(0, 2) <<
+ m_naiveU.col(J - shift).segment(0, 2);
+ m_naiveU.col(J - shift).segment(0, 2) << temp;
+ }
+ if (compV) {
+ const Index CWI = I + firstColW - Zero;
+ const Index CWJ = J + firstColW - Zero;
+ temp = m_naiveV.col(CWI).segment(firstRowW, length);
+ m_naiveV.col(CWI).segment(firstRowW, length) << m_naiveV.col(CWJ).segment(firstRowW, length);
+ m_naiveV.col(CWJ).segment(firstRowW, length) << temp;
+ }
+
+ //update real pos
+ realCol[realI] = J;
+ realCol[j] = I;
+ realInd[J - Zero] = realI;
+ realInd[I - Zero] = j;
+ }
+ for (Index i = firstCol + shift + 1; i<lastCol + shift;i++){
+ if ((m_computed(i + 1, i + 1) - m_computed(i, i)) < EPS){
+ deflation44(firstCol ,
+ firstCol + shift,
+ firstRowW,
+ firstColW,
+ i - Zero,
+ i + 1 - Zero,
+ length);
+ }
+ }
+ delete [] permutation;
+ delete [] realInd;
+ delete [] realCol;
+
+}//end deflation
+
+
+namespace internal{
+
+template<typename _MatrixType, typename Rhs>
+struct solve_retval<BDCSVD<_MatrixType>, Rhs>
+ : solve_retval_base<BDCSVD<_MatrixType>, Rhs>
+{
+ typedef BDCSVD<_MatrixType> BDCSVDType;
+ EIGEN_MAKE_SOLVE_HELPERS(BDCSVDType, Rhs)
+
+ template<typename Dest> void evalTo(Dest& dst) const
+ {
+ eigen_assert(rhs().rows() == dec().rows());
+ // A = U S V^*
+ // So A^{ - 1} = V S^{ - 1} U^*
+ Index diagSize = (std::min)(dec().rows(), dec().cols());
+ typename BDCSVDType::SingularValuesType invertedSingVals(diagSize);
+ Index nonzeroSingVals = dec().nonzeroSingularValues();
+ invertedSingVals.head(nonzeroSingVals) = dec().singularValues().head(nonzeroSingVals).array().inverse();
+ invertedSingVals.tail(diagSize - nonzeroSingVals).setZero();
+
+ dst = dec().matrixV().leftCols(diagSize)
+ * invertedSingVals.asDiagonal()
+ * dec().matrixU().leftCols(diagSize).adjoint()
+ * rhs();
+ return;
+ }
+};
+
+} //end namespace internal
+
+ /** \svd_module
+ *
+ * \return the singular value decomposition of \c *this computed by
+ * BDC Algorithm
+ *
+ * \sa class BDCSVD
+ */
+/*
+template<typename Derived>
+BDCSVD<typename MatrixBase<Derived>::PlainObject>
+MatrixBase<Derived>::bdcSvd(unsigned int computationOptions) const
+{
+ return BDCSVD<PlainObject>(*this, computationOptions);
+}
+*/
+
+} // end namespace Eigen
+
+#endif
diff --git a/unsupported/Eigen/src/SVD/CMakeLists.txt b/unsupported/Eigen/src/SVD/CMakeLists.txt
new file mode 100644
index 000000000..b40baf092
--- /dev/null
+++ b/unsupported/Eigen/src/SVD/CMakeLists.txt
@@ -0,0 +1,6 @@
+FILE(GLOB Eigen_SVD_SRCS "*.h")
+
+INSTALL(FILES
+ ${Eigen_SVD_SRCS}
+ DESTINATION ${INCLUDE_INSTALL_DIR}unsupported/Eigen/src/SVD COMPONENT Devel
+ )
diff --git a/unsupported/Eigen/src/SVD/JacobiSVD.h b/unsupported/Eigen/src/SVD/JacobiSVD.h
new file mode 100644
index 000000000..02fac409e
--- /dev/null
+++ b/unsupported/Eigen/src/SVD/JacobiSVD.h
@@ -0,0 +1,782 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2009-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_JACOBISVD_H
+#define EIGEN_JACOBISVD_H
+
+namespace Eigen {
+
+namespace internal {
+// forward declaration (needed by ICC)
+// the empty body is required by MSVC
+template<typename MatrixType, int QRPreconditioner,
+ bool IsComplex = NumTraits<typename MatrixType::Scalar>::IsComplex>
+struct svd_precondition_2x2_block_to_be_real {};
+
+/*** QR preconditioners (R-SVD)
+ ***
+ *** Their role is to reduce the problem of computing the SVD to the case of a square matrix.
+ *** This approach, known as R-SVD, is an optimization for rectangular-enough matrices, and is a requirement for
+ *** JacobiSVD which by itself is only able to work on square matrices.
+ ***/
+
+enum { PreconditionIfMoreColsThanRows, PreconditionIfMoreRowsThanCols };
+
+template<typename MatrixType, int QRPreconditioner, int Case>
+struct qr_preconditioner_should_do_anything
+{
+ enum { a = MatrixType::RowsAtCompileTime != Dynamic &&
+ MatrixType::ColsAtCompileTime != Dynamic &&
+ MatrixType::ColsAtCompileTime <= MatrixType::RowsAtCompileTime,
+ b = MatrixType::RowsAtCompileTime != Dynamic &&
+ MatrixType::ColsAtCompileTime != Dynamic &&
+ MatrixType::RowsAtCompileTime <= MatrixType::ColsAtCompileTime,
+ ret = !( (QRPreconditioner == NoQRPreconditioner) ||
+ (Case == PreconditionIfMoreColsThanRows && bool(a)) ||
+ (Case == PreconditionIfMoreRowsThanCols && bool(b)) )
+ };
+};
+
+template<typename MatrixType, int QRPreconditioner, int Case,
+ bool DoAnything = qr_preconditioner_should_do_anything<MatrixType, QRPreconditioner, Case>::ret
+> struct qr_preconditioner_impl {};
+
+template<typename MatrixType, int QRPreconditioner, int Case>
+class qr_preconditioner_impl<MatrixType, QRPreconditioner, Case, false>
+{
+public:
+ typedef typename MatrixType::Index Index;
+ void allocate(const JacobiSVD<MatrixType, QRPreconditioner>&) {}
+ bool run(JacobiSVD<MatrixType, QRPreconditioner>&, const MatrixType&)
+ {
+ return false;
+ }
+};
+
+/*** preconditioner using FullPivHouseholderQR ***/
+
+template<typename MatrixType>
+class qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true>
+{
+public:
+ typedef typename MatrixType::Index Index;
+ typedef typename MatrixType::Scalar Scalar;
+ enum
+ {
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime
+ };
+ typedef Matrix<Scalar, 1, RowsAtCompileTime, RowMajor, 1, MaxRowsAtCompileTime> WorkspaceType;
+
+ void allocate(const JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd)
+ {
+ if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols())
+ {
+ m_qr.~QRType();
+ ::new (&m_qr) QRType(svd.rows(), svd.cols());
+ }
+ if (svd.m_computeFullU) m_workspace.resize(svd.rows());
+ }
+
+ bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)
+ {
+ if(matrix.rows() > matrix.cols())
+ {
+ m_qr.compute(matrix);
+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>();
+ if(svd.m_computeFullU) m_qr.matrixQ().evalTo(svd.m_matrixU, m_workspace);
+ if(svd.computeV()) svd.m_matrixV = m_qr.colsPermutation();
+ return true;
+ }
+ return false;
+ }
+private:
+ typedef FullPivHouseholderQR<MatrixType> QRType;
+ QRType m_qr;
+ WorkspaceType m_workspace;
+};
+
+template<typename MatrixType>
+class qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true>
+{
+public:
+ typedef typename MatrixType::Index Index;
+ typedef typename MatrixType::Scalar Scalar;
+ enum
+ {
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
+ ColsAtCompileTime = MatrixType::ColsAtCompileTime,
+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
+ Options = MatrixType::Options
+ };
+ typedef Matrix<Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime>
+ TransposeTypeWithSameStorageOrder;
+
+ void allocate(const JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd)
+ {
+ if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols())
+ {
+ m_qr.~QRType();
+ ::new (&m_qr) QRType(svd.cols(), svd.rows());
+ }
+ m_adjoint.resize(svd.cols(), svd.rows());
+ if (svd.m_computeFullV) m_workspace.resize(svd.cols());
+ }
+
+ bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)
+ {
+ if(matrix.cols() > matrix.rows())
+ {
+ m_adjoint = matrix.adjoint();
+ m_qr.compute(m_adjoint);
+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint();
+ if(svd.m_computeFullV) m_qr.matrixQ().evalTo(svd.m_matrixV, m_workspace);
+ if(svd.computeU()) svd.m_matrixU = m_qr.colsPermutation();
+ return true;
+ }
+ else return false;
+ }
+private:
+ typedef FullPivHouseholderQR<TransposeTypeWithSameStorageOrder> QRType;
+ QRType m_qr;
+ TransposeTypeWithSameStorageOrder m_adjoint;
+ typename internal::plain_row_type<MatrixType>::type m_workspace;
+};
+
+/*** preconditioner using ColPivHouseholderQR ***/
+
+template<typename MatrixType>
+class qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true>
+{
+public:
+ typedef typename MatrixType::Index Index;
+
+ void allocate(const JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd)
+ {
+ if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols())
+ {
+ m_qr.~QRType();
+ ::new (&m_qr) QRType(svd.rows(), svd.cols());
+ }
+ if (svd.m_computeFullU) m_workspace.resize(svd.rows());
+ else if (svd.m_computeThinU) m_workspace.resize(svd.cols());
+ }
+
+ bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)
+ {
+ if(matrix.rows() > matrix.cols())
+ {
+ m_qr.compute(matrix);
+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>();
+ if(svd.m_computeFullU) m_qr.householderQ().evalTo(svd.m_matrixU, m_workspace);
+ else if(svd.m_computeThinU)
+ {
+ svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols());
+ m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU, m_workspace);
+ }
+ if(svd.computeV()) svd.m_matrixV = m_qr.colsPermutation();
+ return true;
+ }
+ return false;
+ }
+
+private:
+ typedef ColPivHouseholderQR<MatrixType> QRType;
+ QRType m_qr;
+ typename internal::plain_col_type<MatrixType>::type m_workspace;
+};
+
+template<typename MatrixType>
+class qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true>
+{
+public:
+ typedef typename MatrixType::Index Index;
+ typedef typename MatrixType::Scalar Scalar;
+ enum
+ {
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
+ ColsAtCompileTime = MatrixType::ColsAtCompileTime,
+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
+ Options = MatrixType::Options
+ };
+
+ typedef Matrix<Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime>
+ TransposeTypeWithSameStorageOrder;
+
+ void allocate(const JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd)
+ {
+ if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols())
+ {
+ m_qr.~QRType();
+ ::new (&m_qr) QRType(svd.cols(), svd.rows());
+ }
+ if (svd.m_computeFullV) m_workspace.resize(svd.cols());
+ else if (svd.m_computeThinV) m_workspace.resize(svd.rows());
+ m_adjoint.resize(svd.cols(), svd.rows());
+ }
+
+ bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)
+ {
+ if(matrix.cols() > matrix.rows())
+ {
+ m_adjoint = matrix.adjoint();
+ m_qr.compute(m_adjoint);
+
+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint();
+ if(svd.m_computeFullV) m_qr.householderQ().evalTo(svd.m_matrixV, m_workspace);
+ else if(svd.m_computeThinV)
+ {
+ svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows());
+ m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV, m_workspace);
+ }
+ if(svd.computeU()) svd.m_matrixU = m_qr.colsPermutation();
+ return true;
+ }
+ else return false;
+ }
+
+private:
+ typedef ColPivHouseholderQR<TransposeTypeWithSameStorageOrder> QRType;
+ QRType m_qr;
+ TransposeTypeWithSameStorageOrder m_adjoint;
+ typename internal::plain_row_type<MatrixType>::type m_workspace;
+};
+
+/*** preconditioner using HouseholderQR ***/
+
+template<typename MatrixType>
+class qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true>
+{
+public:
+ typedef typename MatrixType::Index Index;
+
+ void allocate(const JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd)
+ {
+ if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols())
+ {
+ m_qr.~QRType();
+ ::new (&m_qr) QRType(svd.rows(), svd.cols());
+ }
+ if (svd.m_computeFullU) m_workspace.resize(svd.rows());
+ else if (svd.m_computeThinU) m_workspace.resize(svd.cols());
+ }
+
+ bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd, const MatrixType& matrix)
+ {
+ if(matrix.rows() > matrix.cols())
+ {
+ m_qr.compute(matrix);
+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>();
+ if(svd.m_computeFullU) m_qr.householderQ().evalTo(svd.m_matrixU, m_workspace);
+ else if(svd.m_computeThinU)
+ {
+ svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols());
+ m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU, m_workspace);
+ }
+ if(svd.computeV()) svd.m_matrixV.setIdentity(matrix.cols(), matrix.cols());
+ return true;
+ }
+ return false;
+ }
+private:
+ typedef HouseholderQR<MatrixType> QRType;
+ QRType m_qr;
+ typename internal::plain_col_type<MatrixType>::type m_workspace;
+};
+
+template<typename MatrixType>
+class qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true>
+{
+public:
+ typedef typename MatrixType::Index Index;
+ typedef typename MatrixType::Scalar Scalar;
+ enum
+ {
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
+ ColsAtCompileTime = MatrixType::ColsAtCompileTime,
+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
+ Options = MatrixType::Options
+ };
+
+ typedef Matrix<Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime>
+ TransposeTypeWithSameStorageOrder;
+
+ void allocate(const JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd)
+ {
+ if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols())
+ {
+ m_qr.~QRType();
+ ::new (&m_qr) QRType(svd.cols(), svd.rows());
+ }
+ if (svd.m_computeFullV) m_workspace.resize(svd.cols());
+ else if (svd.m_computeThinV) m_workspace.resize(svd.rows());
+ m_adjoint.resize(svd.cols(), svd.rows());
+ }
+
+ bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd, const MatrixType& matrix)
+ {
+ if(matrix.cols() > matrix.rows())
+ {
+ m_adjoint = matrix.adjoint();
+ m_qr.compute(m_adjoint);
+
+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint();
+ if(svd.m_computeFullV) m_qr.householderQ().evalTo(svd.m_matrixV, m_workspace);
+ else if(svd.m_computeThinV)
+ {
+ svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows());
+ m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV, m_workspace);
+ }
+ if(svd.computeU()) svd.m_matrixU.setIdentity(matrix.rows(), matrix.rows());
+ return true;
+ }
+ else return false;
+ }
+
+private:
+ typedef HouseholderQR<TransposeTypeWithSameStorageOrder> QRType;
+ QRType m_qr;
+ TransposeTypeWithSameStorageOrder m_adjoint;
+ typename internal::plain_row_type<MatrixType>::type m_workspace;
+};
+
+/*** 2x2 SVD implementation
+ ***
+ *** JacobiSVD consists in performing a series of 2x2 SVD subproblems
+ ***/
+
+template<typename MatrixType, int QRPreconditioner>
+struct svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, false>
+{
+ typedef JacobiSVD<MatrixType, QRPreconditioner> SVD;
+ typedef typename SVD::Index Index;
+ static void run(typename SVD::WorkMatrixType&, SVD&, Index, Index) {}
+};
+
+template<typename MatrixType, int QRPreconditioner>
+struct svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, true>
+{
+ typedef JacobiSVD<MatrixType, QRPreconditioner> SVD;
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::RealScalar RealScalar;
+ typedef typename SVD::Index Index;
+ static void run(typename SVD::WorkMatrixType& work_matrix, SVD& svd, Index p, Index q)
+ {
+ using std::sqrt;
+ Scalar z;
+ JacobiRotation<Scalar> rot;
+ RealScalar n = sqrt(numext::abs2(work_matrix.coeff(p,p)) + numext::abs2(work_matrix.coeff(q,p)));
+ if(n==0)
+ {
+ z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
+ work_matrix.row(p) *= z;
+ if(svd.computeU()) svd.m_matrixU.col(p) *= conj(z);
+ z = abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q);
+ work_matrix.row(q) *= z;
+ if(svd.computeU()) svd.m_matrixU.col(q) *= conj(z);
+ }
+ else
+ {
+ rot.c() = conj(work_matrix.coeff(p,p)) / n;
+ rot.s() = work_matrix.coeff(q,p) / n;
+ work_matrix.applyOnTheLeft(p,q,rot);
+ if(svd.computeU()) svd.m_matrixU.applyOnTheRight(p,q,rot.adjoint());
+ if(work_matrix.coeff(p,q) != Scalar(0))
+ {
+ Scalar z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
+ work_matrix.col(q) *= z;
+ if(svd.computeV()) svd.m_matrixV.col(q) *= z;
+ }
+ if(work_matrix.coeff(q,q) != Scalar(0))
+ {
+ z = abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q);
+ work_matrix.row(q) *= z;
+ if(svd.computeU()) svd.m_matrixU.col(q) *= conj(z);
+ }
+ }
+ }
+};
+
+template<typename MatrixType, typename RealScalar, typename Index>
+void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q,
+ JacobiRotation<RealScalar> *j_left,
+ JacobiRotation<RealScalar> *j_right)
+{
+ using std::sqrt;
+ Matrix<RealScalar,2,2> m;
+ m << numext::real(matrix.coeff(p,p)), numext::real(matrix.coeff(p,q)),
+ numext::real(matrix.coeff(q,p)), numext::real(matrix.coeff(q,q));
+ JacobiRotation<RealScalar> rot1;
+ RealScalar t = m.coeff(0,0) + m.coeff(1,1);
+ RealScalar d = m.coeff(1,0) - m.coeff(0,1);
+ if(t == RealScalar(0))
+ {
+ rot1.c() = RealScalar(0);
+ rot1.s() = d > RealScalar(0) ? RealScalar(1) : RealScalar(-1);
+ }
+ else
+ {
+ RealScalar u = d / t;
+ rot1.c() = RealScalar(1) / sqrt(RealScalar(1) + numext::abs2(u));
+ rot1.s() = rot1.c() * u;
+ }
+ m.applyOnTheLeft(0,1,rot1);
+ j_right->makeJacobi(m,0,1);
+ *j_left = rot1 * j_right->transpose();
+}
+
+} // end namespace internal
+
+/** \ingroup SVD_Module
+ *
+ *
+ * \class JacobiSVD
+ *
+ * \brief Two-sided Jacobi SVD decomposition of a rectangular matrix
+ *
+ * \param MatrixType the type of the matrix of which we are computing the SVD decomposition
+ * \param QRPreconditioner this optional parameter allows to specify the type of QR decomposition that will be used internally
+ * for the R-SVD step for non-square matrices. See discussion of possible values below.
+ *
+ * SVD decomposition consists in decomposing any n-by-p matrix \a A as a product
+ * \f[ A = U S V^* \f]
+ * where \a U is a n-by-n unitary, \a V is a p-by-p unitary, and \a S is a n-by-p real positive matrix which is zero outside of its main diagonal;
+ * the diagonal entries of S are known as the \em singular \em values of \a A and the columns of \a U and \a V are known as the left
+ * and right \em singular \em vectors of \a A respectively.
+ *
+ * Singular values are always sorted in decreasing order.
+ *
+ * This JacobiSVD decomposition computes only the singular values by default. If you want \a U or \a V, you need to ask for them explicitly.
+ *
+ * You can ask for only \em thin \a U or \a V to be computed, meaning the following. In case of a rectangular n-by-p matrix, letting \a m be the
+ * smaller value among \a n and \a p, there are only \a m singular vectors; the remaining columns of \a U and \a V do not correspond to actual
+ * singular vectors. Asking for \em thin \a U or \a V means asking for only their \a m first columns to be formed. So \a U is then a n-by-m matrix,
+ * and \a V is then a p-by-m matrix. Notice that thin \a U and \a V are all you need for (least squares) solving.
+ *
+ * Here's an example demonstrating basic usage:
+ * \include JacobiSVD_basic.cpp
+ * Output: \verbinclude JacobiSVD_basic.out
+ *
+ * This JacobiSVD class is a two-sided Jacobi R-SVD decomposition, ensuring optimal reliability and accuracy. The downside is that it's slower than
+ * bidiagonalizing SVD algorithms for large square matrices; however its complexity is still \f$ O(n^2p) \f$ where \a n is the smaller dimension and
+ * \a p is the greater dimension, meaning that it is still of the same order of complexity as the faster bidiagonalizing R-SVD algorithms.
+ * In particular, like any R-SVD, it takes advantage of non-squareness in that its complexity is only linear in the greater dimension.
+ *
+ * If the input matrix has inf or nan coefficients, the result of the computation is undefined, but the computation is guaranteed to
+ * terminate in finite (and reasonable) time.
+ *
+ * The possible values for QRPreconditioner are:
+ * \li ColPivHouseholderQRPreconditioner is the default. In practice it's very safe. It uses column-pivoting QR.
+ * \li FullPivHouseholderQRPreconditioner, is the safest and slowest. It uses full-pivoting QR.
+ * Contrary to other QRs, it doesn't allow computing thin unitaries.
+ * \li HouseholderQRPreconditioner is the fastest, and less safe and accurate than the pivoting variants. It uses non-pivoting QR.
+ * This is very similar in safety and accuracy to the bidiagonalization process used by bidiagonalizing SVD algorithms (since bidiagonalization
+ * is inherently non-pivoting). However the resulting SVD is still more reliable than bidiagonalizing SVDs because the Jacobi-based iterarive
+ * process is more reliable than the optimized bidiagonal SVD iterations.
+ * \li NoQRPreconditioner allows not to use a QR preconditioner at all. This is useful if you know that you will only be computing
+ * JacobiSVD decompositions of square matrices. Non-square matrices require a QR preconditioner. Using this option will result in
+ * faster compilation and smaller executable code. It won't significantly speed up computation, since JacobiSVD is always checking
+ * if QR preconditioning is needed before applying it anyway.
+ *
+ * \sa MatrixBase::jacobiSvd()
+ */
+template<typename _MatrixType, int QRPreconditioner>
+class JacobiSVD : public SVDBase<_MatrixType>
+{
+ public:
+
+ typedef _MatrixType MatrixType;
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
+ typedef typename MatrixType::Index Index;
+ enum {
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
+ ColsAtCompileTime = MatrixType::ColsAtCompileTime,
+ DiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime),
+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
+ MaxDiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(MaxRowsAtCompileTime,MaxColsAtCompileTime),
+ MatrixOptions = MatrixType::Options
+ };
+
+ typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime,
+ MatrixOptions, MaxRowsAtCompileTime, MaxRowsAtCompileTime>
+ MatrixUType;
+ typedef Matrix<Scalar, ColsAtCompileTime, ColsAtCompileTime,
+ MatrixOptions, MaxColsAtCompileTime, MaxColsAtCompileTime>
+ MatrixVType;
+ typedef typename internal::plain_diag_type<MatrixType, RealScalar>::type SingularValuesType;
+ typedef typename internal::plain_row_type<MatrixType>::type RowType;
+ typedef typename internal::plain_col_type<MatrixType>::type ColType;
+ typedef Matrix<Scalar, DiagSizeAtCompileTime, DiagSizeAtCompileTime,
+ MatrixOptions, MaxDiagSizeAtCompileTime, MaxDiagSizeAtCompileTime>
+ WorkMatrixType;
+
+ /** \brief Default Constructor.
+ *
+ * The default constructor is useful in cases in which the user intends to
+ * perform decompositions via JacobiSVD::compute(const MatrixType&).
+ */
+ JacobiSVD()
+ : SVDBase<_MatrixType>::SVDBase()
+ {}
+
+
+ /** \brief Default Constructor with memory preallocation
+ *
+ * Like the default constructor but with preallocation of the internal data
+ * according to the specified problem size.
+ * \sa JacobiSVD()
+ */
+ JacobiSVD(Index rows, Index cols, unsigned int computationOptions = 0)
+ : SVDBase<_MatrixType>::SVDBase()
+ {
+ allocate(rows, cols, computationOptions);
+ }
+
+ /** \brief Constructor performing the decomposition of given matrix.
+ *
+ * \param matrix the matrix to decompose
+ * \param computationOptions optional parameter allowing to specify if you want full or thin U or V unitaries to be computed.
+ * By default, none is computed. This is a bit-field, the possible bits are #ComputeFullU, #ComputeThinU,
+ * #ComputeFullV, #ComputeThinV.
+ *
+ * Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not
+ * available with the (non-default) FullPivHouseholderQR preconditioner.
+ */
+ JacobiSVD(const MatrixType& matrix, unsigned int computationOptions = 0)
+ : SVDBase<_MatrixType>::SVDBase()
+ {
+ compute(matrix, computationOptions);
+ }
+
+ /** \brief Method performing the decomposition of given matrix using custom options.
+ *
+ * \param matrix the matrix to decompose
+ * \param computationOptions optional parameter allowing to specify if you want full or thin U or V unitaries to be computed.
+ * By default, none is computed. This is a bit-field, the possible bits are #ComputeFullU, #ComputeThinU,
+ * #ComputeFullV, #ComputeThinV.
+ *
+ * Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not
+ * available with the (non-default) FullPivHouseholderQR preconditioner.
+ */
+ SVDBase<MatrixType>& compute(const MatrixType& matrix, unsigned int computationOptions);
+
+ /** \brief Method performing the decomposition of given matrix using current options.
+ *
+ * \param matrix the matrix to decompose
+ *
+ * This method uses the current \a computationOptions, as already passed to the constructor or to compute(const MatrixType&, unsigned int).
+ */
+ SVDBase<MatrixType>& compute(const MatrixType& matrix)
+ {
+ return compute(matrix, this->m_computationOptions);
+ }
+
+ /** \returns a (least squares) solution of \f$ A x = b \f$ using the current SVD decomposition of A.
+ *
+ * \param b the right-hand-side of the equation to solve.
+ *
+ * \note Solving requires both U and V to be computed. Thin U and V are enough, there is no need for full U or V.
+ *
+ * \note SVD solving is implicitly least-squares. Thus, this method serves both purposes of exact solving and least-squares solving.
+ * In other words, the returned solution is guaranteed to minimize the Euclidean norm \f$ \Vert A x - b \Vert \f$.
+ */
+ template<typename Rhs>
+ inline const internal::solve_retval<JacobiSVD, Rhs>
+ solve(const MatrixBase<Rhs>& b) const
+ {
+ eigen_assert(this->m_isInitialized && "JacobiSVD is not initialized.");
+ eigen_assert(SVDBase<MatrixType>::computeU() && SVDBase<MatrixType>::computeV() && "JacobiSVD::solve() requires both unitaries U and V to be computed (thin unitaries suffice).");
+ return internal::solve_retval<JacobiSVD, Rhs>(*this, b.derived());
+ }
+
+
+
+ private:
+ void allocate(Index rows, Index cols, unsigned int computationOptions);
+
+ protected:
+ WorkMatrixType m_workMatrix;
+
+ template<typename __MatrixType, int _QRPreconditioner, bool _IsComplex>
+ friend struct internal::svd_precondition_2x2_block_to_be_real;
+ template<typename __MatrixType, int _QRPreconditioner, int _Case, bool _DoAnything>
+ friend struct internal::qr_preconditioner_impl;
+
+ internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreColsThanRows> m_qr_precond_morecols;
+ internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreRowsThanCols> m_qr_precond_morerows;
+};
+
+template<typename MatrixType, int QRPreconditioner>
+void JacobiSVD<MatrixType, QRPreconditioner>::allocate(Index rows, Index cols, unsigned int computationOptions)
+{
+ if (SVDBase<MatrixType>::allocate(rows, cols, computationOptions)) return;
+
+ if (QRPreconditioner == FullPivHouseholderQRPreconditioner)
+ {
+ eigen_assert(!(this->m_computeThinU || this->m_computeThinV) &&
+ "JacobiSVD: can't compute thin U or thin V with the FullPivHouseholderQR preconditioner. "
+ "Use the ColPivHouseholderQR preconditioner instead.");
+ }
+
+ m_workMatrix.resize(this->m_diagSize, this->m_diagSize);
+
+ if(this->m_cols>this->m_rows) m_qr_precond_morecols.allocate(*this);
+ if(this->m_rows>this->m_cols) m_qr_precond_morerows.allocate(*this);
+}
+
+template<typename MatrixType, int QRPreconditioner>
+SVDBase<MatrixType>&
+JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsigned int computationOptions)
+{
+ using std::abs;
+ allocate(matrix.rows(), matrix.cols(), computationOptions);
+
+ // currently we stop when we reach precision 2*epsilon as the last bit of precision can require an unreasonable number of iterations,
+ // only worsening the precision of U and V as we accumulate more rotations
+ const RealScalar precision = RealScalar(2) * NumTraits<Scalar>::epsilon();
+
+ // limit for very small denormal numbers to be considered zero in order to avoid infinite loops (see bug 286)
+ const RealScalar considerAsZero = RealScalar(2) * std::numeric_limits<RealScalar>::denorm_min();
+
+ /*** step 1. The R-SVD step: we use a QR decomposition to reduce to the case of a square matrix */
+
+ if(!m_qr_precond_morecols.run(*this, matrix) && !m_qr_precond_morerows.run(*this, matrix))
+ {
+ m_workMatrix = matrix.block(0,0,this->m_diagSize,this->m_diagSize);
+ if(this->m_computeFullU) this->m_matrixU.setIdentity(this->m_rows,this->m_rows);
+ if(this->m_computeThinU) this->m_matrixU.setIdentity(this->m_rows,this->m_diagSize);
+ if(this->m_computeFullV) this->m_matrixV.setIdentity(this->m_cols,this->m_cols);
+ if(this->m_computeThinV) this->m_matrixV.setIdentity(this->m_cols, this->m_diagSize);
+ }
+
+ /*** step 2. The main Jacobi SVD iteration. ***/
+
+ bool finished = false;
+ while(!finished)
+ {
+ finished = true;
+
+ // do a sweep: for all index pairs (p,q), perform SVD of the corresponding 2x2 sub-matrix
+
+ for(Index p = 1; p < this->m_diagSize; ++p)
+ {
+ for(Index q = 0; q < p; ++q)
+ {
+ // if this 2x2 sub-matrix is not diagonal already...
+ // notice that this comparison will evaluate to false if any NaN is involved, ensuring that NaN's don't
+ // keep us iterating forever. Similarly, small denormal numbers are considered zero.
+ using std::max;
+ RealScalar threshold = (max)(considerAsZero, precision * (max)(abs(m_workMatrix.coeff(p,p)),
+ abs(m_workMatrix.coeff(q,q))));
+ if((max)(abs(m_workMatrix.coeff(p,q)),abs(m_workMatrix.coeff(q,p))) > threshold)
+ {
+ finished = false;
+
+ // perform SVD decomposition of 2x2 sub-matrix corresponding to indices p,q to make it diagonal
+ internal::svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner>::run(m_workMatrix, *this, p, q);
+ JacobiRotation<RealScalar> j_left, j_right;
+ internal::real_2x2_jacobi_svd(m_workMatrix, p, q, &j_left, &j_right);
+
+ // accumulate resulting Jacobi rotations
+ m_workMatrix.applyOnTheLeft(p,q,j_left);
+ if(SVDBase<MatrixType>::computeU()) this->m_matrixU.applyOnTheRight(p,q,j_left.transpose());
+
+ m_workMatrix.applyOnTheRight(p,q,j_right);
+ if(SVDBase<MatrixType>::computeV()) this->m_matrixV.applyOnTheRight(p,q,j_right);
+ }
+ }
+ }
+ }
+
+ /*** step 3. The work matrix is now diagonal, so ensure it's positive so its diagonal entries are the singular values ***/
+
+ for(Index i = 0; i < this->m_diagSize; ++i)
+ {
+ RealScalar a = abs(m_workMatrix.coeff(i,i));
+ this->m_singularValues.coeffRef(i) = a;
+ if(SVDBase<MatrixType>::computeU() && (a!=RealScalar(0))) this->m_matrixU.col(i) *= this->m_workMatrix.coeff(i,i)/a;
+ }
+
+ /*** step 4. Sort singular values in descending order and compute the number of nonzero singular values ***/
+
+ this->m_nonzeroSingularValues = this->m_diagSize;
+ for(Index i = 0; i < this->m_diagSize; i++)
+ {
+ Index pos;
+ RealScalar maxRemainingSingularValue = this->m_singularValues.tail(this->m_diagSize-i).maxCoeff(&pos);
+ if(maxRemainingSingularValue == RealScalar(0))
+ {
+ this->m_nonzeroSingularValues = i;
+ break;
+ }
+ if(pos)
+ {
+ pos += i;
+ std::swap(this->m_singularValues.coeffRef(i), this->m_singularValues.coeffRef(pos));
+ if(SVDBase<MatrixType>::computeU()) this->m_matrixU.col(pos).swap(this->m_matrixU.col(i));
+ if(SVDBase<MatrixType>::computeV()) this->m_matrixV.col(pos).swap(this->m_matrixV.col(i));
+ }
+ }
+
+ this->m_isInitialized = true;
+ return *this;
+}
+
+namespace internal {
+template<typename _MatrixType, int QRPreconditioner, typename Rhs>
+struct solve_retval<JacobiSVD<_MatrixType, QRPreconditioner>, Rhs>
+ : solve_retval_base<JacobiSVD<_MatrixType, QRPreconditioner>, Rhs>
+{
+ typedef JacobiSVD<_MatrixType, QRPreconditioner> JacobiSVDType;
+ EIGEN_MAKE_SOLVE_HELPERS(JacobiSVDType,Rhs)
+
+ template<typename Dest> void evalTo(Dest& dst) const
+ {
+ eigen_assert(rhs().rows() == dec().rows());
+
+ // A = U S V^*
+ // So A^{-1} = V S^{-1} U^*
+
+ Index diagSize = (std::min)(dec().rows(), dec().cols());
+ typename JacobiSVDType::SingularValuesType invertedSingVals(diagSize);
+
+ Index nonzeroSingVals = dec().nonzeroSingularValues();
+ invertedSingVals.head(nonzeroSingVals) = dec().singularValues().head(nonzeroSingVals).array().inverse();
+ invertedSingVals.tail(diagSize - nonzeroSingVals).setZero();
+
+ dst = dec().matrixV().leftCols(diagSize)
+ * invertedSingVals.asDiagonal()
+ * dec().matrixU().leftCols(diagSize).adjoint()
+ * rhs();
+ }
+};
+} // end namespace internal
+
+/** \svd_module
+ *
+ * \return the singular value decomposition of \c *this computed by two-sided
+ * Jacobi transformations.
+ *
+ * \sa class JacobiSVD
+ */
+template<typename Derived>
+JacobiSVD<typename MatrixBase<Derived>::PlainObject>
+MatrixBase<Derived>::jacobiSvd(unsigned int computationOptions) const
+{
+ return JacobiSVD<PlainObject>(*this, computationOptions);
+}
+
+} // end namespace Eigen
+
+#endif // EIGEN_JACOBISVD_H
diff --git a/unsupported/Eigen/src/SVD/SVDBase.h b/unsupported/Eigen/src/SVD/SVDBase.h
new file mode 100644
index 000000000..fd8af3b8c
--- /dev/null
+++ b/unsupported/Eigen/src/SVD/SVDBase.h
@@ -0,0 +1,236 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2009-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Copyright (C) 2013 Gauthier Brun <brun.gauthier@gmail.com>
+// Copyright (C) 2013 Nicolas Carre <nicolas.carre@ensimag.fr>
+// Copyright (C) 2013 Jean Ceccato <jean.ceccato@ensimag.fr>
+// Copyright (C) 2013 Pierre Zoppitelli <pierre.zoppitelli@ensimag.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_SVD_H
+#define EIGEN_SVD_H
+
+namespace Eigen {
+/** \ingroup SVD_Module
+ *
+ *
+ * \class SVDBase
+ *
+ * \brief Mother class of SVD classes algorithms
+ *
+ * \param MatrixType the type of the matrix of which we are computing the SVD decomposition
+ * SVD decomposition consists in decomposing any n-by-p matrix \a A as a product
+ * \f[ A = U S V^* \f]
+ * where \a U is a n-by-n unitary, \a V is a p-by-p unitary, and \a S is a n-by-p real positive matrix which is zero outside of its main diagonal;
+ * the diagonal entries of S are known as the \em singular \em values of \a A and the columns of \a U and \a V are known as the left
+ * and right \em singular \em vectors of \a A respectively.
+ *
+ * Singular values are always sorted in decreasing order.
+ *
+ *
+ * You can ask for only \em thin \a U or \a V to be computed, meaning the following. In case of a rectangular n-by-p matrix, letting \a m be the
+ * smaller value among \a n and \a p, there are only \a m singular vectors; the remaining columns of \a U and \a V do not correspond to actual
+ * singular vectors. Asking for \em thin \a U or \a V means asking for only their \a m first columns to be formed. So \a U is then a n-by-m matrix,
+ * and \a V is then a p-by-m matrix. Notice that thin \a U and \a V are all you need for (least squares) solving.
+ *
+ * If the input matrix has inf or nan coefficients, the result of the computation is undefined, but the computation is guaranteed to
+ * terminate in finite (and reasonable) time.
+ * \sa MatrixBase::genericSvd()
+ */
+template<typename _MatrixType>
+class SVDBase
+{
+
+public:
+ typedef _MatrixType MatrixType;
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
+ typedef typename MatrixType::Index Index;
+ enum {
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
+ ColsAtCompileTime = MatrixType::ColsAtCompileTime,
+ DiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime),
+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
+ MaxDiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(MaxRowsAtCompileTime,MaxColsAtCompileTime),
+ MatrixOptions = MatrixType::Options
+ };
+
+ typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime,
+ MatrixOptions, MaxRowsAtCompileTime, MaxRowsAtCompileTime>
+ MatrixUType;
+ typedef Matrix<Scalar, ColsAtCompileTime, ColsAtCompileTime,
+ MatrixOptions, MaxColsAtCompileTime, MaxColsAtCompileTime>
+ MatrixVType;
+ typedef typename internal::plain_diag_type<MatrixType, RealScalar>::type SingularValuesType;
+ typedef typename internal::plain_row_type<MatrixType>::type RowType;
+ typedef typename internal::plain_col_type<MatrixType>::type ColType;
+ typedef Matrix<Scalar, DiagSizeAtCompileTime, DiagSizeAtCompileTime,
+ MatrixOptions, MaxDiagSizeAtCompileTime, MaxDiagSizeAtCompileTime>
+ WorkMatrixType;
+
+
+
+
+ /** \brief Method performing the decomposition of given matrix using custom options.
+ *
+ * \param matrix the matrix to decompose
+ * \param computationOptions optional parameter allowing to specify if you want full or thin U or V unitaries to be computed.
+ * By default, none is computed. This is a bit-field, the possible bits are #ComputeFullU, #ComputeThinU,
+ * #ComputeFullV, #ComputeThinV.
+ *
+ * Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not
+ * available with the (non-default) FullPivHouseholderQR preconditioner.
+ */
+ SVDBase& compute(const MatrixType& matrix, unsigned int computationOptions);
+
+ /** \brief Method performing the decomposition of given matrix using current options.
+ *
+ * \param matrix the matrix to decompose
+ *
+ * This method uses the current \a computationOptions, as already passed to the constructor or to compute(const MatrixType&, unsigned int).
+ */
+ //virtual SVDBase& compute(const MatrixType& matrix) = 0;
+ SVDBase& compute(const MatrixType& matrix);
+
+ /** \returns the \a U matrix.
+ *
+ * For the SVDBase decomposition of a n-by-p matrix, letting \a m be the minimum of \a n and \a p,
+ * the U matrix is n-by-n if you asked for #ComputeFullU, and is n-by-m if you asked for #ComputeThinU.
+ *
+ * The \a m first columns of \a U are the left singular vectors of the matrix being decomposed.
+ *
+ * This method asserts that you asked for \a U to be computed.
+ */
+ const MatrixUType& matrixU() const
+ {
+ eigen_assert(m_isInitialized && "SVD is not initialized.");
+ eigen_assert(computeU() && "This SVD decomposition didn't compute U. Did you ask for it?");
+ return m_matrixU;
+ }
+
+ /** \returns the \a V matrix.
+ *
+ * For the SVD decomposition of a n-by-p matrix, letting \a m be the minimum of \a n and \a p,
+ * the V matrix is p-by-p if you asked for #ComputeFullV, and is p-by-m if you asked for ComputeThinV.
+ *
+ * The \a m first columns of \a V are the right singular vectors of the matrix being decomposed.
+ *
+ * This method asserts that you asked for \a V to be computed.
+ */
+ const MatrixVType& matrixV() const
+ {
+ eigen_assert(m_isInitialized && "SVD is not initialized.");
+ eigen_assert(computeV() && "This SVD decomposition didn't compute V. Did you ask for it?");
+ return m_matrixV;
+ }
+
+ /** \returns the vector of singular values.
+ *
+ * For the SVD decomposition of a n-by-p matrix, letting \a m be the minimum of \a n and \a p, the
+ * returned vector has size \a m. Singular values are always sorted in decreasing order.
+ */
+ const SingularValuesType& singularValues() const
+ {
+ eigen_assert(m_isInitialized && "SVD is not initialized.");
+ return m_singularValues;
+ }
+
+
+
+ /** \returns the number of singular values that are not exactly 0 */
+ Index nonzeroSingularValues() const
+ {
+ eigen_assert(m_isInitialized && "SVD is not initialized.");
+ return m_nonzeroSingularValues;
+ }
+
+
+ /** \returns true if \a U (full or thin) is asked for in this SVD decomposition */
+ inline bool computeU() const { return m_computeFullU || m_computeThinU; }
+ /** \returns true if \a V (full or thin) is asked for in this SVD decomposition */
+ inline bool computeV() const { return m_computeFullV || m_computeThinV; }
+
+
+ inline Index rows() const { return m_rows; }
+ inline Index cols() const { return m_cols; }
+
+
+protected:
+ // return true if already allocated
+ bool allocate(Index rows, Index cols, unsigned int computationOptions) ;
+
+ MatrixUType m_matrixU;
+ MatrixVType m_matrixV;
+ SingularValuesType m_singularValues;
+ bool m_isInitialized, m_isAllocated;
+ bool m_computeFullU, m_computeThinU;
+ bool m_computeFullV, m_computeThinV;
+ unsigned int m_computationOptions;
+ Index m_nonzeroSingularValues, m_rows, m_cols, m_diagSize;
+
+
+ /** \brief Default Constructor.
+ *
+ * Default constructor of SVDBase
+ */
+ SVDBase()
+ : m_isInitialized(false),
+ m_isAllocated(false),
+ m_computationOptions(0),
+ m_rows(-1), m_cols(-1)
+ {}
+
+
+};
+
+
+template<typename MatrixType>
+bool SVDBase<MatrixType>::allocate(Index rows, Index cols, unsigned int computationOptions)
+{
+ eigen_assert(rows >= 0 && cols >= 0);
+
+ if (m_isAllocated &&
+ rows == m_rows &&
+ cols == m_cols &&
+ computationOptions == m_computationOptions)
+ {
+ return true;
+ }
+
+ m_rows = rows;
+ m_cols = cols;
+ m_isInitialized = false;
+ m_isAllocated = true;
+ m_computationOptions = computationOptions;
+ m_computeFullU = (computationOptions & ComputeFullU) != 0;
+ m_computeThinU = (computationOptions & ComputeThinU) != 0;
+ m_computeFullV = (computationOptions & ComputeFullV) != 0;
+ m_computeThinV = (computationOptions & ComputeThinV) != 0;
+ eigen_assert(!(m_computeFullU && m_computeThinU) && "SVDBase: you can't ask for both full and thin U");
+ eigen_assert(!(m_computeFullV && m_computeThinV) && "SVDBase: you can't ask for both full and thin V");
+ eigen_assert(EIGEN_IMPLIES(m_computeThinU || m_computeThinV, MatrixType::ColsAtCompileTime==Dynamic) &&
+ "SVDBase: thin U and V are only available when your matrix has a dynamic number of columns.");
+
+ m_diagSize = (std::min)(m_rows, m_cols);
+ m_singularValues.resize(m_diagSize);
+ if(RowsAtCompileTime==Dynamic)
+ m_matrixU.resize(m_rows, m_computeFullU ? m_rows
+ : m_computeThinU ? m_diagSize
+ : 0);
+ if(ColsAtCompileTime==Dynamic)
+ m_matrixV.resize(m_cols, m_computeFullV ? m_cols
+ : m_computeThinV ? m_diagSize
+ : 0);
+
+ return false;
+}
+
+}// end namespace
+
+#endif // EIGEN_SVD_H
diff --git a/unsupported/Eigen/src/SVD/TODOBdcsvd.txt b/unsupported/Eigen/src/SVD/TODOBdcsvd.txt
new file mode 100644
index 000000000..0bc9a46e6
--- /dev/null
+++ b/unsupported/Eigen/src/SVD/TODOBdcsvd.txt
@@ -0,0 +1,29 @@
+TO DO LIST
+
+
+
+(optional optimization) - do all the allocations in the allocate part
+ - support static matrices
+ - return a error at compilation time when using integer matrices (int, long, std::complex<int>, ...)
+
+to finish the algorithm :
+ -implement the last part of the algorithm as described on the reference paper.
+ You may find more information on that part on this paper
+
+ -to replace the call to JacobiSVD at the end of the divide algorithm, just after the call to
+ deflation.
+
+(suggested step by step resolution)
+ 0) comment the call to Jacobi in the last part of the divide method and everything right after
+ until the end of the method. What is commented can be a guideline to steps 3) 4) and 6)
+ 1) solve the secular equation (Characteristic equation) on the values that are not null (zi!=0 and di!=0), after the deflation
+ wich should be uncommented in the divide method
+ 2) remember the values of the singular values that are already computed (zi=0)
+ 3) assign the singular values found in m_computed at the right places (with the ones found in step 2) )
+ in decreasing order
+ 4) set the firstcol to zero (except the first element) in m_computed
+ 5) compute all the singular vectors when CompV is set to true and only the left vectors when
+ CompV is set to false
+ 6) multiply naiveU and naiveV to the right by the matrices found, only naiveU when CompV is set to
+ false, /!\ if CompU is false NaiveU has only 2 rows
+ 7) delete everything commented in step 0)
diff --git a/unsupported/Eigen/src/SVD/doneInBDCSVD.txt b/unsupported/Eigen/src/SVD/doneInBDCSVD.txt
new file mode 100644
index 000000000..8563ddab8
--- /dev/null
+++ b/unsupported/Eigen/src/SVD/doneInBDCSVD.txt
@@ -0,0 +1,21 @@
+This unsupported package is about a divide and conquer algorithm to compute SVD.
+
+The implementation follows as closely as possible the following reference paper :
+http://www.cs.yale.edu/publications/techreports/tr933.pdf
+
+The code documentation uses the same names for variables as the reference paper. The code, deflation included, is
+working but there are a few things that could be optimised as explained in the TODOBdsvd.
+
+In the code comments were put at the line where would be the third step of the algorithm so one could simply add the call
+of a function doing the last part of the algorithm and that would not require any knowledge of the part we implemented.
+
+In the TODOBdcsvd we explain what is the main difficulty of the last part and suggest a reference paper to help solve it.
+
+The implemented has trouble with fixed size matrices.
+
+In the actual implementation, it returns matrices of zero when ask to do a svd on an int matrix.
+
+
+Paper for the third part:
+http://www.stat.uchicago.edu/~lekheng/courses/302/classics/greengard-rokhlin.pdf
+
diff --git a/unsupported/Eigen/src/Splines/Spline.h b/unsupported/Eigen/src/Splines/Spline.h
index 1093dfe05..771f10432 100644
--- a/unsupported/Eigen/src/Splines/Spline.h
+++ b/unsupported/Eigen/src/Splines/Spline.h
@@ -295,11 +295,7 @@ namespace Eigen
enum { Order = SplineTraits<SplineType>::OrderAtCompileTime };
enum { DerivativeOrder = DerivativeType::ColsAtCompileTime };
- typedef typename SplineTraits<SplineType>::Scalar Scalar;
-
- typedef typename SplineTraits<SplineType>::BasisVectorType BasisVectorType;
typedef typename SplineTraits<SplineType>::ControlPointVectorType ControlPointVectorType;
-
typedef typename SplineTraits<SplineType,DerivativeOrder>::BasisDerivativeType BasisDerivativeType;
typedef typename BasisDerivativeType::ConstRowXpr BasisDerivativeRowXpr;
@@ -358,7 +354,6 @@ namespace Eigen
typedef typename SplineTraits<SplineType>::Scalar Scalar;
typedef typename SplineTraits<SplineType>::BasisVectorType BasisVectorType;
typedef typename SplineTraits<SplineType>::KnotVectorType KnotVectorType;
- typedef typename SplineTraits<SplineType>::ControlPointVectorType ControlPointVectorType;
const KnotVectorType& U = spline.knots();
diff --git a/unsupported/Eigen/src/Splines/SplineFitting.h b/unsupported/Eigen/src/Splines/SplineFitting.h
index 1b566332f..0265d532c 100644
--- a/unsupported/Eigen/src/Splines/SplineFitting.h
+++ b/unsupported/Eigen/src/Splines/SplineFitting.h
@@ -40,8 +40,6 @@ namespace Eigen
template <typename KnotVectorType>
void KnotAveraging(const KnotVectorType& parameters, DenseIndex degree, KnotVectorType& knots)
{
- typedef typename KnotVectorType::Scalar Scalar;
-
knots.resize(parameters.size()+degree+1);
for (DenseIndex j=1; j<parameters.size()-degree; ++j)
@@ -118,7 +116,6 @@ namespace Eigen
SplineType SplineFitting<SplineType>::Interpolate(const PointArrayType& pts, DenseIndex degree, const KnotVectorType& knot_parameters)
{
typedef typename SplineType::KnotVectorType::Scalar Scalar;
- typedef typename SplineType::BasisVectorType BasisVectorType;
typedef typename SplineType::ControlPointVectorType ControlPointVectorType;
typedef Matrix<Scalar,Dynamic,Dynamic> MatrixType;
diff --git a/unsupported/bench/bench_svd.cpp b/unsupported/bench/bench_svd.cpp
new file mode 100644
index 000000000..01d8231ae
--- /dev/null
+++ b/unsupported/bench/bench_svd.cpp
@@ -0,0 +1,123 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2013 Gauthier Brun <brun.gauthier@gmail.com>
+// Copyright (C) 2013 Nicolas Carre <nicolas.carre@ensimag.fr>
+// Copyright (C) 2013 Jean Ceccato <jean.ceccato@ensimag.fr>
+// Copyright (C) 2013 Pierre Zoppitelli <pierre.zoppitelli@ensimag.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/
+
+// Bench to compare the efficiency of SVD algorithms
+
+#include <iostream>
+#include <bench/BenchTimer.h>
+#include <unsupported/Eigen/SVD>
+
+
+using namespace Eigen;
+using namespace std;
+
+// number of computations of each algorithm before the print of the time
+#ifndef REPEAT
+#define REPEAT 10
+#endif
+
+// number of tests of the same type
+#ifndef NUMBER_SAMPLE
+#define NUMBER_SAMPLE 2
+#endif
+
+template<typename MatrixType>
+void bench_svd(const MatrixType& a = MatrixType())
+{
+ MatrixType m = MatrixType::Random(a.rows(), a.cols());
+ BenchTimer timerJacobi;
+ BenchTimer timerBDC;
+ timerJacobi.reset();
+ timerBDC.reset();
+
+ cout << " Only compute Singular Values" <<endl;
+ for (int k=1; k<=NUMBER_SAMPLE; ++k)
+ {
+ timerBDC.start();
+ for (int i=0; i<REPEAT; ++i)
+ {
+ BDCSVD<MatrixType> bdc_matrix(m);
+ }
+ timerBDC.stop();
+
+ timerJacobi.start();
+ for (int i=0; i<REPEAT; ++i)
+ {
+ JacobiSVD<MatrixType> jacobi_matrix(m);
+ }
+ timerJacobi.stop();
+
+
+ cout << "Sample " << k << " : " << REPEAT << " computations : Jacobi : " << fixed << timerJacobi.value() << "s ";
+ cout << " || " << " BDC : " << timerBDC.value() << "s " <<endl <<endl;
+
+ if (timerBDC.value() >= timerJacobi.value())
+ cout << "KO : BDC is " << timerJacobi.value() / timerBDC.value() << " times faster than Jacobi" <<endl;
+ else
+ cout << "OK : BDC is " << timerJacobi.value() / timerBDC.value() << " times faster than Jacobi" <<endl;
+
+ }
+ cout << " =================" <<endl;
+ std::cout<< std::endl;
+ timerJacobi.reset();
+ timerBDC.reset();
+ cout << " Computes rotaion matrix" <<endl;
+ for (int k=1; k<=NUMBER_SAMPLE; ++k)
+ {
+ timerBDC.start();
+ for (int i=0; i<REPEAT; ++i)
+ {
+ BDCSVD<MatrixType> bdc_matrix(m, ComputeFullU|ComputeFullV);
+ }
+ timerBDC.stop();
+
+ timerJacobi.start();
+ for (int i=0; i<REPEAT; ++i)
+ {
+ JacobiSVD<MatrixType> jacobi_matrix(m, ComputeFullU|ComputeFullV);
+ }
+ timerJacobi.stop();
+
+
+ cout << "Sample " << k << " : " << REPEAT << " computations : Jacobi : " << fixed << timerJacobi.value() << "s ";
+ cout << " || " << " BDC : " << timerBDC.value() << "s " <<endl <<endl;
+
+ if (timerBDC.value() >= timerJacobi.value())
+ cout << "KO : BDC is " << timerJacobi.value() / timerBDC.value() << " times faster than Jacobi" <<endl;
+ else
+ cout << "OK : BDC is " << timerJacobi.value() / timerBDC.value() << " times faster than Jacobi" <<endl;
+
+ }
+ std::cout<< std::endl;
+}
+
+
+
+int main(int argc, char* argv[])
+{
+ std::cout<< std::endl;
+
+ std::cout<<"On a (Dynamic, Dynamic) (6, 6) Matrix" <<std::endl;
+ bench_svd<Matrix<double,Dynamic,Dynamic> >(Matrix<double,Dynamic,Dynamic>(6, 6));
+
+ std::cout<<"On a (Dynamic, Dynamic) (32, 32) Matrix" <<std::endl;
+ bench_svd<Matrix<double,Dynamic,Dynamic> >(Matrix<double,Dynamic,Dynamic>(32, 32));
+
+ //std::cout<<"On a (Dynamic, Dynamic) (128, 128) Matrix" <<std::endl;
+ //bench_svd<Matrix<double,Dynamic,Dynamic> >(Matrix<double,Dynamic,Dynamic>(128, 128));
+
+ std::cout<<"On a (Dynamic, Dynamic) (160, 160) Matrix" <<std::endl;
+ bench_svd<Matrix<double,Dynamic,Dynamic> >(Matrix<double,Dynamic,Dynamic>(160, 160));
+
+ std::cout<< "--------------------------------------------------------------------"<< std::endl;
+
+}
diff --git a/unsupported/test/CMakeLists.txt b/unsupported/test/CMakeLists.txt
index 78b9610d4..a94a3b5e5 100644
--- a/unsupported/test/CMakeLists.txt
+++ b/unsupported/test/CMakeLists.txt
@@ -90,3 +90,4 @@ ei_add_test(splines)
ei_add_test(gmres)
ei_add_test(minres)
ei_add_test(levenberg_marquardt)
+ei_add_test(bdcsvd)
diff --git a/unsupported/test/bdcsvd.cpp b/unsupported/test/bdcsvd.cpp
new file mode 100644
index 000000000..115a649b0
--- /dev/null
+++ b/unsupported/test/bdcsvd.cpp
@@ -0,0 +1,213 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2013 Gauthier Brun <brun.gauthier@gmail.com>
+// Copyright (C) 2013 Nicolas Carre <nicolas.carre@ensimag.fr>
+// Copyright (C) 2013 Jean Ceccato <jean.ceccato@ensimag.fr>
+// Copyright (C) 2013 Pierre Zoppitelli <pierre.zoppitelli@ensimag.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/
+
+#include "svd_common.h"
+#include <iostream>
+#include <Eigen/LU>
+
+// check if "svd" is the good image of "m"
+template<typename MatrixType>
+void bdcsvd_check_full(const MatrixType& m, const BDCSVD<MatrixType>& svd)
+{
+ svd_check_full< MatrixType, BDCSVD< MatrixType > >(m, svd);
+}
+
+// Compare to a reference value
+template<typename MatrixType>
+void bdcsvd_compare_to_full(const MatrixType& m,
+ unsigned int computationOptions,
+ const BDCSVD<MatrixType>& referenceSvd)
+{
+ svd_compare_to_full< MatrixType, BDCSVD< MatrixType > >(m, computationOptions, referenceSvd);
+} // end bdcsvd_compare_to_full
+
+
+template<typename MatrixType>
+void bdcsvd_solve(const MatrixType& m, unsigned int computationOptions)
+{
+ svd_solve< MatrixType, BDCSVD< MatrixType > >(m, computationOptions);
+} // end template bdcsvd_solve
+
+
+// test the computations options
+template<typename MatrixType>
+void bdcsvd_test_all_computation_options(const MatrixType& m)
+{
+ BDCSVD<MatrixType> fullSvd(m, ComputeFullU|ComputeFullV);
+ svd_test_computation_options_1< MatrixType, BDCSVD< MatrixType > >(m, fullSvd);
+ svd_test_computation_options_2< MatrixType, BDCSVD< MatrixType > >(m, fullSvd);
+} // end bdcsvd_test_all_computation_options
+
+
+// Call a test with all the computations options
+template<typename MatrixType>
+void bdcsvd(const MatrixType& a = MatrixType(), bool pickrandom = true)
+{
+ MatrixType m = pickrandom ? MatrixType::Random(a.rows(), a.cols()) : a;
+ bdcsvd_test_all_computation_options<MatrixType>(m);
+} // end template bdcsvd
+
+
+// verify assert
+template<typename MatrixType>
+void bdcsvd_verify_assert(const MatrixType& m)
+{
+ svd_verify_assert< MatrixType, BDCSVD< MatrixType > >(m);
+}// end template bdcsvd_verify_assert
+
+
+// test weird values
+template<typename MatrixType>
+void bdcsvd_inf_nan()
+{
+ svd_inf_nan< MatrixType, BDCSVD< MatrixType > >();
+}// end template bdcsvd_inf_nan
+
+
+
+void bdcsvd_preallocate()
+{
+ svd_preallocate< BDCSVD< MatrixXf > >();
+} // end bdcsvd_preallocate
+
+
+// compare the Singular values returned with Jacobi and Bdc
+template<typename MatrixType>
+void compare_bdc_jacobi(const MatrixType& a = MatrixType(), unsigned int computationOptions = 0)
+{
+ std::cout << "debut compare" << std::endl;
+ MatrixType m = MatrixType::Random(a.rows(), a.cols());
+ BDCSVD<MatrixType> bdc_svd(m);
+ JacobiSVD<MatrixType> jacobi_svd(m);
+ VERIFY_IS_APPROX(bdc_svd.singularValues(), jacobi_svd.singularValues());
+ if(computationOptions & ComputeFullU)
+ VERIFY_IS_APPROX(bdc_svd.matrixU(), jacobi_svd.matrixU());
+ if(computationOptions & ComputeThinU)
+ VERIFY_IS_APPROX(bdc_svd.matrixU(), jacobi_svd.matrixU());
+ if(computationOptions & ComputeFullV)
+ VERIFY_IS_APPROX(bdc_svd.matrixV(), jacobi_svd.matrixV());
+ if(computationOptions & ComputeThinV)
+ VERIFY_IS_APPROX(bdc_svd.matrixV(), jacobi_svd.matrixV());
+ std::cout << "fin compare" << std::endl;
+} // end template compare_bdc_jacobi
+
+
+// call the tests
+void test_bdcsvd()
+{
+ // test of Dynamic defined Matrix (42, 42) of float
+ CALL_SUBTEST_11(( bdcsvd_verify_assert<Matrix<float,Dynamic,Dynamic> >
+ (Matrix<float,Dynamic,Dynamic>(42,42)) ));
+ CALL_SUBTEST_11(( compare_bdc_jacobi<Matrix<float,Dynamic,Dynamic> >
+ (Matrix<float,Dynamic,Dynamic>(42,42), 0) ));
+ CALL_SUBTEST_11(( bdcsvd<Matrix<float,Dynamic,Dynamic> >
+ (Matrix<float,Dynamic,Dynamic>(42,42)) ));
+
+ // test of Dynamic defined Matrix (50, 50) of double
+ CALL_SUBTEST_13(( bdcsvd_verify_assert<Matrix<double,Dynamic,Dynamic> >
+ (Matrix<double,Dynamic,Dynamic>(50,50)) ));
+ CALL_SUBTEST_13(( compare_bdc_jacobi<Matrix<double,Dynamic,Dynamic> >
+ (Matrix<double,Dynamic,Dynamic>(50,50), 0) ));
+ CALL_SUBTEST_13(( bdcsvd<Matrix<double,Dynamic,Dynamic> >
+ (Matrix<double,Dynamic,Dynamic>(50, 50)) ));
+
+ // test of Dynamic defined Matrix (22, 22) of complex double
+ CALL_SUBTEST_14(( bdcsvd_verify_assert<Matrix<std::complex<double>,Dynamic,Dynamic> >
+ (Matrix<std::complex<double>,Dynamic,Dynamic>(22,22)) ));
+ CALL_SUBTEST_14(( compare_bdc_jacobi<Matrix<std::complex<double>,Dynamic,Dynamic> >
+ (Matrix<std::complex<double>, Dynamic, Dynamic> (22,22), 0) ));
+ CALL_SUBTEST_14(( bdcsvd<Matrix<std::complex<double>,Dynamic,Dynamic> >
+ (Matrix<std::complex<double>,Dynamic,Dynamic>(22, 22)) ));
+
+ // test of Dynamic defined Matrix (10, 10) of int
+ //CALL_SUBTEST_15(( bdcsvd_verify_assert<Matrix<int,Dynamic,Dynamic> >
+ // (Matrix<int,Dynamic,Dynamic>(10,10)) ));
+ //CALL_SUBTEST_15(( compare_bdc_jacobi<Matrix<int,Dynamic,Dynamic> >
+ // (Matrix<int,Dynamic,Dynamic>(10,10), 0) ));
+ //CALL_SUBTEST_15(( bdcsvd<Matrix<int,Dynamic,Dynamic> >
+ // (Matrix<int,Dynamic,Dynamic>(10, 10)) ));
+
+
+ // test of Dynamic defined Matrix (8, 6) of double
+
+ CALL_SUBTEST_16(( bdcsvd_verify_assert<Matrix<double,Dynamic,Dynamic> >
+ (Matrix<double,Dynamic,Dynamic>(8,6)) ));
+ CALL_SUBTEST_16(( compare_bdc_jacobi<Matrix<double,Dynamic,Dynamic> >
+ (Matrix<double,Dynamic,Dynamic>(8, 6), 0) ));
+ CALL_SUBTEST_16(( bdcsvd<Matrix<double,Dynamic,Dynamic> >
+ (Matrix<double,Dynamic,Dynamic>(8, 6)) ));
+
+
+
+ // test of Dynamic defined Matrix (36, 12) of float
+ CALL_SUBTEST_17(( compare_bdc_jacobi<Matrix<float,Dynamic,Dynamic> >
+ (Matrix<float,Dynamic,Dynamic>(36, 12), 0) ));
+ CALL_SUBTEST_17(( bdcsvd<Matrix<float,Dynamic,Dynamic> >
+ (Matrix<float,Dynamic,Dynamic>(36, 12)) ));
+
+ // test of Dynamic defined Matrix (5, 8) of double
+ CALL_SUBTEST_18(( compare_bdc_jacobi<Matrix<double,Dynamic,Dynamic> >
+ (Matrix<double,Dynamic,Dynamic>(5, 8), 0) ));
+ CALL_SUBTEST_18(( bdcsvd<Matrix<double,Dynamic,Dynamic> >
+ (Matrix<double,Dynamic,Dynamic>(5, 8)) ));
+
+
+ // non regression tests
+ CALL_SUBTEST_3(( bdcsvd_verify_assert(Matrix3f()) ));
+ CALL_SUBTEST_4(( bdcsvd_verify_assert(Matrix4d()) ));
+ CALL_SUBTEST_7(( bdcsvd_verify_assert(MatrixXf(10,12)) ));
+ CALL_SUBTEST_8(( bdcsvd_verify_assert(MatrixXcd(7,5)) ));
+
+ // SUBTESTS 1 and 2 on specifics matrix
+ for(int i = 0; i < g_repeat; i++) {
+ Matrix2cd m;
+ m << 0, 1,
+ 0, 1;
+ CALL_SUBTEST_1(( bdcsvd(m, false) ));
+ m << 1, 0,
+ 1, 0;
+ CALL_SUBTEST_1(( bdcsvd(m, false) ));
+
+ Matrix2d n;
+ n << 0, 0,
+ 0, 0;
+ CALL_SUBTEST_2(( bdcsvd(n, false) ));
+ n << 0, 0,
+ 0, 1;
+ CALL_SUBTEST_2(( bdcsvd(n, false) ));
+
+ // Statics matrix don't work with BDSVD yet
+ // bdc algo on a random 3x3 float matrix
+ // CALL_SUBTEST_3(( bdcsvd<Matrix3f>() ));
+ // bdc algo on a random 4x4 double matrix
+ // CALL_SUBTEST_4(( bdcsvd<Matrix4d>() ));
+ // bdc algo on a random 3x5 float matrix
+ // CALL_SUBTEST_5(( bdcsvd<Matrix<float,3,5> >() ));
+
+ int r = internal::random<int>(1, 30),
+ c = internal::random<int>(1, 30);
+ CALL_SUBTEST_7(( bdcsvd<MatrixXf>(MatrixXf(r,c)) ));
+ CALL_SUBTEST_8(( bdcsvd<MatrixXcd>(MatrixXcd(r,c)) ));
+ (void) r;
+ (void) c;
+
+ // Test on inf/nan matrix
+ CALL_SUBTEST_7( bdcsvd_inf_nan<MatrixXf>() );
+ }
+
+ CALL_SUBTEST_7(( bdcsvd<MatrixXf>(MatrixXf(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2))) ));
+ CALL_SUBTEST_8(( bdcsvd<MatrixXcd>(MatrixXcd(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/3), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/3))) ));
+
+ // Test problem size constructors
+ CALL_SUBTEST_7( BDCSVD<MatrixXf>(10,10) );
+
+} // end test_bdcsvd
diff --git a/unsupported/test/jacobisvd.cpp b/unsupported/test/jacobisvd.cpp
new file mode 100644
index 000000000..b4e884eee
--- /dev/null
+++ b/unsupported/test/jacobisvd.cpp
@@ -0,0 +1,198 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include "svd_common.h"
+
+template<typename MatrixType, int QRPreconditioner>
+void jacobisvd_check_full(const MatrixType& m, const JacobiSVD<MatrixType, QRPreconditioner>& svd)
+{
+ svd_check_full<MatrixType, JacobiSVD<MatrixType, QRPreconditioner > >(m, svd);
+}
+
+template<typename MatrixType, int QRPreconditioner>
+void jacobisvd_compare_to_full(const MatrixType& m,
+ unsigned int computationOptions,
+ const JacobiSVD<MatrixType, QRPreconditioner>& referenceSvd)
+{
+ svd_compare_to_full<MatrixType, JacobiSVD<MatrixType, QRPreconditioner> >(m, computationOptions, referenceSvd);
+}
+
+
+template<typename MatrixType, int QRPreconditioner>
+void jacobisvd_solve(const MatrixType& m, unsigned int computationOptions)
+{
+ svd_solve< MatrixType, JacobiSVD< MatrixType, QRPreconditioner > >(m, computationOptions);
+}
+
+
+
+template<typename MatrixType, int QRPreconditioner>
+void jacobisvd_test_all_computation_options(const MatrixType& m)
+{
+
+ if (QRPreconditioner == NoQRPreconditioner && m.rows() != m.cols())
+ return;
+
+ JacobiSVD< MatrixType, QRPreconditioner > fullSvd(m, ComputeFullU|ComputeFullV);
+ svd_test_computation_options_1< MatrixType, JacobiSVD< MatrixType, QRPreconditioner > >(m, fullSvd);
+
+ if(QRPreconditioner == FullPivHouseholderQRPreconditioner)
+ return;
+ svd_test_computation_options_2< MatrixType, JacobiSVD< MatrixType, QRPreconditioner > >(m, fullSvd);
+
+}
+
+template<typename MatrixType>
+void jacobisvd(const MatrixType& a = MatrixType(), bool pickrandom = true)
+{
+ MatrixType m = pickrandom ? MatrixType::Random(a.rows(), a.cols()) : a;
+
+ jacobisvd_test_all_computation_options<MatrixType, FullPivHouseholderQRPreconditioner>(m);
+ jacobisvd_test_all_computation_options<MatrixType, ColPivHouseholderQRPreconditioner>(m);
+ jacobisvd_test_all_computation_options<MatrixType, HouseholderQRPreconditioner>(m);
+ jacobisvd_test_all_computation_options<MatrixType, NoQRPreconditioner>(m);
+}
+
+
+template<typename MatrixType>
+void jacobisvd_verify_assert(const MatrixType& m)
+{
+
+ svd_verify_assert<MatrixType, JacobiSVD< MatrixType > >(m);
+
+ typedef typename MatrixType::Index Index;
+ Index rows = m.rows();
+ Index cols = m.cols();
+
+ enum {
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
+ ColsAtCompileTime = MatrixType::ColsAtCompileTime
+ };
+
+ MatrixType a = MatrixType::Zero(rows, cols);
+ a.setZero();
+
+ if (ColsAtCompileTime == Dynamic)
+ {
+ JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner> svd_fullqr;
+ VERIFY_RAISES_ASSERT(svd_fullqr.compute(a, ComputeFullU|ComputeThinV))
+ VERIFY_RAISES_ASSERT(svd_fullqr.compute(a, ComputeThinU|ComputeThinV))
+ VERIFY_RAISES_ASSERT(svd_fullqr.compute(a, ComputeThinU|ComputeFullV))
+ }
+}
+
+template<typename MatrixType>
+void jacobisvd_method()
+{
+ enum { Size = MatrixType::RowsAtCompileTime };
+ typedef typename MatrixType::RealScalar RealScalar;
+ typedef Matrix<RealScalar, Size, 1> RealVecType;
+ MatrixType m = MatrixType::Identity();
+ VERIFY_IS_APPROX(m.jacobiSvd().singularValues(), RealVecType::Ones());
+ VERIFY_RAISES_ASSERT(m.jacobiSvd().matrixU());
+ VERIFY_RAISES_ASSERT(m.jacobiSvd().matrixV());
+ VERIFY_IS_APPROX(m.jacobiSvd(ComputeFullU|ComputeFullV).solve(m), m);
+}
+
+
+
+template<typename MatrixType>
+void jacobisvd_inf_nan()
+{
+ svd_inf_nan<MatrixType, JacobiSVD< MatrixType > >();
+}
+
+
+// Regression test for bug 286: JacobiSVD loops indefinitely with some
+// matrices containing denormal numbers.
+void jacobisvd_bug286()
+{
+#if defined __INTEL_COMPILER
+// shut up warning #239: floating point underflow
+#pragma warning push
+#pragma warning disable 239
+#endif
+ Matrix2d M;
+ M << -7.90884e-313, -4.94e-324,
+ 0, 5.60844e-313;
+#if defined __INTEL_COMPILER
+#pragma warning pop
+#endif
+ JacobiSVD<Matrix2d> svd;
+ svd.compute(M); // just check we don't loop indefinitely
+}
+
+
+void jacobisvd_preallocate()
+{
+ svd_preallocate< JacobiSVD <MatrixXf> >();
+}
+
+void test_jacobisvd()
+{
+ CALL_SUBTEST_11(( jacobisvd<Matrix<double,Dynamic,Dynamic> >
+ (Matrix<double,Dynamic,Dynamic>(16, 6)) ));
+
+ CALL_SUBTEST_3(( jacobisvd_verify_assert(Matrix3f()) ));
+ CALL_SUBTEST_4(( jacobisvd_verify_assert(Matrix4d()) ));
+ CALL_SUBTEST_7(( jacobisvd_verify_assert(MatrixXf(10,12)) ));
+ CALL_SUBTEST_8(( jacobisvd_verify_assert(MatrixXcd(7,5)) ));
+
+ for(int i = 0; i < g_repeat; i++) {
+ Matrix2cd m;
+ m << 0, 1,
+ 0, 1;
+ CALL_SUBTEST_1(( jacobisvd(m, false) ));
+ m << 1, 0,
+ 1, 0;
+ CALL_SUBTEST_1(( jacobisvd(m, false) ));
+
+ Matrix2d n;
+ n << 0, 0,
+ 0, 0;
+ CALL_SUBTEST_2(( jacobisvd(n, false) ));
+ n << 0, 0,
+ 0, 1;
+ CALL_SUBTEST_2(( jacobisvd(n, false) ));
+
+ CALL_SUBTEST_3(( jacobisvd<Matrix3f>() ));
+ CALL_SUBTEST_4(( jacobisvd<Matrix4d>() ));
+ CALL_SUBTEST_5(( jacobisvd<Matrix<float,3,5> >() ));
+ CALL_SUBTEST_6(( jacobisvd<Matrix<double,Dynamic,2> >(Matrix<double,Dynamic,2>(10,2)) ));
+
+ int r = internal::random<int>(1, 30),
+ c = internal::random<int>(1, 30);
+ CALL_SUBTEST_7(( jacobisvd<MatrixXf>(MatrixXf(r,c)) ));
+ CALL_SUBTEST_8(( jacobisvd<MatrixXcd>(MatrixXcd(r,c)) ));
+ (void) r;
+ (void) c;
+
+ // Test on inf/nan matrix
+ CALL_SUBTEST_7( jacobisvd_inf_nan<MatrixXf>() );
+ }
+
+ CALL_SUBTEST_7(( jacobisvd<MatrixXf>(MatrixXf(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2))) ));
+ CALL_SUBTEST_8(( jacobisvd<MatrixXcd>(MatrixXcd(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/3), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/3))) ));
+
+
+ // test matrixbase method
+ CALL_SUBTEST_1(( jacobisvd_method<Matrix2cd>() ));
+ CALL_SUBTEST_3(( jacobisvd_method<Matrix3f>() ));
+
+
+ // Test problem size constructors
+ CALL_SUBTEST_7( JacobiSVD<MatrixXf>(10,10) );
+
+ // Check that preallocation avoids subsequent mallocs
+ CALL_SUBTEST_9( jacobisvd_preallocate() );
+
+ // Regression check for bug 286
+ CALL_SUBTEST_2( jacobisvd_bug286() );
+}
diff --git a/unsupported/test/kronecker_product.cpp b/unsupported/test/kronecker_product.cpp
index 108bf6fde..8ddc6ec28 100644
--- a/unsupported/test/kronecker_product.cpp
+++ b/unsupported/test/kronecker_product.cpp
@@ -112,8 +112,8 @@ void test_kronecker_product()
CALL_SUBTEST(check_kronecker_product(DM_fix_ab));
- for(unsigned int i=0;i<DM_fix_ab.rows();++i)
- for(unsigned int j=0;j<DM_fix_ab.cols();++j)
+ for(int i=0;i<DM_fix_ab.rows();++i)
+ for(int j=0;j<DM_fix_ab.cols();++j)
VERIFY_IS_APPROX(kroneckerProduct(DM_a,DM_b).coeff(i,j), DM_fix_ab(i,j));
// test kroneckerProduct(DM,DM,DM_block)
diff --git a/unsupported/test/matrix_power.cpp b/unsupported/test/matrix_power.cpp
index 2763b97cc..b9d513b45 100644
--- a/unsupported/test/matrix_power.cpp
+++ b/unsupported/test/matrix_power.cpp
@@ -109,64 +109,11 @@ void testExponentLaws(const MatrixType& m, double tol)
}
}
-template<typename MatrixType, typename VectorType>
-void testProduct(const MatrixType& m, const VectorType& v, double tol)
-{
- typedef typename MatrixType::RealScalar RealScalar;
- MatrixType m1;
- VectorType v1, v2, v3;
- RealScalar p;
-
- for (int i=0; i < g_repeat; ++i) {
- generateTestMatrix<MatrixType>::run(m1, m.rows());
- MatrixPower<MatrixType> mpow(m1);
-
- v1 = VectorType::Random(v.rows(), v.cols());
- p = internal::random<RealScalar>();
-
- v2.noalias() = mpow(p) * v1;
- v3.noalias() = mpow(p).eval() * v1;
- std::cout << "testProduct: error powerm = " << relerr(v2, v3) << '\n';
- VERIFY(v2.isApprox(v3, static_cast<RealScalar>(tol)));
- }
-}
-
-template<typename MatrixType, typename VectorType>
-void testTriangularProduct(const MatrixType& m, const VectorType& v, double tol)
-{
- typedef typename MatrixType::RealScalar RealScalar;
- MatrixType m1;
- VectorType v1, v2, v3;
- RealScalar p;
-
- for (int i=0; i < g_repeat; ++i) {
- generateTriangularMatrix<MatrixType>::run(m1, m.rows());
- MatrixPowerTriangular<MatrixType> mpow(m1);
-
- v1 = VectorType::Random(v.rows(), v.cols());
- p = internal::random<RealScalar>();
-
- v2.noalias() = mpow(p) * v1;
- v3.noalias() = mpow(p).eval() * v1;
- std::cout << "testTriangularProduct: error powerm = " << relerr(v2, v3) << '\n';
- VERIFY(v2.isApprox(v3, static_cast<RealScalar>(tol)));
- }
-}
-
-template<typename MatrixType, typename VectorType>
-void testMatrixVector(const MatrixType& m, const VectorType& v, double tol)
-{
- testExponentLaws(m,tol);
- testProduct(m,v,tol);
- testTriangularProduct(m,v,tol);
-}
-
+typedef Matrix<double,3,3,RowMajor> Matrix3dRowMajor;
+typedef Matrix<long double,Dynamic,Dynamic> MatrixXe;
+
void test_matrix_power()
{
- typedef Matrix<double,3,3,RowMajor> Matrix3dRowMajor;
- typedef Matrix<long double,Dynamic,Dynamic> MatrixXe;
- typedef Matrix<long double,Dynamic,1> VectorXe;
-
CALL_SUBTEST_2(test2dRotation<double>(1e-13));
CALL_SUBTEST_1(test2dRotation<float>(2e-5)); // was 1e-5, relaxed for clang 2.8 / linux / x86-64
CALL_SUBTEST_9(test2dRotation<long double>(1e-13));
@@ -174,13 +121,13 @@ void test_matrix_power()
CALL_SUBTEST_1(test2dHyperbolicRotation<float>(1e-5));
CALL_SUBTEST_9(test2dHyperbolicRotation<long double>(1e-14));
- CALL_SUBTEST_2(testMatrixVector(Matrix2d(), Vector2d(), 1e-13));
- CALL_SUBTEST_7(testMatrixVector(Matrix3dRowMajor(), MatrixXd(3,5), 1e-13));
- CALL_SUBTEST_3(testMatrixVector(Matrix4cd(), Vector4cd(), 1e-13));
- CALL_SUBTEST_4(testMatrixVector(MatrixXd(8,8), VectorXd(8), 2e-12));
- CALL_SUBTEST_1(testMatrixVector(Matrix2f(), Vector2f(), 1e-4));
- CALL_SUBTEST_5(testMatrixVector(Matrix3cf(), Vector3cf(), 1e-4));
- CALL_SUBTEST_8(testMatrixVector(Matrix4f(), Vector4f(), 1e-4));
- CALL_SUBTEST_6(testMatrixVector(MatrixXf(8,8), VectorXf(8), 1e-3));
- CALL_SUBTEST_9(testMatrixVector(MatrixXe(7,7), VectorXe(7), 1e-13));
+ CALL_SUBTEST_2(testExponentLaws(Matrix2d(), 1e-13));
+ CALL_SUBTEST_7(testExponentLaws(Matrix3dRowMajor(), 1e-13));
+ CALL_SUBTEST_3(testExponentLaws(Matrix4cd(), 1e-13));
+ CALL_SUBTEST_4(testExponentLaws(MatrixXd(8,8), 2e-12));
+ CALL_SUBTEST_1(testExponentLaws(Matrix2f(), 1e-4));
+ CALL_SUBTEST_5(testExponentLaws(Matrix3cf(), 1e-4));
+ CALL_SUBTEST_8(testExponentLaws(Matrix4f(), 1e-4));
+ CALL_SUBTEST_6(testExponentLaws(MatrixXf(2,2), 1e-3)); // see bug 614
+ CALL_SUBTEST_9(testExponentLaws(MatrixXe(7,7), 1e-13));
}
diff --git a/unsupported/test/polynomialsolver.cpp b/unsupported/test/polynomialsolver.cpp
index c31104f14..13f92169e 100644
--- a/unsupported/test/polynomialsolver.cpp
+++ b/unsupported/test/polynomialsolver.cpp
@@ -106,10 +106,7 @@ void evalSolverSugarFunction( const POLYNOMIAL& pols, const ROOTS& roots, const
typedef typename POLYNOMIAL::Scalar Scalar;
typedef typename REAL_ROOTS::Scalar Real;
-
typedef PolynomialSolver<Scalar, Deg > PolynomialSolverType;
- typedef typename PolynomialSolverType::RootsType RootsType;
- typedef Matrix<Scalar,Deg,1> EvalRootsType;
//Test realRoots
std::vector< Real > calc_realRoots;
diff --git a/unsupported/test/sparse_extra.cpp b/unsupported/test/sparse_extra.cpp
index 5dc333424..1ee791b0f 100644
--- a/unsupported/test/sparse_extra.cpp
+++ b/unsupported/test/sparse_extra.cpp
@@ -17,7 +17,6 @@
template<typename SetterType,typename DenseType, typename Scalar, int Options>
bool test_random_setter(SparseMatrix<Scalar,Options>& sm, const DenseType& ref, const std::vector<Vector2i>& nonzeroCoords)
{
- typedef SparseMatrix<Scalar,Options> SparseType;
{
sm.setZero();
SetterType w(sm);
diff --git a/unsupported/test/svd_common.h b/unsupported/test/svd_common.h
new file mode 100644
index 000000000..b40c23a2b
--- /dev/null
+++ b/unsupported/test/svd_common.h
@@ -0,0 +1,261 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// Copyright (C) 2013 Gauthier Brun <brun.gauthier@gmail.com>
+// Copyright (C) 2013 Nicolas Carre <nicolas.carre@ensimag.fr>
+// Copyright (C) 2013 Jean Ceccato <jean.ceccato@ensimag.fr>
+// Copyright (C) 2013 Pierre Zoppitelli <pierre.zoppitelli@ensimag.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+// discard stack allocation as that too bypasses malloc
+#define EIGEN_STACK_ALLOCATION_LIMIT 0
+#define EIGEN_RUNTIME_NO_MALLOC
+
+#include "main.h"
+#include <unsupported/Eigen/SVD>
+#include <Eigen/LU>
+
+
+// check if "svd" is the good image of "m"
+template<typename MatrixType, typename SVD>
+void svd_check_full(const MatrixType& m, const SVD& svd)
+{
+ typedef typename MatrixType::Index Index;
+ Index rows = m.rows();
+ Index cols = m.cols();
+ enum {
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
+ ColsAtCompileTime = MatrixType::ColsAtCompileTime
+ };
+
+ typedef typename MatrixType::Scalar Scalar;
+ typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime> MatrixUType;
+ typedef Matrix<Scalar, ColsAtCompileTime, ColsAtCompileTime> MatrixVType;
+
+
+ MatrixType sigma = MatrixType::Zero(rows, cols);
+ sigma.diagonal() = svd.singularValues().template cast<Scalar>();
+ MatrixUType u = svd.matrixU();
+ MatrixVType v = svd.matrixV();
+ VERIFY_IS_APPROX(m, u * sigma * v.adjoint());
+ VERIFY_IS_UNITARY(u);
+ VERIFY_IS_UNITARY(v);
+} // end svd_check_full
+
+
+
+// Compare to a reference value
+template<typename MatrixType, typename SVD>
+void svd_compare_to_full(const MatrixType& m,
+ unsigned int computationOptions,
+ const SVD& referenceSvd)
+{
+ typedef typename MatrixType::Index Index;
+ Index rows = m.rows();
+ Index cols = m.cols();
+ Index diagSize = (std::min)(rows, cols);
+
+ SVD svd(m, computationOptions);
+
+ VERIFY_IS_APPROX(svd.singularValues(), referenceSvd.singularValues());
+ if(computationOptions & ComputeFullU)
+ VERIFY_IS_APPROX(svd.matrixU(), referenceSvd.matrixU());
+ if(computationOptions & ComputeThinU)
+ VERIFY_IS_APPROX(svd.matrixU(), referenceSvd.matrixU().leftCols(diagSize));
+ if(computationOptions & ComputeFullV)
+ VERIFY_IS_APPROX(svd.matrixV(), referenceSvd.matrixV());
+ if(computationOptions & ComputeThinV)
+ VERIFY_IS_APPROX(svd.matrixV(), referenceSvd.matrixV().leftCols(diagSize));
+} // end svd_compare_to_full
+
+
+
+template<typename MatrixType, typename SVD>
+void svd_solve(const MatrixType& m, unsigned int computationOptions)
+{
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::Index Index;
+ Index rows = m.rows();
+ Index cols = m.cols();
+
+ enum {
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
+ ColsAtCompileTime = MatrixType::ColsAtCompileTime
+ };
+
+ typedef Matrix<Scalar, RowsAtCompileTime, Dynamic> RhsType;
+ typedef Matrix<Scalar, ColsAtCompileTime, Dynamic> SolutionType;
+
+ RhsType rhs = RhsType::Random(rows, internal::random<Index>(1, cols));
+ SVD svd(m, computationOptions);
+ SolutionType x = svd.solve(rhs);
+ // evaluate normal equation which works also for least-squares solutions
+ VERIFY_IS_APPROX(m.adjoint()*m*x,m.adjoint()*rhs);
+} // end svd_solve
+
+
+// test computations options
+// 2 functions because Jacobisvd can return before the second function
+template<typename MatrixType, typename SVD>
+void svd_test_computation_options_1(const MatrixType& m, const SVD& fullSvd)
+{
+ svd_check_full< MatrixType, SVD >(m, fullSvd);
+ svd_solve< MatrixType, SVD >(m, ComputeFullU | ComputeFullV);
+}
+
+
+template<typename MatrixType, typename SVD>
+void svd_test_computation_options_2(const MatrixType& m, const SVD& fullSvd)
+{
+ svd_compare_to_full< MatrixType, SVD >(m, ComputeFullU, fullSvd);
+ svd_compare_to_full< MatrixType, SVD >(m, ComputeFullV, fullSvd);
+ svd_compare_to_full< MatrixType, SVD >(m, 0, fullSvd);
+
+ if (MatrixType::ColsAtCompileTime == Dynamic) {
+ // thin U/V are only available with dynamic number of columns
+
+ svd_compare_to_full< MatrixType, SVD >(m, ComputeFullU|ComputeThinV, fullSvd);
+ svd_compare_to_full< MatrixType, SVD >(m, ComputeThinV, fullSvd);
+ svd_compare_to_full< MatrixType, SVD >(m, ComputeThinU|ComputeFullV, fullSvd);
+ svd_compare_to_full< MatrixType, SVD >(m, ComputeThinU , fullSvd);
+ svd_compare_to_full< MatrixType, SVD >(m, ComputeThinU|ComputeThinV, fullSvd);
+ svd_solve<MatrixType, SVD>(m, ComputeFullU | ComputeThinV);
+ svd_solve<MatrixType, SVD>(m, ComputeThinU | ComputeFullV);
+ svd_solve<MatrixType, SVD>(m, ComputeThinU | ComputeThinV);
+
+ typedef typename MatrixType::Index Index;
+ Index diagSize = (std::min)(m.rows(), m.cols());
+ SVD svd(m, ComputeThinU | ComputeThinV);
+ VERIFY_IS_APPROX(m, svd.matrixU().leftCols(diagSize) * svd.singularValues().asDiagonal() * svd.matrixV().leftCols(diagSize).adjoint());
+ }
+}
+
+template<typename MatrixType, typename SVD>
+void svd_verify_assert(const MatrixType& m)
+{
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::Index Index;
+ Index rows = m.rows();
+ Index cols = m.cols();
+
+ enum {
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
+ ColsAtCompileTime = MatrixType::ColsAtCompileTime
+ };
+
+ typedef Matrix<Scalar, RowsAtCompileTime, 1> RhsType;
+ RhsType rhs(rows);
+ SVD svd;
+ VERIFY_RAISES_ASSERT(svd.matrixU())
+ VERIFY_RAISES_ASSERT(svd.singularValues())
+ VERIFY_RAISES_ASSERT(svd.matrixV())
+ VERIFY_RAISES_ASSERT(svd.solve(rhs))
+ MatrixType a = MatrixType::Zero(rows, cols);
+ a.setZero();
+ svd.compute(a, 0);
+ VERIFY_RAISES_ASSERT(svd.matrixU())
+ VERIFY_RAISES_ASSERT(svd.matrixV())
+ svd.singularValues();
+ VERIFY_RAISES_ASSERT(svd.solve(rhs))
+
+ if (ColsAtCompileTime == Dynamic)
+ {
+ svd.compute(a, ComputeThinU);
+ svd.matrixU();
+ VERIFY_RAISES_ASSERT(svd.matrixV())
+ VERIFY_RAISES_ASSERT(svd.solve(rhs))
+ svd.compute(a, ComputeThinV);
+ svd.matrixV();
+ VERIFY_RAISES_ASSERT(svd.matrixU())
+ VERIFY_RAISES_ASSERT(svd.solve(rhs))
+ }
+ else
+ {
+ VERIFY_RAISES_ASSERT(svd.compute(a, ComputeThinU))
+ VERIFY_RAISES_ASSERT(svd.compute(a, ComputeThinV))
+ }
+}
+
+// work around stupid msvc error when constructing at compile time an expression that involves
+// a division by zero, even if the numeric type has floating point
+template<typename Scalar>
+EIGEN_DONT_INLINE Scalar zero() { return Scalar(0); }
+
+// workaround aggressive optimization in ICC
+template<typename T> EIGEN_DONT_INLINE T sub(T a, T b) { return a - b; }
+
+
+template<typename MatrixType, typename SVD>
+void svd_inf_nan()
+{
+ // all this function does is verify we don't iterate infinitely on nan/inf values
+
+ SVD svd;
+ typedef typename MatrixType::Scalar Scalar;
+ Scalar some_inf = Scalar(1) / zero<Scalar>();
+ VERIFY(sub(some_inf, some_inf) != sub(some_inf, some_inf));
+ svd.compute(MatrixType::Constant(10,10,some_inf), ComputeFullU | ComputeFullV);
+
+ Scalar some_nan = zero<Scalar> () / zero<Scalar> ();
+ VERIFY(some_nan != some_nan);
+ svd.compute(MatrixType::Constant(10,10,some_nan), ComputeFullU | ComputeFullV);
+
+ MatrixType m = MatrixType::Zero(10,10);
+ m(internal::random<int>(0,9), internal::random<int>(0,9)) = some_inf;
+ svd.compute(m, ComputeFullU | ComputeFullV);
+
+ m = MatrixType::Zero(10,10);
+ m(internal::random<int>(0,9), internal::random<int>(0,9)) = some_nan;
+ svd.compute(m, ComputeFullU | ComputeFullV);
+}
+
+
+template<typename SVD>
+void svd_preallocate()
+{
+ Vector3f v(3.f, 2.f, 1.f);
+ MatrixXf m = v.asDiagonal();
+
+ internal::set_is_malloc_allowed(false);
+ VERIFY_RAISES_ASSERT(VectorXf v(10);)
+ SVD svd;
+ internal::set_is_malloc_allowed(true);
+ svd.compute(m);
+ VERIFY_IS_APPROX(svd.singularValues(), v);
+
+ SVD svd2(3,3);
+ internal::set_is_malloc_allowed(false);
+ svd2.compute(m);
+ internal::set_is_malloc_allowed(true);
+ VERIFY_IS_APPROX(svd2.singularValues(), v);
+ VERIFY_RAISES_ASSERT(svd2.matrixU());
+ VERIFY_RAISES_ASSERT(svd2.matrixV());
+ svd2.compute(m, ComputeFullU | ComputeFullV);
+ VERIFY_IS_APPROX(svd2.matrixU(), Matrix3f::Identity());
+ VERIFY_IS_APPROX(svd2.matrixV(), Matrix3f::Identity());
+ internal::set_is_malloc_allowed(false);
+ svd2.compute(m);
+ internal::set_is_malloc_allowed(true);
+
+ SVD svd3(3,3,ComputeFullU|ComputeFullV);
+ internal::set_is_malloc_allowed(false);
+ svd2.compute(m);
+ internal::set_is_malloc_allowed(true);
+ VERIFY_IS_APPROX(svd2.singularValues(), v);
+ VERIFY_IS_APPROX(svd2.matrixU(), Matrix3f::Identity());
+ VERIFY_IS_APPROX(svd2.matrixV(), Matrix3f::Identity());
+ internal::set_is_malloc_allowed(false);
+ svd2.compute(m, ComputeFullU|ComputeFullV);
+ internal::set_is_malloc_allowed(true);
+}
+
+
+
+
+