mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Compare commits
191 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56f9b810ab | ||
|
|
12815309a6 | ||
|
|
207747a518 | ||
|
|
5ecfdf2c00 | ||
|
|
e788869cf5 | ||
|
|
9df04bcede | ||
|
|
c31606c88a | ||
|
|
2872d964f4 | ||
|
|
2c288b3949 | ||
|
|
bbaef8ebba | ||
|
|
bd689ccc28 | ||
|
|
e3774e93b7 | ||
|
|
db8e88c936 | ||
|
|
cfd7f9b84a | ||
|
|
3e094af410 | ||
|
|
adeaa657eb | ||
|
|
f2aba7a768 | ||
|
|
d02e329218 | ||
|
|
c76990664b | ||
|
|
ee244d54f4 | ||
|
|
4bb0fff151 | ||
|
|
9a16519d62 | ||
|
|
06a5bcecf6 | ||
|
|
7ee378d89d | ||
|
|
61c3f55362 | ||
|
|
5431473d67 | ||
|
|
444c09e313 | ||
|
|
84f52ad317 | ||
|
|
6d1f5dbaae | ||
|
|
71cccf0ed8 | ||
|
|
5a4519d2b4 | ||
|
|
f850550e3e | ||
|
|
0567cf96cc | ||
|
|
4f28ccdd0e | ||
|
|
9b833aff42 | ||
|
|
3edd4681f2 | ||
|
|
d0142e963b | ||
|
|
8ba7ccf16a | ||
|
|
cc03c9d683 | ||
|
|
4f14b3fa72 | ||
|
|
9b9177f1ce | ||
|
|
7d8823c8b7 | ||
|
|
edba612f68 | ||
|
|
4020d4286f | ||
|
|
3cda1deb52 | ||
|
|
eaf92ef48c | ||
|
|
155fa0ca83 | ||
|
|
4e458d309c | ||
|
|
419b5cff44 | ||
|
|
1caeb814f0 | ||
|
|
f8e325356a | ||
|
|
65cc51288a | ||
|
|
22820e950e | ||
|
|
99bef0957b | ||
|
|
9f035c876a | ||
|
|
fc27cbd914 | ||
|
|
a915f0292e | ||
|
|
4cf742525f | ||
|
|
487d94f495 | ||
|
|
74beb218d2 | ||
|
|
ffbe04ae78 | ||
|
|
95f8a738ea | ||
|
|
7b6e94fb58 | ||
|
|
b9543ce237 | ||
|
|
b9fc9d8f32 | ||
|
|
4cc9377941 | ||
|
|
ee8a28fb85 | ||
|
|
1330ca611b | ||
|
|
c21a04bcf9 | ||
|
|
c695cbf0fa | ||
|
|
8bbde351e7 | ||
|
|
d1d7a1ade9 | ||
|
|
fab0235369 | ||
|
|
bea4a67c92 | ||
|
|
260a923334 | ||
|
|
3ed919e0ed | ||
|
|
dd964ec08c | ||
|
|
620e4277bc | ||
|
|
8cc9b12589 | ||
|
|
cf5c5ed725 | ||
|
|
7adfca5af2 | ||
|
|
c0cad44da6 | ||
|
|
8105b5ed3f | ||
|
|
ba79e39c5c | ||
|
|
eef8d98139 | ||
|
|
4e6d746514 | ||
|
|
e37ff98bbb | ||
|
|
05da15bf40 | ||
|
|
33788b97dd | ||
|
|
79bd6fa5ee | ||
|
|
a8494787f4 | ||
|
|
437e26d000 | ||
|
|
55365566b2 | ||
|
|
9f11f80db1 | ||
|
|
5f178e54e9 | ||
|
|
d5fa5001a7 | ||
|
|
3352b8d873 | ||
|
|
d541765e85 | ||
|
|
f75419c711 | ||
|
|
f3a029e957 | ||
|
|
1b92d2ca33 | ||
|
|
f6c1841316 | ||
|
|
65c59307e2 | ||
|
|
62670c83a0 | ||
|
|
827843bbbd | ||
|
|
76f4820560 | ||
|
|
f0efe60924 | ||
|
|
92eb807c30 | ||
|
|
7742eacfeb | ||
|
|
f3af423c70 | ||
|
|
1bf18bd57f | ||
|
|
9266f65318 | ||
|
|
4cd8245c96 | ||
|
|
b3fff170a0 | ||
|
|
18e476107e | ||
|
|
ca67c60150 | ||
|
|
05c9be65ce | ||
|
|
a4a575e2a3 | ||
|
|
26c35b95c7 | ||
|
|
0525874a03 | ||
|
|
2b6528effc | ||
|
|
47e89026d0 | ||
|
|
e8c963568c | ||
|
|
b6d3fcf6f2 | ||
|
|
e392948548 | ||
|
|
4811b4526c | ||
|
|
a69b4b092b | ||
|
|
c98fd7a6ca | ||
|
|
e04b59929e | ||
|
|
b3adc4face | ||
|
|
62e337eb01 | ||
|
|
d7cd957f10 | ||
|
|
e0566a817f | ||
|
|
8e050bd681 | ||
|
|
cf939f154f | ||
|
|
bd7511fc36 | ||
|
|
bd0474adbb | ||
|
|
9ab3811cc5 | ||
|
|
b5e5b6aa57 | ||
|
|
f7bdbf69e1 | ||
|
|
83736e9c61 | ||
|
|
122b16d841 | ||
|
|
43bb942365 | ||
|
|
fcdbfabf7a | ||
|
|
aa8b897607 | ||
|
|
46755648ec | ||
|
|
41b3c56e61 | ||
|
|
9a4caf2b0f | ||
|
|
94e20f485c | ||
|
|
d4b0c19a46 | ||
|
|
db43205dc6 | ||
|
|
9816e8532e | ||
|
|
43f4fd4d71 | ||
|
|
7450b23fbb | ||
|
|
6eaff5a098 | ||
|
|
1e38928c64 | ||
|
|
ff661a7b6f | ||
|
|
899c0c2b6c | ||
|
|
7e04d7db02 | ||
|
|
f7e52d22d4 | ||
|
|
84637ca58c | ||
|
|
d7f3cfb56e | ||
|
|
3cb6e21f80 | ||
|
|
d8f1035355 | ||
|
|
bff264283d | ||
|
|
8f44205671 | ||
|
|
d97cd746ae | ||
|
|
9b33ab62da | ||
|
|
c3a6fa03a2 | ||
|
|
0a1d9fb9ae | ||
|
|
225fd0f579 | ||
|
|
c519be2bac | ||
|
|
f350f34560 | ||
|
|
d63712163c | ||
|
|
da6219b19d | ||
|
|
22460edb49 | ||
|
|
4107b371e3 | ||
|
|
9bfeeba1c5 | ||
|
|
11a9091084 | ||
|
|
aba50d842e | ||
|
|
f29b4c435b | ||
|
|
0d5a418048 | ||
|
|
d6d638c751 | ||
|
|
6357fd68da | ||
|
|
f8addac4e1 | ||
|
|
5d1a74da0a | ||
|
|
6c68f1d787 | ||
|
|
79f93247c5 | ||
|
|
97c9e3c74f | ||
|
|
03373f41cb | ||
|
|
f82ee241ac |
@@ -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
|
||||
|
||||
@@ -107,27 +107,64 @@ endif()
|
||||
|
||||
set(EIGEN_TEST_MAX_SIZE "320" CACHE STRING "Maximal matrix/vector size, default is 320")
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -fexceptions -fno-check-new -fno-common -fstrict-aliasing")
|
||||
macro(ei_add_cxx_compiler_flag FLAG)
|
||||
string(REGEX REPLACE "-" "" SFLAG ${FLAG})
|
||||
check_cxx_compiler_flag(${FLAG} COMPILER_SUPPORT_${SFLAG})
|
||||
if(COMPILER_SUPPORT_${SFLAG})
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAG}")
|
||||
endif()
|
||||
endmacro(ei_add_cxx_compiler_flag)
|
||||
|
||||
if(NOT MSVC)
|
||||
# We assume that other compilers are partly compatible with GNUCC
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g3")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-g0 -O2")
|
||||
|
||||
check_cxx_compiler_flag("-Wno-psabi" COMPILER_SUPPORT_WNOPSABI)
|
||||
if(COMPILER_SUPPORT_WNOPSABI)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-psabi")
|
||||
# clang outputs some warnings for unknwon flags that are not caught by check_cxx_compiler_flag
|
||||
# adding -Werror turns such warnings into errors
|
||||
check_cxx_compiler_flag("-Werror" COMPILER_SUPPORT_WERROR)
|
||||
if(COMPILER_SUPPORT_WERROR)
|
||||
set(CMAKE_REQUIRED_FLAGS "-Werror")
|
||||
endif()
|
||||
|
||||
check_cxx_compiler_flag("-Wno-variadic-macros" COMPILER_SUPPORT_WNOVARIADICMACRO)
|
||||
if(COMPILER_SUPPORT_WNOVARIADICMACRO)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-variadic-macros")
|
||||
|
||||
ei_add_cxx_compiler_flag("-pedantic")
|
||||
ei_add_cxx_compiler_flag("-Wall")
|
||||
ei_add_cxx_compiler_flag("-Wextra")
|
||||
#ei_add_cxx_compiler_flag("-Weverything") # clang
|
||||
|
||||
ei_add_cxx_compiler_flag("-Wundef")
|
||||
ei_add_cxx_compiler_flag("-Wcast-align")
|
||||
ei_add_cxx_compiler_flag("-Wchar-subscripts")
|
||||
ei_add_cxx_compiler_flag("-Wnon-virtual-dtor")
|
||||
ei_add_cxx_compiler_flag("-Wunused-local-typedefs")
|
||||
ei_add_cxx_compiler_flag("-Wpointer-arith")
|
||||
ei_add_cxx_compiler_flag("-Wwrite-strings")
|
||||
ei_add_cxx_compiler_flag("-Wformat-security")
|
||||
|
||||
ei_add_cxx_compiler_flag("-Wno-psabi")
|
||||
ei_add_cxx_compiler_flag("-Wno-variadic-macros")
|
||||
ei_add_cxx_compiler_flag("-Wno-long-long")
|
||||
|
||||
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") # 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()
|
||||
ei_add_cxx_compiler_flag("-ansi")
|
||||
endif()
|
||||
|
||||
check_cxx_compiler_flag("-Wextra" COMPILER_SUPPORT_WEXTRA)
|
||||
if(COMPILER_SUPPORT_WEXTRA)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra")
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
|
||||
|
||||
set(CMAKE_REQUIRED_FLAGS "")
|
||||
|
||||
option(EIGEN_TEST_SSE2 "Enable/Disable SSE2 in tests/examples" OFF)
|
||||
if(EIGEN_TEST_SSE2)
|
||||
@@ -180,9 +217,8 @@ if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif(CMAKE_COMPILER_IS_GNUCXX)
|
||||
else(NOT MSVC)
|
||||
|
||||
if(MSVC)
|
||||
# C4127 - conditional expression is constant
|
||||
# C4714 - marked as __forceinline not inlined (I failed to deactivate it selectively)
|
||||
# We can disable this warning in the unit tests since it is clear that it occurs
|
||||
@@ -212,7 +248,7 @@ if(MSVC)
|
||||
endif(NOT CMAKE_CL_64)
|
||||
message(STATUS "Enabling SSE2 in tests/examples")
|
||||
endif(EIGEN_TEST_SSE2)
|
||||
endif(MSVC)
|
||||
endif(NOT MSVC)
|
||||
|
||||
option(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION "Disable explicit vectorization in tests/examples" OFF)
|
||||
option(EIGEN_TEST_X87 "Force using X87 instructions. Implies no vectorization." OFF)
|
||||
@@ -311,6 +347,7 @@ add_subdirectory(Eigen)
|
||||
add_subdirectory(doc EXCLUDE_FROM_ALL)
|
||||
|
||||
include(EigenConfigureTesting)
|
||||
|
||||
# fixme, not sure this line is still needed:
|
||||
enable_testing() # must be called from the root CMakeLists, see man page
|
||||
|
||||
@@ -345,6 +382,8 @@ if(NOT WIN32)
|
||||
add_subdirectory(bench/spbench EXCLUDE_FROM_ALL)
|
||||
endif(NOT WIN32)
|
||||
|
||||
configure_file(scripts/cdashtesting.cmake.in cdashtesting.cmake @ONLY)
|
||||
|
||||
ei_testing_print_summary()
|
||||
|
||||
message(STATUS "")
|
||||
|
||||
@@ -11,3 +11,7 @@ set(CTEST_DROP_METHOD "http")
|
||||
set(CTEST_DROP_SITE "manao.inria.fr")
|
||||
set(CTEST_DROP_LOCATION "/CDash/submit.php?project=Eigen")
|
||||
set(CTEST_DROP_SITE_CDASH TRUE)
|
||||
set(CTEST_PROJECT_SUBPROJECTS
|
||||
Official
|
||||
Unsupported
|
||||
)
|
||||
|
||||
@@ -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")
|
||||
|
||||
17
Eigen/Core
17
Eigen/Core
@@ -19,6 +19,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
|
||||
@@ -44,7 +50,7 @@
|
||||
#endif
|
||||
#else
|
||||
// Remember that usage of defined() in a #define is undefined by the standard
|
||||
#if (defined __SSE2__) && ( (!defined __GNUC__) || EIGEN_GNUC_AT_LEAST(4,2) )
|
||||
#if (defined __SSE2__) && ( (!defined __GNUC__) || (defined __INTEL_COMPILER) || EIGEN_GNUC_AT_LEAST(4,2) )
|
||||
#define EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC
|
||||
#endif
|
||||
#endif
|
||||
@@ -245,8 +251,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"
|
||||
@@ -344,13 +350,6 @@ using std::ptrdiff_t;
|
||||
#include "src/Core/ArrayBase.h"
|
||||
#include "src/Core/ArrayWrapper.h"
|
||||
|
||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
||||
#include "src/Core/Product.h"
|
||||
#include "src/Core/CoreEvaluators.h"
|
||||
#include "src/Core/AssignEvaluator.h"
|
||||
#include "src/Core/ProductEvaluators.h"
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_USE_BLAS
|
||||
#include "src/Core/products/GeneralMatrixMatrix_MKL.h"
|
||||
#include "src/Core/products/GeneralMatrixVector_MKL.h"
|
||||
|
||||
@@ -26,4 +26,4 @@
|
||||
#include "src/CholmodSupport/CholmodSupport.h"
|
||||
#include "src/SPQRSupport/SuiteSparseQRSupport.h"
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
14
Eigen/Sparse
14
Eigen/Sparse
@@ -1,13 +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
|
||||
* - IterativeLinearSolvers
|
||||
* - \ref SparseCore_Module
|
||||
* - \ref OrderingMethods_Module
|
||||
* - \ref SparseCholesky_Module
|
||||
* - \ref SparseLU_Module
|
||||
* - \ref SparseQR_Module
|
||||
* - \ref IterativeLinearSolvers_Module
|
||||
*
|
||||
* \code
|
||||
* #include <Eigen/Sparse>
|
||||
@@ -17,6 +19,8 @@
|
||||
#include "SparseCore"
|
||||
#include "OrderingMethods"
|
||||
#include "SparseCholesky"
|
||||
#include "SparseLU"
|
||||
#include "SparseQR"
|
||||
#include "IterativeLinearSolvers"
|
||||
|
||||
#endif // EIGEN_SPARSE_MODULE_H
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const V
|
||||
typedef Matrix<Scalar,Dynamic,1> TempVectorType;
|
||||
typedef typename TempVectorType::SegmentReturnType TempVecSegment;
|
||||
|
||||
int n = mat.cols();
|
||||
Index n = mat.cols();
|
||||
eigen_assert(mat.rows()==n && vec.size()==n);
|
||||
|
||||
TempVectorType temp;
|
||||
@@ -212,12 +212,12 @@ static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const V
|
||||
// i.e., for sigma > 0
|
||||
temp = sqrt(sigma) * vec;
|
||||
|
||||
for(int i=0; i<n; ++i)
|
||||
for(Index i=0; i<n; ++i)
|
||||
{
|
||||
JacobiRotation<Scalar> g;
|
||||
g.makeGivens(mat(i,i), -temp(i), &mat(i,i));
|
||||
|
||||
int rs = n-i-1;
|
||||
Index rs = n-i-1;
|
||||
if(rs>0)
|
||||
{
|
||||
ColXprSegment x(mat.col(i).tail(rs));
|
||||
@@ -230,12 +230,12 @@ static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const V
|
||||
{
|
||||
temp = vec;
|
||||
RealScalar beta = 1;
|
||||
for(int j=0; j<n; ++j)
|
||||
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;
|
||||
|
||||
@@ -51,7 +51,6 @@ void cholmod_configure_matrix(CholmodType& mat)
|
||||
template<typename _Scalar, int _Options, typename _Index>
|
||||
cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_Index>& mat)
|
||||
{
|
||||
typedef SparseMatrix<_Scalar,_Options,_Index> MatrixType;
|
||||
cholmod_sparse res;
|
||||
res.nzmax = mat.nonZeros();
|
||||
res.nrow = mat.rows();;
|
||||
@@ -127,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);
|
||||
@@ -296,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)
|
||||
{
|
||||
@@ -313,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
|
||||
@@ -345,7 +346,7 @@ class CholmodBase : internal::noncopyable
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void dumpMemory(Stream& s)
|
||||
void dumpMemory(Stream& /*s*/)
|
||||
{}
|
||||
|
||||
protected:
|
||||
|
||||
@@ -107,7 +107,7 @@ class Array
|
||||
*
|
||||
* \sa resize(Index,Index)
|
||||
*/
|
||||
EIGEN_STRONG_INLINE explicit Array() : Base()
|
||||
EIGEN_STRONG_INLINE Array() : Base()
|
||||
{
|
||||
Base::_check_template_params();
|
||||
EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -155,7 +155,7 @@ struct assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
|
||||
template<typename Derived1, typename Derived2, int Index, int Stop>
|
||||
struct assign_DefaultTraversal_InnerUnrolling
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, int outer)
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, typename Derived1::Index outer)
|
||||
{
|
||||
dst.copyCoeffByOuterInner(outer, Index, src);
|
||||
assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src, outer);
|
||||
@@ -165,7 +165,7 @@ struct assign_DefaultTraversal_InnerUnrolling
|
||||
template<typename Derived1, typename Derived2, int Stop>
|
||||
struct assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Stop, Stop>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, int) {}
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, typename Derived1::Index) {}
|
||||
};
|
||||
|
||||
/***********************
|
||||
@@ -218,7 +218,7 @@ struct assign_innervec_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
|
||||
template<typename Derived1, typename Derived2, int Index, int Stop>
|
||||
struct assign_innervec_InnerUnrolling
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, int outer)
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, typename Derived1::Index outer)
|
||||
{
|
||||
dst.template copyPacketByOuterInner<Derived2, Aligned, Aligned>(outer, Index, src);
|
||||
assign_innervec_InnerUnrolling<Derived1, Derived2,
|
||||
@@ -229,7 +229,7 @@ struct assign_innervec_InnerUnrolling
|
||||
template<typename Derived1, typename Derived2, int Stop>
|
||||
struct assign_innervec_InnerUnrolling<Derived1, Derived2, Stop, Stop>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, int) {}
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, typename Derived1::Index) {}
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
@@ -507,19 +507,19 @@ 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> {
|
||||
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> {
|
||||
@@ -528,6 +528,8 @@ struct assign_selector<Derived,OtherDerived,true,false> {
|
||||
template<typename Derived, typename OtherDerived>
|
||||
struct assign_selector<Derived,OtherDerived,false,true> {
|
||||
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> {
|
||||
@@ -566,16 +568,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
|
||||
|
||||
@@ -1,755 +0,0 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
// Copyright (C) 2011-2012 Jitse Niesen <jitse@maths.leeds.ac.uk>
|
||||
//
|
||||
// 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_ASSIGN_EVALUATOR_H
|
||||
#define EIGEN_ASSIGN_EVALUATOR_H
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
// This implementation is based on Assign.h
|
||||
|
||||
namespace internal {
|
||||
|
||||
/***************************************************************************
|
||||
* Part 1 : the logic deciding a strategy for traversal and unrolling *
|
||||
***************************************************************************/
|
||||
|
||||
// copy_using_evaluator_traits is based on assign_traits
|
||||
|
||||
template <typename Derived, typename OtherDerived>
|
||||
struct copy_using_evaluator_traits
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
DstIsAligned = Derived::Flags & AlignedBit,
|
||||
DstHasDirectAccess = Derived::Flags & DirectAccessBit,
|
||||
SrcIsAligned = OtherDerived::Flags & AlignedBit,
|
||||
JointAlignment = bool(DstIsAligned) && bool(SrcIsAligned) ? Aligned : Unaligned,
|
||||
SrcEvalBeforeAssign = (evaluator_traits<OtherDerived>::HasEvalTo == 1)
|
||||
};
|
||||
|
||||
private:
|
||||
enum {
|
||||
InnerSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::SizeAtCompileTime)
|
||||
: int(Derived::Flags)&RowMajorBit ? int(Derived::ColsAtCompileTime)
|
||||
: int(Derived::RowsAtCompileTime),
|
||||
InnerMaxSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::MaxSizeAtCompileTime)
|
||||
: int(Derived::Flags)&RowMajorBit ? int(Derived::MaxColsAtCompileTime)
|
||||
: int(Derived::MaxRowsAtCompileTime),
|
||||
MaxSizeAtCompileTime = Derived::SizeAtCompileTime,
|
||||
PacketSize = packet_traits<typename Derived::Scalar>::size
|
||||
};
|
||||
|
||||
enum {
|
||||
StorageOrdersAgree = (int(Derived::IsRowMajor) == int(OtherDerived::IsRowMajor)),
|
||||
MightVectorize = StorageOrdersAgree
|
||||
&& (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit),
|
||||
MayInnerVectorize = MightVectorize && int(InnerSize)!=Dynamic && int(InnerSize)%int(PacketSize)==0
|
||||
&& int(DstIsAligned) && int(SrcIsAligned),
|
||||
MayLinearize = StorageOrdersAgree && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit),
|
||||
MayLinearVectorize = MightVectorize && MayLinearize && DstHasDirectAccess
|
||||
&& (DstIsAligned || MaxSizeAtCompileTime == Dynamic),
|
||||
/* If the destination isn't aligned, we have to do runtime checks and we don't unroll,
|
||||
so it's only good for large enough sizes. */
|
||||
MaySliceVectorize = MightVectorize && DstHasDirectAccess
|
||||
&& (int(InnerMaxSize)==Dynamic || int(InnerMaxSize)>=3*PacketSize)
|
||||
/* slice vectorization can be slow, so we only want it if the slices are big, which is
|
||||
indicated by InnerMaxSize rather than InnerSize, think of the case of a dynamic block
|
||||
in a fixed-size matrix */
|
||||
};
|
||||
|
||||
public:
|
||||
enum {
|
||||
Traversal = int(SrcEvalBeforeAssign) ? int(AllAtOnceTraversal)
|
||||
: int(MayInnerVectorize) ? int(InnerVectorizedTraversal)
|
||||
: int(MayLinearVectorize) ? int(LinearVectorizedTraversal)
|
||||
: int(MaySliceVectorize) ? int(SliceVectorizedTraversal)
|
||||
: int(MayLinearize) ? int(LinearTraversal)
|
||||
: int(DefaultTraversal),
|
||||
Vectorized = int(Traversal) == InnerVectorizedTraversal
|
||||
|| int(Traversal) == LinearVectorizedTraversal
|
||||
|| int(Traversal) == SliceVectorizedTraversal
|
||||
};
|
||||
|
||||
private:
|
||||
enum {
|
||||
UnrollingLimit = EIGEN_UNROLLING_LIMIT * (Vectorized ? int(PacketSize) : 1),
|
||||
MayUnrollCompletely = int(Derived::SizeAtCompileTime) != Dynamic
|
||||
&& int(OtherDerived::CoeffReadCost) != Dynamic
|
||||
&& int(Derived::SizeAtCompileTime) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit),
|
||||
MayUnrollInner = int(InnerSize) != Dynamic
|
||||
&& int(OtherDerived::CoeffReadCost) != Dynamic
|
||||
&& int(InnerSize) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit)
|
||||
};
|
||||
|
||||
public:
|
||||
enum {
|
||||
Unrolling = (int(Traversal) == int(InnerVectorizedTraversal) || int(Traversal) == int(DefaultTraversal))
|
||||
? (
|
||||
int(MayUnrollCompletely) ? int(CompleteUnrolling)
|
||||
: int(MayUnrollInner) ? int(InnerUnrolling)
|
||||
: int(NoUnrolling)
|
||||
)
|
||||
: int(Traversal) == int(LinearVectorizedTraversal)
|
||||
? ( bool(MayUnrollCompletely) && bool(DstIsAligned) ? int(CompleteUnrolling)
|
||||
: int(NoUnrolling) )
|
||||
: int(Traversal) == int(LinearTraversal)
|
||||
? ( bool(MayUnrollCompletely) ? int(CompleteUnrolling)
|
||||
: int(NoUnrolling) )
|
||||
: int(NoUnrolling)
|
||||
};
|
||||
|
||||
#ifdef EIGEN_DEBUG_ASSIGN
|
||||
static void debug()
|
||||
{
|
||||
EIGEN_DEBUG_VAR(DstIsAligned)
|
||||
EIGEN_DEBUG_VAR(SrcIsAligned)
|
||||
EIGEN_DEBUG_VAR(JointAlignment)
|
||||
EIGEN_DEBUG_VAR(InnerSize)
|
||||
EIGEN_DEBUG_VAR(InnerMaxSize)
|
||||
EIGEN_DEBUG_VAR(PacketSize)
|
||||
EIGEN_DEBUG_VAR(StorageOrdersAgree)
|
||||
EIGEN_DEBUG_VAR(MightVectorize)
|
||||
EIGEN_DEBUG_VAR(MayLinearize)
|
||||
EIGEN_DEBUG_VAR(MayInnerVectorize)
|
||||
EIGEN_DEBUG_VAR(MayLinearVectorize)
|
||||
EIGEN_DEBUG_VAR(MaySliceVectorize)
|
||||
EIGEN_DEBUG_VAR(Traversal)
|
||||
EIGEN_DEBUG_VAR(UnrollingLimit)
|
||||
EIGEN_DEBUG_VAR(MayUnrollCompletely)
|
||||
EIGEN_DEBUG_VAR(MayUnrollInner)
|
||||
EIGEN_DEBUG_VAR(Unrolling)
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
* Part 2 : meta-unrollers
|
||||
***************************************************************************/
|
||||
|
||||
/************************
|
||||
*** Default traversal ***
|
||||
************************/
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Index, int Stop>
|
||||
struct copy_using_evaluator_DefaultTraversal_CompleteUnrolling
|
||||
{
|
||||
typedef typename DstEvaluatorType::XprType DstXprType;
|
||||
|
||||
enum {
|
||||
outer = Index / DstXprType::InnerSizeAtCompileTime,
|
||||
inner = Index % DstXprType::InnerSizeAtCompileTime
|
||||
};
|
||||
|
||||
static EIGEN_STRONG_INLINE void run(DstEvaluatorType &dstEvaluator,
|
||||
SrcEvaluatorType &srcEvaluator)
|
||||
{
|
||||
dstEvaluator.copyCoeffByOuterInner(outer, inner, srcEvaluator);
|
||||
copy_using_evaluator_DefaultTraversal_CompleteUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, Index+1, Stop>
|
||||
::run(dstEvaluator, srcEvaluator);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Stop>
|
||||
struct copy_using_evaluator_DefaultTraversal_CompleteUnrolling<DstEvaluatorType, SrcEvaluatorType, Stop, Stop>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(DstEvaluatorType&, SrcEvaluatorType&) { }
|
||||
};
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Index, int Stop>
|
||||
struct copy_using_evaluator_DefaultTraversal_InnerUnrolling
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(DstEvaluatorType &dstEvaluator,
|
||||
SrcEvaluatorType &srcEvaluator,
|
||||
int outer)
|
||||
{
|
||||
dstEvaluator.copyCoeffByOuterInner(outer, Index, srcEvaluator);
|
||||
copy_using_evaluator_DefaultTraversal_InnerUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, Index+1, Stop>
|
||||
::run(dstEvaluator, srcEvaluator, outer);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Stop>
|
||||
struct copy_using_evaluator_DefaultTraversal_InnerUnrolling<DstEvaluatorType, SrcEvaluatorType, Stop, Stop>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(DstEvaluatorType&, SrcEvaluatorType&, int) { }
|
||||
};
|
||||
|
||||
/***********************
|
||||
*** Linear traversal ***
|
||||
***********************/
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Index, int Stop>
|
||||
struct copy_using_evaluator_LinearTraversal_CompleteUnrolling
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(DstEvaluatorType &dstEvaluator,
|
||||
SrcEvaluatorType &srcEvaluator)
|
||||
{
|
||||
dstEvaluator.copyCoeff(Index, srcEvaluator);
|
||||
copy_using_evaluator_LinearTraversal_CompleteUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, Index+1, Stop>
|
||||
::run(dstEvaluator, srcEvaluator);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Stop>
|
||||
struct copy_using_evaluator_LinearTraversal_CompleteUnrolling<DstEvaluatorType, SrcEvaluatorType, Stop, Stop>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(DstEvaluatorType&, SrcEvaluatorType&) { }
|
||||
};
|
||||
|
||||
/**************************
|
||||
*** Inner vectorization ***
|
||||
**************************/
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Index, int Stop>
|
||||
struct copy_using_evaluator_innervec_CompleteUnrolling
|
||||
{
|
||||
typedef typename DstEvaluatorType::XprType DstXprType;
|
||||
typedef typename SrcEvaluatorType::XprType SrcXprType;
|
||||
|
||||
enum {
|
||||
outer = Index / DstXprType::InnerSizeAtCompileTime,
|
||||
inner = Index % DstXprType::InnerSizeAtCompileTime,
|
||||
JointAlignment = copy_using_evaluator_traits<DstXprType,SrcXprType>::JointAlignment
|
||||
};
|
||||
|
||||
static EIGEN_STRONG_INLINE void run(DstEvaluatorType &dstEvaluator,
|
||||
SrcEvaluatorType &srcEvaluator)
|
||||
{
|
||||
dstEvaluator.template copyPacketByOuterInner<Aligned, JointAlignment>(outer, inner, srcEvaluator);
|
||||
enum { NextIndex = Index + packet_traits<typename DstXprType::Scalar>::size };
|
||||
copy_using_evaluator_innervec_CompleteUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, NextIndex, Stop>
|
||||
::run(dstEvaluator, srcEvaluator);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Stop>
|
||||
struct copy_using_evaluator_innervec_CompleteUnrolling<DstEvaluatorType, SrcEvaluatorType, Stop, Stop>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(DstEvaluatorType&, SrcEvaluatorType&) { }
|
||||
};
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Index, int Stop>
|
||||
struct copy_using_evaluator_innervec_InnerUnrolling
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(DstEvaluatorType &dstEvaluator,
|
||||
SrcEvaluatorType &srcEvaluator,
|
||||
int outer)
|
||||
{
|
||||
dstEvaluator.template copyPacketByOuterInner<Aligned, Aligned>(outer, Index, srcEvaluator);
|
||||
typedef typename DstEvaluatorType::XprType DstXprType;
|
||||
enum { NextIndex = Index + packet_traits<typename DstXprType::Scalar>::size };
|
||||
copy_using_evaluator_innervec_InnerUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, NextIndex, Stop>
|
||||
::run(dstEvaluator, srcEvaluator, outer);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Stop>
|
||||
struct copy_using_evaluator_innervec_InnerUnrolling<DstEvaluatorType, SrcEvaluatorType, Stop, Stop>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(DstEvaluatorType&, SrcEvaluatorType&, int) { }
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
* Part 3 : implementation of all cases
|
||||
***************************************************************************/
|
||||
|
||||
// copy_using_evaluator_impl is based on assign_impl
|
||||
|
||||
template<typename DstXprType, typename SrcXprType,
|
||||
int Traversal = copy_using_evaluator_traits<DstXprType, SrcXprType>::Traversal,
|
||||
int Unrolling = copy_using_evaluator_traits<DstXprType, SrcXprType>::Unrolling>
|
||||
struct copy_using_evaluator_impl;
|
||||
|
||||
/************************
|
||||
*** Default traversal ***
|
||||
************************/
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, DefaultTraversal, NoUnrolling>
|
||||
{
|
||||
static void run(DstXprType& dst, const SrcXprType& src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
typedef typename DstXprType::Index Index;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
for(Index outer = 0; outer < dst.outerSize(); ++outer) {
|
||||
for(Index inner = 0; inner < dst.innerSize(); ++inner) {
|
||||
dstEvaluator.copyCoeffByOuterInner(outer, inner, srcEvaluator);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, DefaultTraversal, CompleteUnrolling>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
copy_using_evaluator_DefaultTraversal_CompleteUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, 0, DstXprType::SizeAtCompileTime>
|
||||
::run(dstEvaluator, srcEvaluator);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, DefaultTraversal, InnerUnrolling>
|
||||
{
|
||||
typedef typename DstXprType::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
const Index outerSize = dst.outerSize();
|
||||
for(Index outer = 0; outer < outerSize; ++outer)
|
||||
copy_using_evaluator_DefaultTraversal_InnerUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, 0, DstXprType::InnerSizeAtCompileTime>
|
||||
::run(dstEvaluator, srcEvaluator, outer);
|
||||
}
|
||||
};
|
||||
|
||||
/***************************
|
||||
*** Linear vectorization ***
|
||||
***************************/
|
||||
|
||||
template <bool IsAligned = false>
|
||||
struct unaligned_copy_using_evaluator_impl
|
||||
{
|
||||
// if IsAligned = true, then do nothing
|
||||
template <typename SrcEvaluatorType, typename DstEvaluatorType>
|
||||
static EIGEN_STRONG_INLINE void run(const SrcEvaluatorType&, DstEvaluatorType&,
|
||||
typename SrcEvaluatorType::Index, typename SrcEvaluatorType::Index) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct unaligned_copy_using_evaluator_impl<false>
|
||||
{
|
||||
// MSVC must not inline this functions. If it does, it fails to optimize the
|
||||
// packet access path.
|
||||
#ifdef _MSC_VER
|
||||
template <typename DstEvaluatorType, typename SrcEvaluatorType>
|
||||
static EIGEN_DONT_INLINE void run(DstEvaluatorType &dstEvaluator,
|
||||
const SrcEvaluatorType &srcEvaluator,
|
||||
typename DstEvaluatorType::Index start,
|
||||
typename DstEvaluatorType::Index end)
|
||||
#else
|
||||
template <typename DstEvaluatorType, typename SrcEvaluatorType>
|
||||
static EIGEN_STRONG_INLINE void run(DstEvaluatorType &dstEvaluator,
|
||||
const SrcEvaluatorType &srcEvaluator,
|
||||
typename DstEvaluatorType::Index start,
|
||||
typename DstEvaluatorType::Index end)
|
||||
#endif
|
||||
{
|
||||
for (typename DstEvaluatorType::Index index = start; index < end; ++index)
|
||||
dstEvaluator.copyCoeff(index, srcEvaluator);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, LinearVectorizedTraversal, NoUnrolling>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
typedef typename DstXprType::Index Index;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
const Index size = dst.size();
|
||||
typedef packet_traits<typename DstXprType::Scalar> PacketTraits;
|
||||
enum {
|
||||
packetSize = PacketTraits::size,
|
||||
dstIsAligned = int(copy_using_evaluator_traits<DstXprType,SrcXprType>::DstIsAligned),
|
||||
dstAlignment = PacketTraits::AlignedOnScalar ? Aligned : dstIsAligned,
|
||||
srcAlignment = copy_using_evaluator_traits<DstXprType,SrcXprType>::JointAlignment
|
||||
};
|
||||
const Index alignedStart = dstIsAligned ? 0 : internal::first_aligned(&dstEvaluator.coeffRef(0), size);
|
||||
const Index alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize;
|
||||
|
||||
unaligned_copy_using_evaluator_impl<dstIsAligned!=0>::run(dstEvaluator, srcEvaluator, 0, alignedStart);
|
||||
|
||||
for(Index index = alignedStart; index < alignedEnd; index += packetSize)
|
||||
{
|
||||
dstEvaluator.template copyPacket<dstAlignment, srcAlignment>(index, srcEvaluator);
|
||||
}
|
||||
|
||||
unaligned_copy_using_evaluator_impl<>::run(dstEvaluator, srcEvaluator, alignedEnd, size);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, LinearVectorizedTraversal, CompleteUnrolling>
|
||||
{
|
||||
typedef typename DstXprType::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
enum { size = DstXprType::SizeAtCompileTime,
|
||||
packetSize = packet_traits<typename DstXprType::Scalar>::size,
|
||||
alignedSize = (size/packetSize)*packetSize };
|
||||
|
||||
copy_using_evaluator_innervec_CompleteUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, 0, alignedSize>
|
||||
::run(dstEvaluator, srcEvaluator);
|
||||
copy_using_evaluator_DefaultTraversal_CompleteUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, alignedSize, size>
|
||||
::run(dstEvaluator, srcEvaluator);
|
||||
}
|
||||
};
|
||||
|
||||
/**************************
|
||||
*** Inner vectorization ***
|
||||
**************************/
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, InnerVectorizedTraversal, NoUnrolling>
|
||||
{
|
||||
inline static void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
typedef typename DstXprType::Index Index;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
const Index innerSize = dst.innerSize();
|
||||
const Index outerSize = dst.outerSize();
|
||||
const Index packetSize = packet_traits<typename DstXprType::Scalar>::size;
|
||||
for(Index outer = 0; outer < outerSize; ++outer)
|
||||
for(Index inner = 0; inner < innerSize; inner+=packetSize) {
|
||||
dstEvaluator.template copyPacketByOuterInner<Aligned, Aligned>(outer, inner, srcEvaluator);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, InnerVectorizedTraversal, CompleteUnrolling>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
copy_using_evaluator_innervec_CompleteUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, 0, DstXprType::SizeAtCompileTime>
|
||||
::run(dstEvaluator, srcEvaluator);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, InnerVectorizedTraversal, InnerUnrolling>
|
||||
{
|
||||
typedef typename DstXprType::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
const Index outerSize = dst.outerSize();
|
||||
for(Index outer = 0; outer < outerSize; ++outer)
|
||||
copy_using_evaluator_innervec_InnerUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, 0, DstXprType::InnerSizeAtCompileTime>
|
||||
::run(dstEvaluator, srcEvaluator, outer);
|
||||
}
|
||||
};
|
||||
|
||||
/***********************
|
||||
*** Linear traversal ***
|
||||
***********************/
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, LinearTraversal, NoUnrolling>
|
||||
{
|
||||
inline static void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
typedef typename DstXprType::Index Index;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
const Index size = dst.size();
|
||||
for(Index i = 0; i < size; ++i)
|
||||
dstEvaluator.copyCoeff(i, srcEvaluator);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, LinearTraversal, CompleteUnrolling>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
copy_using_evaluator_LinearTraversal_CompleteUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, 0, DstXprType::SizeAtCompileTime>
|
||||
::run(dstEvaluator, srcEvaluator);
|
||||
}
|
||||
};
|
||||
|
||||
/**************************
|
||||
*** Slice vectorization ***
|
||||
***************************/
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, SliceVectorizedTraversal, NoUnrolling>
|
||||
{
|
||||
inline static void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
typedef typename DstXprType::Index Index;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
typedef packet_traits<typename DstXprType::Scalar> PacketTraits;
|
||||
enum {
|
||||
packetSize = PacketTraits::size,
|
||||
alignable = PacketTraits::AlignedOnScalar,
|
||||
dstAlignment = alignable ? Aligned : int(copy_using_evaluator_traits<DstXprType,SrcXprType>::DstIsAligned)
|
||||
};
|
||||
const Index packetAlignedMask = packetSize - 1;
|
||||
const Index innerSize = dst.innerSize();
|
||||
const Index outerSize = dst.outerSize();
|
||||
const Index alignedStep = alignable ? (packetSize - dst.outerStride() % packetSize) & packetAlignedMask : 0;
|
||||
Index alignedStart = ((!alignable) || copy_using_evaluator_traits<DstXprType,SrcXprType>::DstIsAligned) ? 0
|
||||
: internal::first_aligned(&dstEvaluator.coeffRef(0,0), innerSize);
|
||||
|
||||
for(Index outer = 0; outer < outerSize; ++outer)
|
||||
{
|
||||
const Index alignedEnd = alignedStart + ((innerSize-alignedStart) & ~packetAlignedMask);
|
||||
// do the non-vectorizable part of the assignment
|
||||
for(Index inner = 0; inner<alignedStart ; ++inner) {
|
||||
dstEvaluator.copyCoeffByOuterInner(outer, inner, srcEvaluator);
|
||||
}
|
||||
|
||||
// do the vectorizable part of the assignment
|
||||
for(Index inner = alignedStart; inner<alignedEnd; inner+=packetSize) {
|
||||
dstEvaluator.template copyPacketByOuterInner<dstAlignment, Unaligned>(outer, inner, srcEvaluator);
|
||||
}
|
||||
|
||||
// do the non-vectorizable part of the assignment
|
||||
for(Index inner = alignedEnd; inner<innerSize ; ++inner) {
|
||||
dstEvaluator.copyCoeffByOuterInner(outer, inner, srcEvaluator);
|
||||
}
|
||||
|
||||
alignedStart = std::min<Index>((alignedStart+alignedStep)%packetSize, innerSize);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/****************************
|
||||
*** All-at-once traversal ***
|
||||
****************************/
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, AllAtOnceTraversal, NoUnrolling>
|
||||
{
|
||||
inline static void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
typedef typename DstXprType::Index Index;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
// Evaluate rhs in temporary to prevent aliasing problems in a = a * a;
|
||||
// TODO: Do not pass the xpr object to evalTo()
|
||||
srcEvaluator.evalTo(dstEvaluator, dst);
|
||||
}
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
* Part 4 : Entry points
|
||||
***************************************************************************/
|
||||
|
||||
// Based on DenseBase::LazyAssign()
|
||||
|
||||
template<typename DstXprType, template <typename> class StorageBase, typename SrcXprType>
|
||||
EIGEN_STRONG_INLINE
|
||||
const DstXprType& copy_using_evaluator(const NoAlias<DstXprType, StorageBase>& dst,
|
||||
const EigenBase<SrcXprType>& src)
|
||||
{
|
||||
return noalias_copy_using_evaluator(dst.expression(), src.derived());
|
||||
}
|
||||
|
||||
template<typename XprType, int AssumeAliasing = evaluator_traits<XprType>::AssumeAliasing>
|
||||
struct AddEvalIfAssumingAliasing;
|
||||
|
||||
template<typename XprType>
|
||||
struct AddEvalIfAssumingAliasing<XprType, 0>
|
||||
{
|
||||
static const XprType& run(const XprType& xpr)
|
||||
{
|
||||
return xpr;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename XprType>
|
||||
struct AddEvalIfAssumingAliasing<XprType, 1>
|
||||
{
|
||||
static const EvalToTemp<XprType> run(const XprType& xpr)
|
||||
{
|
||||
return EvalToTemp<XprType>(xpr);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
EIGEN_STRONG_INLINE
|
||||
const DstXprType& copy_using_evaluator(const EigenBase<DstXprType>& dst, const EigenBase<SrcXprType>& src)
|
||||
{
|
||||
return noalias_copy_using_evaluator(dst.const_cast_derived(),
|
||||
AddEvalIfAssumingAliasing<SrcXprType>::run(src.derived()));
|
||||
}
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
EIGEN_STRONG_INLINE
|
||||
const DstXprType& noalias_copy_using_evaluator(const PlainObjectBase<DstXprType>& dst, const EigenBase<SrcXprType>& src)
|
||||
{
|
||||
#ifdef EIGEN_DEBUG_ASSIGN
|
||||
internal::copy_using_evaluator_traits<DstXprType, SrcXprType>::debug();
|
||||
#endif
|
||||
#ifdef EIGEN_NO_AUTOMATIC_RESIZING
|
||||
eigen_assert((dst.size()==0 || (IsVectorAtCompileTime ? (dst.size() == src.size())
|
||||
: (dst.rows() == src.rows() && dst.cols() == src.cols())))
|
||||
&& "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
|
||||
#else
|
||||
dst.const_cast_derived().resizeLike(src.derived());
|
||||
#endif
|
||||
return copy_using_evaluator_without_resizing(dst.const_cast_derived(), src.derived());
|
||||
}
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
EIGEN_STRONG_INLINE
|
||||
const DstXprType& noalias_copy_using_evaluator(const EigenBase<DstXprType>& dst, const EigenBase<SrcXprType>& src)
|
||||
{
|
||||
return copy_using_evaluator_without_resizing(dst.const_cast_derived(), src.derived());
|
||||
}
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
const DstXprType& copy_using_evaluator_without_resizing(const DstXprType& dst, const SrcXprType& src)
|
||||
{
|
||||
#ifdef EIGEN_DEBUG_ASSIGN
|
||||
internal::copy_using_evaluator_traits<DstXprType, SrcXprType>::debug();
|
||||
#endif
|
||||
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
|
||||
copy_using_evaluator_impl<DstXprType, SrcXprType>::run(const_cast<DstXprType&>(dst), src);
|
||||
return dst;
|
||||
}
|
||||
|
||||
// Based on DenseBase::swap()
|
||||
// TODO: Chech whether we need to do something special for swapping two
|
||||
// Arrays or Matrices.
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
void swap_using_evaluator(const DstXprType& dst, const SrcXprType& src)
|
||||
{
|
||||
copy_using_evaluator(SwapWrapper<DstXprType>(const_cast<DstXprType&>(dst)), src);
|
||||
}
|
||||
|
||||
// Based on MatrixBase::operator+= (in CwiseBinaryOp.h)
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
void add_assign_using_evaluator(const MatrixBase<DstXprType>& dst, const MatrixBase<SrcXprType>& src)
|
||||
{
|
||||
typedef typename DstXprType::Scalar Scalar;
|
||||
SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, DstXprType, SrcXprType> tmp(dst.const_cast_derived());
|
||||
copy_using_evaluator(tmp, src.derived());
|
||||
}
|
||||
|
||||
// Based on ArrayBase::operator+=
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
void add_assign_using_evaluator(const ArrayBase<DstXprType>& dst, const ArrayBase<SrcXprType>& src)
|
||||
{
|
||||
typedef typename DstXprType::Scalar Scalar;
|
||||
SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, DstXprType, SrcXprType> tmp(dst.const_cast_derived());
|
||||
copy_using_evaluator(tmp, src.derived());
|
||||
}
|
||||
|
||||
// TODO: Add add_assign_using_evaluator for EigenBase ?
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
void subtract_assign_using_evaluator(const MatrixBase<DstXprType>& dst, const MatrixBase<SrcXprType>& src)
|
||||
{
|
||||
typedef typename DstXprType::Scalar Scalar;
|
||||
SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, DstXprType, SrcXprType> tmp(dst.const_cast_derived());
|
||||
copy_using_evaluator(tmp, src.derived());
|
||||
}
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
void subtract_assign_using_evaluator(const ArrayBase<DstXprType>& dst, const ArrayBase<SrcXprType>& src)
|
||||
{
|
||||
typedef typename DstXprType::Scalar Scalar;
|
||||
SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, DstXprType, SrcXprType> tmp(dst.const_cast_derived());
|
||||
copy_using_evaluator(tmp, src.derived());
|
||||
}
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
void multiply_assign_using_evaluator(const ArrayBase<DstXprType>& dst, const ArrayBase<SrcXprType>& src)
|
||||
{
|
||||
typedef typename DstXprType::Scalar Scalar;
|
||||
SelfCwiseBinaryOp<internal::scalar_product_op<Scalar>, DstXprType, SrcXprType> tmp(dst.const_cast_derived());
|
||||
copy_using_evaluator(tmp, src.derived());
|
||||
}
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
void divide_assign_using_evaluator(const ArrayBase<DstXprType>& dst, const ArrayBase<SrcXprType>& src)
|
||||
{
|
||||
typedef typename DstXprType::Scalar Scalar;
|
||||
SelfCwiseBinaryOp<internal::scalar_quotient_op<Scalar>, DstXprType, SrcXprType> tmp(dst.const_cast_derived());
|
||||
copy_using_evaluator(tmp, src.derived());
|
||||
}
|
||||
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_ASSIGN_EVALUATOR_H
|
||||
@@ -129,6 +129,26 @@ inline typename DenseBase<Derived>::Index DenseBase<Derived>::count() const
|
||||
return derived().template cast<bool>().template cast<Index>().sum();
|
||||
}
|
||||
|
||||
/** \returns true is \c *this contains at least one Not A Number (NaN).
|
||||
*
|
||||
* \sa allFinite()
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline bool DenseBase<Derived>::hasNaN() const
|
||||
{
|
||||
return !((derived().array()==derived().array()).all());
|
||||
}
|
||||
|
||||
/** \returns true if \c *this contains only finite numbers, i.e., no NaN and no +/-INF values.
|
||||
*
|
||||
* \sa hasNaN()
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline bool DenseBase<Derived>::allFinite() const
|
||||
{
|
||||
return !((derived()-derived()).hasNaN());
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_ALLANDANY_H
|
||||
|
||||
@@ -118,6 +118,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
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -94,8 +94,8 @@ struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
|
||||
// So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to
|
||||
// add together a float matrix and a double matrix.
|
||||
#define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \
|
||||
EIGEN_STATIC_ASSERT((internal::functor_allows_mixing_real_and_complex<BINOP>::ret \
|
||||
? int(internal::is_same<typename NumTraits<LHS>::Real, typename NumTraits<RHS>::Real>::value) \
|
||||
EIGEN_STATIC_ASSERT((internal::functor_is_product_like<BINOP>::ret \
|
||||
? int(internal::scalar_product_traits<LHS, RHS>::Defined) \
|
||||
: int(internal::is_same<LHS, RHS>::value)), \
|
||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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
|
||||
*
|
||||
@@ -271,7 +281,7 @@ template<typename Derived> class DenseBase
|
||||
CommaInitializer<Derived> operator<< (const DenseBase<OtherDerived>& other);
|
||||
|
||||
Eigen::Transpose<Derived> transpose();
|
||||
typedef const Transpose<const Derived> ConstTransposeReturnType;
|
||||
typedef typename internal::add_const<Transpose<const Derived> >::type ConstTransposeReturnType;
|
||||
ConstTransposeReturnType transpose() const;
|
||||
void transposeInPlace();
|
||||
#ifndef EIGEN_NO_DEBUG
|
||||
@@ -336,6 +346,9 @@ template<typename Derived> class DenseBase
|
||||
bool isConstant(const Scalar& value, const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||
bool isZero(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||
bool isOnes(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||
|
||||
inline bool hasNaN() const;
|
||||
inline bool allFinite() const;
|
||||
|
||||
inline Derived& operator*=(const Scalar& other);
|
||||
inline Derived& operator/=(const Scalar& other);
|
||||
@@ -415,8 +428,6 @@ template<typename Derived> class DenseBase
|
||||
return derived().coeff(0,0);
|
||||
}
|
||||
|
||||
/////////// Array module ///////////
|
||||
|
||||
bool all(void) const;
|
||||
bool any(void) const;
|
||||
Index count() const;
|
||||
@@ -442,11 +453,11 @@ template<typename Derived> class DenseBase
|
||||
|
||||
template<typename ThenDerived>
|
||||
inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
|
||||
select(const DenseBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const;
|
||||
select(const DenseBase<ThenDerived>& thenMatrix, const typename ThenDerived::Scalar& elseScalar) const;
|
||||
|
||||
template<typename ElseDerived>
|
||||
inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
|
||||
select(typename ElseDerived::Scalar thenScalar, const DenseBase<ElseDerived>& elseMatrix) const;
|
||||
select(const typename ElseDerived::Scalar& thenScalar, const DenseBase<ElseDerived>& elseMatrix) const;
|
||||
|
||||
template<int p> RealScalar lpNorm() const;
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseSt
|
||||
{
|
||||
internal::plain_array<T,Size,_Options> m_data;
|
||||
public:
|
||||
inline explicit DenseStorage() {}
|
||||
inline DenseStorage() {}
|
||||
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
: m_data(internal::constructor_without_unaligned_array_assert()) {}
|
||||
inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
|
||||
@@ -131,7 +131,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& ) {}
|
||||
@@ -160,7 +160,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) {}
|
||||
@@ -180,7 +180,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) {}
|
||||
@@ -199,7 +199,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) {}
|
||||
@@ -219,7 +219,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)
|
||||
@@ -260,7 +260,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 }
|
||||
@@ -296,7 +296,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 }
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -112,7 +112,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.
|
||||
@@ -166,6 +166,7 @@ struct lpNorm_selector
|
||||
typedef typename NumTraits<typename traits<Derived>::Scalar>::Real RealScalar;
|
||||
static inline RealScalar run(const MatrixBase<Derived>& m)
|
||||
{
|
||||
using std::pow;
|
||||
return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p);
|
||||
}
|
||||
};
|
||||
@@ -228,7 +229,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,
|
||||
|
||||
@@ -171,7 +171,7 @@ 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)
|
||||
inline Scalar operator() (const Scalar& a, const OtherScalar& b) const { return internal::pow(a, b); }
|
||||
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 +310,7 @@ 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_STRONG_INLINE const result_type operator() (const Scalar& a) const { return internal::abs2(a); }
|
||||
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 +326,7 @@ struct functor_traits<scalar_abs2_op<Scalar> >
|
||||
*/
|
||||
template<typename Scalar> struct scalar_conjugate_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_conjugate_op)
|
||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { using internal::conj; return conj(a); }
|
||||
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 +363,7 @@ template<typename Scalar>
|
||||
struct scalar_real_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_real_op)
|
||||
typedef typename NumTraits<Scalar>::Real result_type;
|
||||
EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return internal::real(a); }
|
||||
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 +378,7 @@ template<typename Scalar>
|
||||
struct scalar_imag_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_op)
|
||||
typedef typename NumTraits<Scalar>::Real result_type;
|
||||
EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return internal::imag(a); }
|
||||
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 +393,7 @@ template<typename Scalar>
|
||||
struct scalar_real_ref_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_real_ref_op)
|
||||
typedef typename NumTraits<Scalar>::Real result_type;
|
||||
EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return internal::real_ref(*const_cast<Scalar*>(&a)); }
|
||||
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 +408,7 @@ template<typename Scalar>
|
||||
struct scalar_imag_ref_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_ref_op)
|
||||
typedef typename NumTraits<Scalar>::Real result_type;
|
||||
EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return internal::imag_ref(*const_cast<Scalar*>(&a)); }
|
||||
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> >
|
||||
@@ -560,7 +560,7 @@ struct linspaced_op_impl<Scalar,false>
|
||||
EIGEN_STRONG_INLINE const Scalar operator() (Index i) const
|
||||
{
|
||||
m_base = padd(m_base, pset1<Packet>(m_step));
|
||||
return m_low+i*m_step;
|
||||
return m_low+Scalar(i)*m_step;
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
@@ -609,7 +609,7 @@ template <typename Scalar, bool RandomAccess> struct functor_traits< linspaced_o
|
||||
template <typename Scalar, bool RandomAccess> struct linspaced_op
|
||||
{
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
linspaced_op(const Scalar& low, const Scalar& high, int num_steps) : impl((num_steps==1 ? high : low), (num_steps==1 ? Scalar() : (high-low)/(num_steps-1))) {}
|
||||
linspaced_op(const Scalar& low, const Scalar& high, DenseIndex num_steps) : impl((num_steps==1 ? high : low), (num_steps==1 ? Scalar() : (high-low)/(num_steps-1))) {}
|
||||
|
||||
template<typename Index>
|
||||
EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return impl(i); }
|
||||
@@ -648,13 +648,14 @@ template <typename Scalar, bool RandomAccess> struct linspaced_op
|
||||
template<typename Functor> struct functor_has_linear_access { enum { ret = 1 }; };
|
||||
template<typename Scalar> struct functor_has_linear_access<scalar_identity_op<Scalar> > { enum { ret = 0 }; };
|
||||
|
||||
// in CwiseBinaryOp, we require the Lhs and Rhs to have the same scalar type, except for multiplication
|
||||
// where we only require them to have the same _real_ scalar type so one may multiply, say, float by complex<float>.
|
||||
// In Eigen, any binary op (Product, CwiseBinaryOp) require the Lhs and Rhs to have the same scalar type, except for multiplication
|
||||
// where the mixing of different types is handled by scalar_product_traits
|
||||
// In particular, real * complex<real> is allowed.
|
||||
// FIXME move this to functor_traits adding a functor_default
|
||||
template<typename Functor> struct functor_allows_mixing_real_and_complex { enum { ret = 0 }; };
|
||||
template<typename LhsScalar,typename RhsScalar> struct functor_allows_mixing_real_and_complex<scalar_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
|
||||
template<typename LhsScalar,typename RhsScalar> struct functor_allows_mixing_real_and_complex<scalar_conj_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
|
||||
template<typename LhsScalar,typename RhsScalar> struct functor_allows_mixing_real_and_complex<scalar_quotient_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
|
||||
template<typename Functor> struct functor_is_product_like { enum { ret = 0 }; };
|
||||
template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
|
||||
template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_conj_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
|
||||
template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_quotient_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
|
||||
|
||||
|
||||
/** \internal
|
||||
@@ -800,7 +801,7 @@ 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) {}
|
||||
inline Scalar operator() (const Scalar& a) const { return internal::pow(a, m_exponent); }
|
||||
inline Scalar operator() (const Scalar& a) const { return numext::pow(a, m_exponent); }
|
||||
const Scalar m_exponent;
|
||||
};
|
||||
template<typename Scalar>
|
||||
|
||||
@@ -42,7 +42,7 @@ struct isMuchSmallerThan_object_selector
|
||||
{
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -60,7 +60,7 @@ struct isMuchSmallerThan_scalar_selector
|
||||
{
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -106,7 +106,7 @@ pnegate(const Packet& a) { return -a; }
|
||||
|
||||
/** \internal \returns conj(a) (coeff-wise) */
|
||||
template<typename Packet> 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> inline Packet
|
||||
@@ -156,7 +156,11 @@ pload(const typename unpacket_traits<Packet>::type* from) { return *from; }
|
||||
template<typename Packet> inline Packet
|
||||
ploadu(const typename unpacket_traits<Packet>::type* from) { return *from; }
|
||||
|
||||
/** \internal \returns a packet with elements of \a *from duplicated, e.g.: (from[0],from[0],from[1],from[1]) */
|
||||
/** \internal \returns a packet with elements of \a *from duplicated.
|
||||
* For instance, for a packet of 8 elements, 4 scalar will be read from \a *from and
|
||||
* duplicated to form: {from[0],from[0],from[1],from[1],,from[2],from[2],,from[3],from[3]}
|
||||
* Currently, this function is only used for scalar * complex products.
|
||||
*/
|
||||
template<typename Packet> inline Packet
|
||||
ploaddup(const typename unpacket_traits<Packet>::type* from) { return *from; }
|
||||
|
||||
@@ -307,8 +311,21 @@ struct palign_impl
|
||||
static inline void run(PacketType&, const PacketType&) {}
|
||||
};
|
||||
|
||||
/** \internal update \a first using the concatenation of the \a Offset last elements
|
||||
* of \a first and packet_size minus \a Offset first elements of \a second */
|
||||
/** \internal update \a first using the concatenation of the packet_size minus \a Offset last elements
|
||||
* of \a first and \a Offset first elements of \a second.
|
||||
*
|
||||
* This function is currently only used to optimize matrix-vector products on unligned matrices.
|
||||
* It takes 2 packets that represent a contiguous memory array, and returns a packet starting
|
||||
* at the position \a Offset. For instance, for packets of 4 elements, we have:
|
||||
* Input:
|
||||
* - first = {f0,f1,f2,f3}
|
||||
* - second = {s0,s1,s2,s3}
|
||||
* Output:
|
||||
* - if Offset==0 then {f0,f1,f2,f3}
|
||||
* - if Offset==1 then {f1,f2,f3,s0}
|
||||
* - if Offset==2 then {f2,f3,s0,s1}
|
||||
* - if Offset==3 then {f3,s0,s1,s3}
|
||||
*/
|
||||
template<int Offset,typename PacketType>
|
||||
inline void palign(PacketType& first, const PacketType& second)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
@@ -70,7 +71,7 @@ namespace Eigen
|
||||
**/
|
||||
template <typename Derived>
|
||||
inline const Eigen::CwiseUnaryOp<Eigen::internal::scalar_inverse_mult_op<typename Derived::Scalar>, const Derived>
|
||||
operator/(typename Derived::Scalar s, const Eigen::ArrayBase<Derived>& a)
|
||||
operator/(const typename Derived::Scalar& s, const Eigen::ArrayBase<Derived>& a)
|
||||
{
|
||||
return Eigen::CwiseUnaryOp<Eigen::internal::scalar_inverse_mult_op<typename Derived::Scalar>, const Derived>(
|
||||
a.derived(),
|
||||
@@ -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
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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;
|
||||
static inline RealScalar run(const Scalar& x)
|
||||
@@ -69,34 +68,32 @@ struct real_impl
|
||||
}
|
||||
};
|
||||
|
||||
template<typename RealScalar>
|
||||
struct real_impl<std::complex<RealScalar> >
|
||||
template<typename Scalar>
|
||||
struct real_default_impl<Scalar,true>
|
||||
{
|
||||
static inline RealScalar run(const std::complex<RealScalar>& x)
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
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>
|
||||
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;
|
||||
static inline RealScalar run(const Scalar&)
|
||||
@@ -105,28 +102,25 @@ struct imag_impl
|
||||
}
|
||||
};
|
||||
|
||||
template<typename RealScalar>
|
||||
struct imag_impl<std::complex<RealScalar> >
|
||||
template<typename Scalar>
|
||||
struct imag_default_impl<Scalar,true>
|
||||
{
|
||||
static inline RealScalar run(const std::complex<RealScalar>& x)
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
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>
|
||||
inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Implementation of real_ref *
|
||||
****************************************************************************/
|
||||
@@ -151,18 +145,6 @@ struct real_ref_retval
|
||||
typedef typename NumTraits<Scalar>::Real & type;
|
||||
};
|
||||
|
||||
template<typename Scalar>
|
||||
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>
|
||||
inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Implementation of imag_ref *
|
||||
****************************************************************************/
|
||||
@@ -203,23 +185,11 @@ struct imag_ref_retval
|
||||
typedef typename NumTraits<Scalar>::Real & type;
|
||||
};
|
||||
|
||||
template<typename Scalar>
|
||||
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>
|
||||
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
|
||||
{
|
||||
static inline Scalar run(const Scalar& x)
|
||||
@@ -228,10 +198,10 @@ struct conj_impl
|
||||
}
|
||||
};
|
||||
|
||||
template<typename RealScalar>
|
||||
struct conj_impl<std::complex<RealScalar> >
|
||||
template<typename Scalar>
|
||||
struct conj_impl<Scalar,true>
|
||||
{
|
||||
static inline std::complex<RealScalar> run(const std::complex<RealScalar>& x)
|
||||
static inline Scalar run(const Scalar& x)
|
||||
{
|
||||
using std::conj;
|
||||
return conj(x);
|
||||
@@ -244,12 +214,6 @@ struct conj_retval
|
||||
typedef Scalar type;
|
||||
};
|
||||
|
||||
template<typename Scalar>
|
||||
inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Implementation of abs2 *
|
||||
****************************************************************************/
|
||||
@@ -279,12 +243,6 @@ struct abs2_retval
|
||||
typedef typename NumTraits<Scalar>::Real type;
|
||||
};
|
||||
|
||||
template<typename Scalar>
|
||||
inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Implementation of norm1 *
|
||||
****************************************************************************/
|
||||
@@ -319,12 +277,6 @@ struct norm1_retval
|
||||
typedef typename NumTraits<Scalar>::Real type;
|
||||
};
|
||||
|
||||
template<typename Scalar>
|
||||
inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Implementation of hypot *
|
||||
****************************************************************************/
|
||||
@@ -342,6 +294,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);
|
||||
@@ -354,12 +307,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 *
|
||||
****************************************************************************/
|
||||
@@ -396,7 +343,7 @@ struct atanh2_default_impl
|
||||
using std::log;
|
||||
using std::sqrt;
|
||||
Scalar z = x / y;
|
||||
if (abs(z) > sqrt(NumTraits<RealScalar>::epsilon()))
|
||||
if (y == Scalar(0) || abs(z) > sqrt(NumTraits<RealScalar>::epsilon()))
|
||||
return RealScalar(0.5) * log((y + x) / (y - x));
|
||||
else
|
||||
return z + z*z*z / RealScalar(3);
|
||||
@@ -422,12 +369,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 *
|
||||
****************************************************************************/
|
||||
@@ -471,12 +412,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 *
|
||||
****************************************************************************/
|
||||
@@ -575,11 +510,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
|
||||
}
|
||||
};
|
||||
@@ -611,6 +545,97 @@ 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>
|
||||
inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
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>
|
||||
inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
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>
|
||||
inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// 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 numext
|
||||
|
||||
namespace internal {
|
||||
|
||||
/****************************************************************************
|
||||
* Implementation of fuzzy comparisons *
|
||||
****************************************************************************/
|
||||
@@ -668,12 +693,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)
|
||||
{
|
||||
using std::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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -735,17 +760,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
|
||||
|
||||
@@ -200,7 +200,7 @@ class Matrix
|
||||
*
|
||||
* \sa resize(Index,Index)
|
||||
*/
|
||||
EIGEN_STRONG_INLINE explicit Matrix() : Base()
|
||||
EIGEN_STRONG_INLINE Matrix() : Base()
|
||||
{
|
||||
Base::_check_template_params();
|
||||
EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
||||
|
||||
@@ -215,8 +215,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; };
|
||||
@@ -457,7 +457,7 @@ template<typename Derived> class MatrixBase
|
||||
const MatrixFunctionReturnValue<Derived> sin() const;
|
||||
const MatrixSquareRootReturnValue<Derived> sqrt() const;
|
||||
const MatrixLogarithmReturnValue<Derived> log() const;
|
||||
const MatrixPowerReturnValue<Derived> pow(RealScalar p) const;
|
||||
const MatrixPowerReturnValue<Derived> pow(const RealScalar& p) const;
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
template<typename ProductDerived, typename Lhs, typename Rhs>
|
||||
|
||||
@@ -80,6 +80,10 @@ class NoAlias
|
||||
template<typename Lhs, typename Rhs, int NestingFlags>
|
||||
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
|
||||
|
||||
ExpressionType& expression() const
|
||||
|
||||
@@ -140,6 +140,9 @@ struct NumTraits<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
|
||||
AddCost = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::AddCost,
|
||||
MulCost = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::MulCost
|
||||
};
|
||||
|
||||
static inline RealScalar epsilon() { return NumTraits<RealScalar>::epsilon(); }
|
||||
static inline RealScalar dummy_precision() { return NumTraits<RealScalar>::dummy_precision(); }
|
||||
};
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -541,24 +541,25 @@ struct permut_matrix_product_retval
|
||||
: public ReturnByValue<permut_matrix_product_retval<PermutationType, MatrixType, Side, Transposed> >
|
||||
{
|
||||
typedef typename remove_all<typename MatrixType::Nested>::type MatrixTypeNestedCleaned;
|
||||
typedef typename MatrixType::Index Index;
|
||||
|
||||
permut_matrix_product_retval(const PermutationType& perm, const MatrixType& matrix)
|
||||
: m_permutation(perm), m_matrix(matrix)
|
||||
{}
|
||||
|
||||
inline int rows() const { return m_matrix.rows(); }
|
||||
inline int cols() const { return m_matrix.cols(); }
|
||||
inline Index rows() const { return m_matrix.rows(); }
|
||||
inline Index cols() const { return m_matrix.cols(); }
|
||||
|
||||
template<typename Dest> inline void evalTo(Dest& dst) const
|
||||
{
|
||||
const int n = Side==OnTheLeft ? rows() : cols();
|
||||
const Index n = Side==OnTheLeft ? rows() : cols();
|
||||
|
||||
if(is_same<MatrixTypeNestedCleaned,Dest>::value && extract_data(dst) == extract_data(m_matrix))
|
||||
{
|
||||
// apply the permutation inplace
|
||||
Matrix<bool,PermutationType::RowsAtCompileTime,1,0,PermutationType::MaxRowsAtCompileTime> mask(m_permutation.size());
|
||||
mask.fill(false);
|
||||
int r = 0;
|
||||
Index r = 0;
|
||||
while(r < m_permutation.size())
|
||||
{
|
||||
// search for the next seed
|
||||
@@ -566,10 +567,10 @@ struct permut_matrix_product_retval
|
||||
if(r>=m_permutation.size())
|
||||
break;
|
||||
// we got one, let's follow it until we are back to the seed
|
||||
int k0 = r++;
|
||||
int kPrev = k0;
|
||||
Index k0 = r++;
|
||||
Index kPrev = k0;
|
||||
mask.coeffRef(k0) = true;
|
||||
for(int k=m_permutation.indices().coeff(k0); k!=k0; k=m_permutation.indices().coeff(k))
|
||||
for(Index k=m_permutation.indices().coeff(k0); k!=k0; k=m_permutation.indices().coeff(k))
|
||||
{
|
||||
Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>(dst, k)
|
||||
.swap(Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>
|
||||
|
||||
@@ -418,7 +418,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
return Base::operator=(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
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2008-2011 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_PRODUCT_H
|
||||
#define EIGEN_PRODUCT_H
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
template<typename Lhs, typename Rhs> class Product;
|
||||
template<typename Lhs, typename Rhs, typename StorageKind> class ProductImpl;
|
||||
|
||||
/** \class Product
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* \brief Expression of the product of two arbitrary matrices or vectors
|
||||
*
|
||||
* \param Lhs the type of the left-hand side expression
|
||||
* \param Rhs the type of the right-hand side expression
|
||||
*
|
||||
* This class represents an expression of the product of two arbitrary matrices.
|
||||
*
|
||||
*/
|
||||
|
||||
// Use ProductReturnType to get correct traits, in particular vectorization flags
|
||||
namespace internal {
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct traits<Product<Lhs, Rhs> >
|
||||
: traits<typename ProductReturnType<Lhs, Rhs>::Type>
|
||||
{
|
||||
// We want A+B*C to be of type Product<Matrix, Sum> and not Product<Matrix, Matrix>
|
||||
// TODO: This flag should eventually go in a separate evaluator traits class
|
||||
enum {
|
||||
Flags = traits<typename ProductReturnType<Lhs, Rhs>::Type>::Flags & ~EvalBeforeNestingBit
|
||||
};
|
||||
};
|
||||
} // end namespace internal
|
||||
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
class Product : public ProductImpl<Lhs,Rhs,typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind,
|
||||
typename internal::traits<Rhs>::StorageKind>::ret>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename ProductImpl<
|
||||
Lhs, Rhs,
|
||||
typename internal::promote_storage_type<typename Lhs::StorageKind,
|
||||
typename Rhs::StorageKind>::ret>::Base Base;
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(Product)
|
||||
|
||||
typedef typename Lhs::Nested LhsNested;
|
||||
typedef typename Rhs::Nested RhsNested;
|
||||
typedef typename internal::remove_all<LhsNested>::type LhsNestedCleaned;
|
||||
typedef typename internal::remove_all<RhsNested>::type RhsNestedCleaned;
|
||||
|
||||
Product(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs)
|
||||
{
|
||||
eigen_assert(lhs.cols() == rhs.rows()
|
||||
&& "invalid matrix product"
|
||||
&& "if you wanted a coeff-wise or a dot product use the respective explicit functions");
|
||||
}
|
||||
|
||||
inline Index rows() const { return m_lhs.rows(); }
|
||||
inline Index cols() const { return m_rhs.cols(); }
|
||||
|
||||
const LhsNestedCleaned& lhs() const { return m_lhs; }
|
||||
const RhsNestedCleaned& rhs() const { return m_rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
LhsNested m_lhs;
|
||||
RhsNested m_rhs;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
class ProductImpl<Lhs,Rhs,Dense> : public internal::dense_xpr_base<Product<Lhs,Rhs> >::type
|
||||
{
|
||||
typedef Product<Lhs, Rhs> Derived;
|
||||
public:
|
||||
|
||||
typedef typename internal::dense_xpr_base<Product<Lhs, Rhs> >::type Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
* Implementation of matrix base methods
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
/** \internal used to test the evaluator only
|
||||
*/
|
||||
template<typename Lhs,typename Rhs>
|
||||
const Product<Lhs,Rhs>
|
||||
prod(const Lhs& lhs, const Rhs& rhs)
|
||||
{
|
||||
return Product<Lhs,Rhs>(lhs,rhs);
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_PRODUCT_H
|
||||
@@ -195,7 +195,7 @@ class ScaledProduct;
|
||||
// Also note that here we accept any compatible scalar types
|
||||
template<typename Derived,typename Lhs,typename Rhs>
|
||||
const ScaledProduct<Derived>
|
||||
operator*(const ProductBase<Derived,Lhs,Rhs>& prod, typename Derived::Scalar x)
|
||||
operator*(const ProductBase<Derived,Lhs,Rhs>& prod, const typename Derived::Scalar& x)
|
||||
{ return ScaledProduct<Derived>(prod.derived(), x); }
|
||||
|
||||
template<typename Derived,typename Lhs,typename Rhs>
|
||||
@@ -207,7 +207,7 @@ operator*(const ProductBase<Derived,Lhs,Rhs>& prod, const typename Derived::Real
|
||||
|
||||
template<typename Derived,typename Lhs,typename Rhs>
|
||||
const ScaledProduct<Derived>
|
||||
operator*(typename Derived::Scalar x,const ProductBase<Derived,Lhs,Rhs>& prod)
|
||||
operator*(const typename Derived::Scalar& x,const ProductBase<Derived,Lhs,Rhs>& prod)
|
||||
{ return ScaledProduct<Derived>(prod.derived(), x); }
|
||||
|
||||
template<typename Derived,typename Lhs,typename Rhs>
|
||||
|
||||
@@ -1,411 +0,0 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
// Copyright (C) 2011 Jitse Niesen <jitse@maths.leeds.ac.uk>
|
||||
//
|
||||
// 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_PRODUCTEVALUATORS_H
|
||||
#define EIGEN_PRODUCTEVALUATORS_H
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
// We can evaluate the product either all at once, like GeneralProduct and its evalTo() function, or
|
||||
// traverse the matrix coefficient by coefficient, like CoeffBasedProduct. Use the existing logic
|
||||
// in ProductReturnType to decide.
|
||||
|
||||
template<typename XprType, typename ProductType>
|
||||
struct product_evaluator_dispatcher;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct evaluator_impl<Product<Lhs, Rhs> >
|
||||
: product_evaluator_dispatcher<Product<Lhs, Rhs>, typename ProductReturnType<Lhs, Rhs>::Type>
|
||||
{
|
||||
typedef Product<Lhs, Rhs> XprType;
|
||||
typedef product_evaluator_dispatcher<XprType, typename ProductReturnType<Lhs, Rhs>::Type> Base;
|
||||
|
||||
evaluator_impl(const XprType& xpr) : Base(xpr)
|
||||
{ }
|
||||
};
|
||||
|
||||
template<typename XprType, typename ProductType>
|
||||
struct product_evaluator_traits_dispatcher;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct evaluator_traits<Product<Lhs, Rhs> >
|
||||
: product_evaluator_traits_dispatcher<Product<Lhs, Rhs>, typename ProductReturnType<Lhs, Rhs>::Type>
|
||||
{
|
||||
static const int AssumeAliasing = 1;
|
||||
};
|
||||
|
||||
// Case 1: Evaluate all at once
|
||||
//
|
||||
// We can view the GeneralProduct class as a part of the product evaluator.
|
||||
// Four sub-cases: InnerProduct, OuterProduct, GemmProduct and GemvProduct.
|
||||
// InnerProduct is special because GeneralProduct does not have an evalTo() method in this case.
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct product_evaluator_traits_dispatcher<Product<Lhs, Rhs>, GeneralProduct<Lhs, Rhs, InnerProduct> >
|
||||
{
|
||||
static const int HasEvalTo = 0;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct product_evaluator_dispatcher<Product<Lhs, Rhs>, GeneralProduct<Lhs, Rhs, InnerProduct> >
|
||||
: public evaluator<typename Product<Lhs, Rhs>::PlainObject>::type
|
||||
{
|
||||
typedef Product<Lhs, Rhs> XprType;
|
||||
typedef typename XprType::PlainObject PlainObject;
|
||||
typedef typename evaluator<PlainObject>::type evaluator_base;
|
||||
|
||||
// TODO: Computation is too early (?)
|
||||
product_evaluator_dispatcher(const XprType& xpr) : evaluator_base(m_result)
|
||||
{
|
||||
m_result.coeffRef(0,0) = (xpr.lhs().transpose().cwiseProduct(xpr.rhs())).sum();
|
||||
}
|
||||
|
||||
protected:
|
||||
PlainObject m_result;
|
||||
};
|
||||
|
||||
// For the other three subcases, simply call the evalTo() method of GeneralProduct
|
||||
// TODO: GeneralProduct should take evaluators, not expression objects.
|
||||
|
||||
template<typename Lhs, typename Rhs, int ProductType>
|
||||
struct product_evaluator_traits_dispatcher<Product<Lhs, Rhs>, GeneralProduct<Lhs, Rhs, ProductType> >
|
||||
{
|
||||
static const int HasEvalTo = 1;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, int ProductType>
|
||||
struct product_evaluator_dispatcher<Product<Lhs, Rhs>, GeneralProduct<Lhs, Rhs, ProductType> >
|
||||
{
|
||||
typedef Product<Lhs, Rhs> XprType;
|
||||
typedef typename XprType::PlainObject PlainObject;
|
||||
typedef typename evaluator<PlainObject>::type evaluator_base;
|
||||
|
||||
product_evaluator_dispatcher(const XprType& xpr) : m_xpr(xpr)
|
||||
{ }
|
||||
|
||||
template<typename DstEvaluatorType, typename DstXprType>
|
||||
void evalTo(DstEvaluatorType /* not used */, DstXprType& dst)
|
||||
{
|
||||
dst.resize(m_xpr.rows(), m_xpr.cols());
|
||||
GeneralProduct<Lhs, Rhs, ProductType>(m_xpr.lhs(), m_xpr.rhs()).evalTo(dst);
|
||||
}
|
||||
|
||||
protected:
|
||||
const XprType& m_xpr;
|
||||
};
|
||||
|
||||
// Case 2: Evaluate coeff by coeff
|
||||
//
|
||||
// This is mostly taken from CoeffBasedProduct.h
|
||||
// The main difference is that we add an extra argument to the etor_product_*_impl::run() function
|
||||
// for the inner dimension of the product, because evaluator object do not know their size.
|
||||
|
||||
template<int Traversal, int UnrollingIndex, typename Lhs, typename Rhs, typename RetScalar>
|
||||
struct etor_product_coeff_impl;
|
||||
|
||||
template<int StorageOrder, int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||
struct etor_product_packet_impl;
|
||||
|
||||
template<typename Lhs, typename Rhs, typename LhsNested, typename RhsNested, int Flags>
|
||||
struct product_evaluator_traits_dispatcher<Product<Lhs, Rhs>, CoeffBasedProduct<LhsNested, RhsNested, Flags> >
|
||||
{
|
||||
static const int HasEvalTo = 0;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename LhsNested, typename RhsNested, int Flags>
|
||||
struct product_evaluator_dispatcher<Product<Lhs, Rhs>, CoeffBasedProduct<LhsNested, RhsNested, Flags> >
|
||||
: evaluator_impl_base<Product<Lhs, Rhs> >
|
||||
{
|
||||
typedef Product<Lhs, Rhs> XprType;
|
||||
typedef CoeffBasedProduct<LhsNested, RhsNested, Flags> CoeffBasedProductType;
|
||||
|
||||
product_evaluator_dispatcher(const XprType& xpr)
|
||||
: m_lhsImpl(xpr.lhs()),
|
||||
m_rhsImpl(xpr.rhs()),
|
||||
m_innerDim(xpr.lhs().cols())
|
||||
{ }
|
||||
|
||||
typedef typename XprType::Index Index;
|
||||
typedef typename XprType::Scalar Scalar;
|
||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||
typedef typename XprType::PacketScalar PacketScalar;
|
||||
typedef typename XprType::PacketReturnType PacketReturnType;
|
||||
|
||||
// Everything below here is taken from CoeffBasedProduct.h
|
||||
|
||||
enum {
|
||||
RowsAtCompileTime = traits<CoeffBasedProductType>::RowsAtCompileTime,
|
||||
PacketSize = packet_traits<Scalar>::size,
|
||||
InnerSize = traits<CoeffBasedProductType>::InnerSize,
|
||||
CoeffReadCost = traits<CoeffBasedProductType>::CoeffReadCost,
|
||||
Unroll = CoeffReadCost != Dynamic && CoeffReadCost <= EIGEN_UNROLLING_LIMIT,
|
||||
CanVectorizeInner = traits<CoeffBasedProductType>::CanVectorizeInner
|
||||
};
|
||||
|
||||
typedef typename evaluator<Lhs>::type LhsEtorType;
|
||||
typedef typename evaluator<Rhs>::type RhsEtorType;
|
||||
typedef etor_product_coeff_impl<CanVectorizeInner ? InnerVectorizedTraversal : DefaultTraversal,
|
||||
Unroll ? InnerSize-1 : Dynamic,
|
||||
LhsEtorType, RhsEtorType, Scalar> CoeffImpl;
|
||||
|
||||
const CoeffReturnType coeff(Index row, Index col) const
|
||||
{
|
||||
Scalar res;
|
||||
CoeffImpl::run(row, col, m_lhsImpl, m_rhsImpl, m_innerDim, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Allow index-based non-packet access. It is impossible though to allow index-based packed access,
|
||||
* which is why we don't set the LinearAccessBit.
|
||||
*/
|
||||
const CoeffReturnType coeff(Index index) const
|
||||
{
|
||||
Scalar res;
|
||||
const Index row = RowsAtCompileTime == 1 ? 0 : index;
|
||||
const Index col = RowsAtCompileTime == 1 ? index : 0;
|
||||
CoeffImpl::run(row, col, m_lhsImpl, m_rhsImpl, m_innerDim, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
const PacketReturnType packet(Index row, Index col) const
|
||||
{
|
||||
PacketScalar res;
|
||||
typedef etor_product_packet_impl<Flags&RowMajorBit ? RowMajor : ColMajor,
|
||||
Unroll ? InnerSize-1 : Dynamic,
|
||||
LhsEtorType, RhsEtorType, PacketScalar, LoadMode> PacketImpl;
|
||||
PacketImpl::run(row, col, m_lhsImpl, m_rhsImpl, m_innerDim, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
protected:
|
||||
typename evaluator<Lhs>::type m_lhsImpl;
|
||||
typename evaluator<Rhs>::type m_rhsImpl;
|
||||
|
||||
// TODO: Get rid of m_innerDim if known at compile time
|
||||
Index m_innerDim;
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
* Normal product .coeff() implementation (with meta-unrolling)
|
||||
***************************************************************************/
|
||||
|
||||
/**************************************
|
||||
*** Scalar path - no vectorization ***
|
||||
**************************************/
|
||||
|
||||
template<int UnrollingIndex, typename Lhs, typename Rhs, typename RetScalar>
|
||||
struct etor_product_coeff_impl<DefaultTraversal, UnrollingIndex, Lhs, Rhs, RetScalar>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, RetScalar &res)
|
||||
{
|
||||
etor_product_coeff_impl<DefaultTraversal, UnrollingIndex-1, Lhs, Rhs, RetScalar>::run(row, col, lhs, rhs, innerDim, res);
|
||||
res += lhs.coeff(row, UnrollingIndex) * rhs.coeff(UnrollingIndex, col);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename RetScalar>
|
||||
struct etor_product_coeff_impl<DefaultTraversal, 0, Lhs, Rhs, RetScalar>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, RetScalar &res)
|
||||
{
|
||||
res = lhs.coeff(row, 0) * rhs.coeff(0, col);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename RetScalar>
|
||||
struct etor_product_coeff_impl<DefaultTraversal, Dynamic, Lhs, Rhs, RetScalar>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, RetScalar& res)
|
||||
{
|
||||
eigen_assert(innerDim>0 && "you are using a non initialized matrix");
|
||||
res = lhs.coeff(row, 0) * rhs.coeff(0, col);
|
||||
for(Index i = 1; i < innerDim; ++i)
|
||||
res += lhs.coeff(row, i) * rhs.coeff(i, col);
|
||||
}
|
||||
};
|
||||
|
||||
/*******************************************
|
||||
*** Scalar path with inner vectorization ***
|
||||
*******************************************/
|
||||
|
||||
template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet>
|
||||
struct etor_product_coeff_vectorized_unroller
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
enum { PacketSize = packet_traits<typename Lhs::Scalar>::size };
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, typename Lhs::PacketScalar &pres)
|
||||
{
|
||||
etor_product_coeff_vectorized_unroller<UnrollingIndex-PacketSize, Lhs, Rhs, Packet>::run(row, col, lhs, rhs, innerDim, pres);
|
||||
pres = padd(pres, pmul( lhs.template packet<Aligned>(row, UnrollingIndex) , rhs.template packet<Aligned>(UnrollingIndex, col) ));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename Packet>
|
||||
struct etor_product_coeff_vectorized_unroller<0, Lhs, Rhs, Packet>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, typename Lhs::PacketScalar &pres)
|
||||
{
|
||||
pres = pmul(lhs.template packet<Aligned>(row, 0) , rhs.template packet<Aligned>(0, col));
|
||||
}
|
||||
};
|
||||
|
||||
template<int UnrollingIndex, typename Lhs, typename Rhs, typename RetScalar>
|
||||
struct etor_product_coeff_impl<InnerVectorizedTraversal, UnrollingIndex, Lhs, Rhs, RetScalar>
|
||||
{
|
||||
typedef typename Lhs::PacketScalar Packet;
|
||||
typedef typename Lhs::Index Index;
|
||||
enum { PacketSize = packet_traits<typename Lhs::Scalar>::size };
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, RetScalar &res)
|
||||
{
|
||||
Packet pres;
|
||||
etor_product_coeff_vectorized_unroller<UnrollingIndex+1-PacketSize, Lhs, Rhs, Packet>::run(row, col, lhs, rhs, innerDim, pres);
|
||||
etor_product_coeff_impl<DefaultTraversal,UnrollingIndex,Lhs,Rhs,RetScalar>::run(row, col, lhs, rhs, innerDim, res);
|
||||
res = predux(pres);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, int LhsRows = Lhs::RowsAtCompileTime, int RhsCols = Rhs::ColsAtCompileTime>
|
||||
struct etor_product_coeff_vectorized_dyn_selector
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, typename Lhs::Scalar &res)
|
||||
{
|
||||
res = lhs.row(row).transpose().cwiseProduct(rhs.col(col)).sum();
|
||||
}
|
||||
};
|
||||
|
||||
// NOTE the 3 following specializations are because taking .col(0) on a vector is a bit slower
|
||||
// NOTE maybe they are now useless since we have a specialization for Block<Matrix>
|
||||
template<typename Lhs, typename Rhs, int RhsCols>
|
||||
struct etor_product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,RhsCols>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index /*row*/, Index col, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, typename Lhs::Scalar &res)
|
||||
{
|
||||
res = lhs.transpose().cwiseProduct(rhs.col(col)).sum();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, int LhsRows>
|
||||
struct etor_product_coeff_vectorized_dyn_selector<Lhs,Rhs,LhsRows,1>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index /*col*/, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, typename Lhs::Scalar &res)
|
||||
{
|
||||
res = lhs.row(row).transpose().cwiseProduct(rhs).sum();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct etor_product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,1>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, typename Lhs::Scalar &res)
|
||||
{
|
||||
res = lhs.transpose().cwiseProduct(rhs).sum();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename RetScalar>
|
||||
struct etor_product_coeff_impl<InnerVectorizedTraversal, Dynamic, Lhs, Rhs, RetScalar>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, typename Lhs::Scalar &res)
|
||||
{
|
||||
etor_product_coeff_vectorized_dyn_selector<Lhs,Rhs>::run(row, col, lhs, rhs, innerDim, res);
|
||||
}
|
||||
};
|
||||
|
||||
/*******************
|
||||
*** Packet path ***
|
||||
*******************/
|
||||
|
||||
template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||
struct etor_product_packet_impl<RowMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet &res)
|
||||
{
|
||||
etor_product_packet_impl<RowMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, innerDim, res);
|
||||
res = pmadd(pset1<Packet>(lhs.coeff(row, UnrollingIndex)), rhs.template packet<LoadMode>(UnrollingIndex, col), res);
|
||||
}
|
||||
};
|
||||
|
||||
template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||
struct etor_product_packet_impl<ColMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet &res)
|
||||
{
|
||||
etor_product_packet_impl<ColMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, innerDim, res);
|
||||
res = pmadd(lhs.template packet<LoadMode>(row, UnrollingIndex), pset1<Packet>(rhs.coeff(UnrollingIndex, col)), res);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||
struct etor_product_packet_impl<RowMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, Packet &res)
|
||||
{
|
||||
res = pmul(pset1<Packet>(lhs.coeff(row, 0)),rhs.template packet<LoadMode>(0, col));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||
struct etor_product_packet_impl<ColMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, Packet &res)
|
||||
{
|
||||
res = pmul(lhs.template packet<LoadMode>(row, 0), pset1<Packet>(rhs.coeff(0, col)));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||
struct etor_product_packet_impl<RowMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet& res)
|
||||
{
|
||||
eigen_assert(innerDim>0 && "you are using a non initialized matrix");
|
||||
res = pmul(pset1<Packet>(lhs.coeff(row, 0)),rhs.template packet<LoadMode>(0, col));
|
||||
for(Index i = 1; i < innerDim; ++i)
|
||||
res = pmadd(pset1<Packet>(lhs.coeff(row, i)), rhs.template packet<LoadMode>(i, col), res);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||
struct etor_product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet& res)
|
||||
{
|
||||
eigen_assert(innerDim>0 && "you are using a non initialized matrix");
|
||||
res = pmul(lhs.template packet<LoadMode>(row, 0), pset1<Packet>(rhs.coeff(0, col)));
|
||||
for(Index i = 1; i < innerDim; ++i)
|
||||
res = pmadd(lhs.template packet<LoadMode>(row, i), pset1<Packet>(rhs.coeff(i, col)), res);
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_PRODUCT_EVALUATORS_H
|
||||
@@ -330,7 +330,8 @@ DenseBase<Derived>::redux(const Func& func) const
|
||||
::run(derived(), func);
|
||||
}
|
||||
|
||||
/** \returns the minimum of all coefficients of *this
|
||||
/** \returns the minimum of all coefficients of \c *this.
|
||||
* \warning the result is undefined if \c *this contains NaN.
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
||||
@@ -339,7 +340,8 @@ DenseBase<Derived>::minCoeff() const
|
||||
return this->redux(Eigen::internal::scalar_min_op<Scalar>());
|
||||
}
|
||||
|
||||
/** \returns the maximum of all coefficients of *this
|
||||
/** \returns the maximum of all coefficients of \c *this.
|
||||
* \warning the result is undefined if \c *this contains NaN.
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -136,7 +136,7 @@ template<typename Derived>
|
||||
template<typename ThenDerived>
|
||||
inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
|
||||
DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
||||
typename ThenDerived::Scalar elseScalar) const
|
||||
const typename ThenDerived::Scalar& elseScalar) const
|
||||
{
|
||||
return Select<Derived,ThenDerived,typename ThenDerived::ConstantReturnType>(
|
||||
derived(), thenMatrix.derived(), ThenDerived::Constant(rows(),cols(),elseScalar));
|
||||
@@ -150,8 +150,8 @@ DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
||||
template<typename Derived>
|
||||
template<typename ElseDerived>
|
||||
inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
|
||||
DenseBase<Derived>::select(typename ElseDerived::Scalar thenScalar,
|
||||
const DenseBase<ElseDerived>& elseMatrix) const
|
||||
DenseBase<Derived>::select(const typename ElseDerived::Scalar& thenScalar,
|
||||
const DenseBase<ElseDerived>& elseMatrix) const
|
||||
{
|
||||
return Select<Derived,typename ElseDerived::ConstantReturnType,ElseDerived>(
|
||||
derived(), ElseDerived::Constant(rows(),cols(),thenScalar), elseMatrix.derived());
|
||||
|
||||
@@ -132,7 +132,7 @@ template<typename MatrixType, unsigned int UpLo> class SelfAdjointView
|
||||
* \sa rankUpdate(const MatrixBase<DerivedU>&, Scalar)
|
||||
*/
|
||||
template<typename DerivedU, typename DerivedV>
|
||||
SelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, const MatrixBase<DerivedV>& v, Scalar alpha = Scalar(1));
|
||||
SelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, const MatrixBase<DerivedV>& v, const Scalar& alpha = Scalar(1));
|
||||
|
||||
/** Perform a symmetric rank K update of the selfadjoint matrix \c *this:
|
||||
* \f$ this = this + \alpha ( u u^* ) \f$ where \a u is a vector or matrix.
|
||||
@@ -145,7 +145,7 @@ template<typename MatrixType, unsigned int UpLo> class SelfAdjointView
|
||||
* \sa rankUpdate(const MatrixBase<DerivedU>&, const MatrixBase<DerivedV>&, Scalar)
|
||||
*/
|
||||
template<typename DerivedU>
|
||||
SelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, Scalar alpha = Scalar(1));
|
||||
SelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, const Scalar& alpha = Scalar(1));
|
||||
|
||||
/////////// Cholesky module ///////////
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -13,13 +13,14 @@
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename ExpressionType, typename Scalar>
|
||||
inline void stable_norm_kernel(const ExpressionType& bl, Scalar& ssq, Scalar& scale, Scalar& invScale)
|
||||
{
|
||||
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;
|
||||
}
|
||||
@@ -32,7 +33,6 @@ template<typename Derived>
|
||||
inline typename NumTraits<typename traits<Derived>::Scalar>::Real
|
||||
blueNorm_impl(const EigenBase<Derived>& _vec)
|
||||
{
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
typedef typename Derived::RealScalar RealScalar;
|
||||
typedef typename Derived::Index Index;
|
||||
using std::pow;
|
||||
@@ -41,43 +41,40 @@ blueNorm_impl(const EigenBase<Derived>& _vec)
|
||||
using std::sqrt;
|
||||
using std::abs;
|
||||
const Derived& vec(_vec.derived());
|
||||
static Index nmax = -1;
|
||||
static bool initialized = false;
|
||||
static RealScalar b1, b2, s1m, s2m, overfl, rbig, relerr;
|
||||
if(nmax <= 0)
|
||||
if(!initialized)
|
||||
{
|
||||
int nbig, ibeta, it, iemin, iemax, iexp;
|
||||
RealScalar abig, eps;
|
||||
int ibeta, it, iemin, iemax, iexp;
|
||||
RealScalar eps;
|
||||
// This program calculates the machine-dependent constants
|
||||
// bl, b2, slm, s2m, relerr overfl, nmax
|
||||
// bl, b2, slm, s2m, relerr overfl
|
||||
// from the "basic" machine-dependent numbers
|
||||
// nbig, ibeta, it, iemin, iemax, rbig.
|
||||
// The following define the basic machine-dependent constants.
|
||||
// For portability, the PORT subprograms "ilmaeh" and "rlmach"
|
||||
// are used. For any specific computer, each of the assignment
|
||||
// statements can be replaced
|
||||
nbig = (std::numeric_limits<Index>::max)(); // largest integer
|
||||
ibeta = std::numeric_limits<RealScalar>::radix; // base for floating-point numbers
|
||||
it = std::numeric_limits<RealScalar>::digits; // number of base-beta digits in mantissa
|
||||
iemin = std::numeric_limits<RealScalar>::min_exponent; // minimum exponent
|
||||
iemax = std::numeric_limits<RealScalar>::max_exponent; // maximum exponent
|
||||
rbig = (std::numeric_limits<RealScalar>::max)(); // largest floating-point number
|
||||
ibeta = std::numeric_limits<RealScalar>::radix; // base for floating-point numbers
|
||||
it = std::numeric_limits<RealScalar>::digits; // number of base-beta digits in mantissa
|
||||
iemin = std::numeric_limits<RealScalar>::min_exponent; // minimum exponent
|
||||
iemax = std::numeric_limits<RealScalar>::max_exponent; // maximum exponent
|
||||
rbig = (std::numeric_limits<RealScalar>::max)(); // largest floating-point number
|
||||
|
||||
iexp = -((1-iemin)/2);
|
||||
b1 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // lower boundary of midrange
|
||||
b1 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // lower boundary of midrange
|
||||
iexp = (iemax + 1 - it)/2;
|
||||
b2 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // upper boundary of midrange
|
||||
b2 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // upper boundary of midrange
|
||||
|
||||
iexp = (2-iemin)/2;
|
||||
s1m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for lower range
|
||||
s1m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for lower range
|
||||
iexp = - ((iemax+it)/2);
|
||||
s2m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for upper range
|
||||
s2m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for upper range
|
||||
|
||||
overfl = rbig*s2m; // overflow boundary for abig
|
||||
overfl = rbig*s2m; // overflow boundary for abig
|
||||
eps = RealScalar(pow(double(ibeta), 1-it));
|
||||
relerr = sqrt(eps); // tolerance for neglecting asml
|
||||
abig = RealScalar(1.0/eps - 1.0);
|
||||
if (RealScalar(nbig)>abig) nmax = int(abig); // largest safe n
|
||||
else nmax = nbig;
|
||||
relerr = sqrt(eps); // tolerance for neglecting asml
|
||||
initialized = true;
|
||||
}
|
||||
Index n = vec.size();
|
||||
RealScalar ab2 = b2 / RealScalar(n);
|
||||
@@ -87,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))
|
||||
{
|
||||
@@ -123,8 +120,9 @@ 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
|
||||
|
||||
/** \returns the \em l2 norm of \c *this avoiding underflow and overflow.
|
||||
|
||||
@@ -104,6 +104,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)
|
||||
|
||||
inline Index innerStride() const { return derived().nestedExpression().innerStride(); }
|
||||
inline Index outerStride() const { return derived().nestedExpression().outerStride(); }
|
||||
@@ -206,7 +207,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());
|
||||
@@ -252,7 +253,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());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -260,7 +261,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();
|
||||
}
|
||||
@@ -387,7 +388,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()");
|
||||
|
||||
}
|
||||
|
||||
@@ -233,6 +233,28 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
Direction==Vertical ? 1 : m_matrix.rows(),
|
||||
Direction==Horizontal ? 1 : m_matrix.cols());
|
||||
}
|
||||
|
||||
template<typename OtherDerived> struct OppositeExtendedType {
|
||||
typedef Replicate<OtherDerived,
|
||||
Direction==Horizontal ? 1 : ExpressionType::RowsAtCompileTime,
|
||||
Direction==Vertical ? 1 : ExpressionType::ColsAtCompileTime> Type;
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* Replicates a vector in the opposite direction to match the size of \c *this */
|
||||
template<typename OtherDerived>
|
||||
typename OppositeExtendedType<OtherDerived>::Type
|
||||
extendedToOpposite(const DenseBase<OtherDerived>& other) const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Horizontal, OtherDerived::MaxColsAtCompileTime==1),
|
||||
YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED)
|
||||
EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Vertical, OtherDerived::MaxRowsAtCompileTime==1),
|
||||
YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED)
|
||||
return typename OppositeExtendedType<OtherDerived>::Type
|
||||
(other.derived(),
|
||||
Direction==Horizontal ? 1 : m_matrix.rows(),
|
||||
Direction==Vertical ? 1 : m_matrix.cols());
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
@@ -255,6 +277,8 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
|
||||
/** \returns a row (or column) vector expression of the smallest coefficient
|
||||
* of each column (or row) of the referenced expression.
|
||||
*
|
||||
* \warning the result is undefined if \c *this contains NaN.
|
||||
*
|
||||
* Example: \include PartialRedux_minCoeff.cpp
|
||||
* Output: \verbinclude PartialRedux_minCoeff.out
|
||||
@@ -265,6 +289,8 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
|
||||
/** \returns a row (or column) vector expression of the largest coefficient
|
||||
* of each column (or row) of the referenced expression.
|
||||
*
|
||||
* \warning the result is undefined if \c *this contains NaN.
|
||||
*
|
||||
* Example: \include PartialRedux_maxCoeff.cpp
|
||||
* Output: \verbinclude PartialRedux_maxCoeff.out
|
||||
@@ -504,6 +530,23 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
|
||||
return m_matrix / extendedTo(other.derived());
|
||||
}
|
||||
|
||||
/** \returns an expression where each column of row of the referenced matrix are normalized.
|
||||
* The referenced matrix is \b not modified.
|
||||
* \sa MatrixBase::normalized(), normalize()
|
||||
*/
|
||||
CwiseBinaryOp<internal::scalar_quotient_op<Scalar>,
|
||||
const ExpressionTypeNestedCleaned,
|
||||
const typename OppositeExtendedType<typename ReturnType<internal::member_norm,RealScalar>::Type>::Type>
|
||||
normalized() const { return m_matrix.cwiseQuotient(extendedToOpposite(this->norm())); }
|
||||
|
||||
|
||||
/** Normalize in-place each row or columns of the referenced matrix.
|
||||
* \sa MatrixBase::normalize(), normalized()
|
||||
*/
|
||||
void normalize() {
|
||||
m_matrix = this->normalized();
|
||||
}
|
||||
|
||||
/////////// Geometry module ///////////
|
||||
|
||||
|
||||
@@ -164,8 +164,8 @@ struct functor_traits<max_coeff_visitor<Scalar> > {
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
/** \returns the minimum of all coefficients of *this
|
||||
* and puts in *row and *col its location.
|
||||
/** \returns the minimum of all coefficients of *this and puts in *row and *col its location.
|
||||
* \warning the result is undefined if \c *this contains NaN.
|
||||
*
|
||||
* \sa DenseBase::minCoeff(Index*), DenseBase::maxCoeff(Index*,Index*), DenseBase::visitor(), DenseBase::minCoeff()
|
||||
*/
|
||||
@@ -181,8 +181,8 @@ DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
|
||||
return minVisitor.res;
|
||||
}
|
||||
|
||||
/** \returns the minimum of all coefficients of *this
|
||||
* and puts in *index its location.
|
||||
/** \returns the minimum of all coefficients of *this and puts in *index its location.
|
||||
* \warning the result is undefined if \c *this contains NaN.
|
||||
*
|
||||
* \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::minCoeff()
|
||||
*/
|
||||
@@ -198,8 +198,8 @@ DenseBase<Derived>::minCoeff(IndexType* index) const
|
||||
return minVisitor.res;
|
||||
}
|
||||
|
||||
/** \returns the maximum of all coefficients of *this
|
||||
* and puts in *row and *col its location.
|
||||
/** \returns the maximum of all coefficients of *this and puts in *row and *col its location.
|
||||
* \warning the result is undefined if \c *this contains NaN.
|
||||
*
|
||||
* \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::maxCoeff()
|
||||
*/
|
||||
@@ -215,8 +215,8 @@ DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const
|
||||
return maxVisitor.res;
|
||||
}
|
||||
|
||||
/** \returns the maximum of all coefficients of *this
|
||||
* and puts in *index its location.
|
||||
/** \returns the maximum of all coefficients of *this and puts in *index its location.
|
||||
* \warning the result is undefined if \c *this contains NaN.
|
||||
*
|
||||
* \sa DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::maxCoeff()
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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); }
|
||||
|
||||
|
||||
@@ -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))));
|
||||
|
||||
@@ -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)
|
||||
@@ -173,18 +177,26 @@ template<> EIGEN_STRONG_INLINE Packet4f pmin<Packet4f>(const Packet4f& a, const
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pmin<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_min_pd(a,b); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4i pmin<Packet4i>(const Packet4i& a, const Packet4i& b)
|
||||
{
|
||||
#ifdef EIGEN_VECTORIZE_SSE4_1
|
||||
return _mm_min_epi32(a,b);
|
||||
#else
|
||||
// after some bench, this version *is* faster than a scalar implementation
|
||||
Packet4i mask = _mm_cmplt_epi32(a,b);
|
||||
return _mm_or_si128(_mm_and_si128(mask,a),_mm_andnot_si128(mask,b));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pmax<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_max_ps(a,b); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2d pmax<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_max_pd(a,b); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4i pmax<Packet4i>(const Packet4i& a, const Packet4i& b)
|
||||
{
|
||||
#ifdef EIGEN_VECTORIZE_SSE4_1
|
||||
return _mm_max_epi32(a,b);
|
||||
#else
|
||||
// after some bench, this version *is* faster than a scalar implementation
|
||||
Packet4i mask = _mm_cmpgt_epi32(a,b);
|
||||
return _mm_or_si128(_mm_and_si128(mask,a),_mm_andnot_si128(mask,b));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f pand<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_and_ps(a,b); }
|
||||
|
||||
@@ -150,7 +150,7 @@ class CoeffBasedProduct
|
||||
{
|
||||
// we don't allow taking products of matrices of different real types, as that wouldn't be vectorizable.
|
||||
// We still allow to mix T and complex<T>.
|
||||
EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::RealScalar, typename Rhs::RealScalar>::value),
|
||||
EIGEN_STATIC_ASSERT((internal::scalar_product_traits<typename Lhs::RealScalar, typename Rhs::RealScalar>::Defined),
|
||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||
eigen_assert(lhs.cols() == rhs.rows()
|
||||
&& "invalid matrix product"
|
||||
|
||||
@@ -238,7 +238,6 @@ struct general_product_to_triangular_selector<MatrixType,ProductType,UpLo,false>
|
||||
{
|
||||
static void run(MatrixType& mat, const ProductType& prod, const typename MatrixType::Scalar& alpha)
|
||||
{
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::Index Index;
|
||||
|
||||
typedef typename internal::remove_all<typename ProductType::LhsNested>::type Lhs;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -44,7 +44,6 @@ EIGEN_DONT_INLINE void selfadjoint_matrix_vector_product<Scalar,Index,StorageOrd
|
||||
Scalar alpha)
|
||||
{
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
const Index PacketSize = sizeof(Packet)/sizeof(Scalar);
|
||||
|
||||
enum {
|
||||
@@ -60,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,
|
||||
@@ -99,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);
|
||||
@@ -115,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.
|
||||
@@ -153,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);
|
||||
|
||||
@@ -111,7 +111,7 @@ struct selfadjoint_product_selector<MatrixType,OtherType,UpLo,false>
|
||||
template<typename MatrixType, unsigned int UpLo>
|
||||
template<typename DerivedU>
|
||||
SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo>
|
||||
::rankUpdate(const MatrixBase<DerivedU>& u, Scalar alpha)
|
||||
::rankUpdate(const MatrixBase<DerivedU>& u, const Scalar& alpha)
|
||||
{
|
||||
selfadjoint_product_selector<MatrixType,DerivedU,UpLo>::run(_expression().const_cast_derived(), u.derived(), alpha);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -58,7 +58,7 @@ template<bool Cond, typename T> struct conj_expr_if
|
||||
template<typename MatrixType, unsigned int UpLo>
|
||||
template<typename DerivedU, typename DerivedV>
|
||||
SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo>
|
||||
::rankUpdate(const MatrixBase<DerivedU>& u, const MatrixBase<DerivedV>& v, Scalar alpha)
|
||||
::rankUpdate(const MatrixBase<DerivedU>& u, const MatrixBase<DerivedV>& v, const Scalar& alpha)
|
||||
{
|
||||
typedef internal::blas_traits<DerivedU> UBlasTraits;
|
||||
typedef typename UBlasTraits::DirectLinearAccessType ActualUType;
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
@@ -256,7 +256,7 @@ template<> struct trmv_selector<ColMajor>
|
||||
if(!evalToDest)
|
||||
{
|
||||
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||
int size = dest.size();
|
||||
Index size = dest.size();
|
||||
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||
#endif
|
||||
if(!alphaIsCompatible)
|
||||
|
||||
@@ -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,7 @@ template<typename From,typename To> struct get_factor {
|
||||
};
|
||||
|
||||
template<typename Scalar> struct get_factor<Scalar,typename NumTraits<Scalar>::Real> {
|
||||
static EIGEN_STRONG_INLINE typename NumTraits<Scalar>::Real run(const Scalar& x) { return real(x); }
|
||||
static EIGEN_STRONG_INLINE typename NumTraits<Scalar>::Real run(const Scalar& x) { return numext::real(x); }
|
||||
};
|
||||
|
||||
// Lightweight helper class to access matrix coefficients.
|
||||
|
||||
@@ -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 0
|
||||
|
||||
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
|
||||
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -94,11 +101,11 @@ inline void throw_std_bad_alloc()
|
||||
/** \internal Like malloc, but the returned pointer is guaranteed to be 16-byte aligned.
|
||||
* Fast, but wastes 16 additional bytes of memory. Does not throw any exception.
|
||||
*/
|
||||
inline void* handmade_aligned_malloc(size_t size)
|
||||
inline void* handmade_aligned_malloc(std::size_t size)
|
||||
{
|
||||
void *original = std::malloc(size+16);
|
||||
if (original == 0) return 0;
|
||||
void *aligned = reinterpret_cast<void*>((reinterpret_cast<size_t>(original) & ~(size_t(15))) + 16);
|
||||
void *aligned = reinterpret_cast<void*>((reinterpret_cast<std::size_t>(original) & ~(std::size_t(15))) + 16);
|
||||
*(reinterpret_cast<void**>(aligned) - 1) = original;
|
||||
return aligned;
|
||||
}
|
||||
@@ -114,13 +121,18 @@ inline void handmade_aligned_free(void *ptr)
|
||||
* Since we know that our handmade version is based on std::realloc
|
||||
* we can use std::realloc to implement efficient reallocation.
|
||||
*/
|
||||
inline void* handmade_aligned_realloc(void* ptr, size_t size, size_t = 0)
|
||||
inline void* handmade_aligned_realloc(void* ptr, std::size_t size, std::size_t = 0)
|
||||
{
|
||||
if (ptr == 0) return handmade_aligned_malloc(size);
|
||||
void *original = *(reinterpret_cast<void**>(ptr) - 1);
|
||||
std::ptrdiff_t previous_offset = static_cast<char *>(ptr)-static_cast<char *>(original);
|
||||
original = std::realloc(original,size+16);
|
||||
if (original == 0) return 0;
|
||||
void *aligned = reinterpret_cast<void*>((reinterpret_cast<size_t>(original) & ~(size_t(15))) + 16);
|
||||
void *aligned = reinterpret_cast<void*>((reinterpret_cast<std::size_t>(original) & ~(std::size_t(15))) + 16);
|
||||
void *previous_aligned = static_cast<char *>(original)+previous_offset;
|
||||
if(aligned!=previous_aligned)
|
||||
std::memmove(aligned, previous_aligned, size);
|
||||
|
||||
*(reinterpret_cast<void**>(aligned) - 1) = original;
|
||||
return aligned;
|
||||
}
|
||||
@@ -129,7 +141,7 @@ inline void* handmade_aligned_realloc(void* ptr, size_t size, size_t = 0)
|
||||
*** Implementation of generic aligned realloc (when no realloc can be used)***
|
||||
*****************************************************************************/
|
||||
|
||||
void* aligned_malloc(size_t size);
|
||||
void* aligned_malloc(std::size_t size);
|
||||
void aligned_free(void *ptr);
|
||||
|
||||
/** \internal
|
||||
@@ -210,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);
|
||||
@@ -452,7 +464,6 @@ template<typename T, bool Align> inline void conditional_aligned_delete_auto(T *
|
||||
template<typename Scalar, typename Index>
|
||||
static inline Index first_aligned(const Scalar* array, Index size)
|
||||
{
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
enum { PacketSize = packet_traits<Scalar>::size,
|
||||
PacketAlignedMask = PacketSize-1
|
||||
};
|
||||
@@ -751,11 +762,16 @@ public:
|
||||
# if defined(__PIC__) && defined(__i386__)
|
||||
// Case for x86 with PIC
|
||||
# define EIGEN_CPUID(abcd,func,id) \
|
||||
__asm__ __volatile__ ("xchgl %%ebx, %%esi;cpuid; xchgl %%ebx,%%esi": "=a" (abcd[0]), "=S" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "a" (func), "c" (id));
|
||||
__asm__ __volatile__ ("xchgl %%ebx, %k1;cpuid; xchgl %%ebx,%k1": "=a" (abcd[0]), "=&r" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "a" (func), "c" (id));
|
||||
# elif defined(__PIC__) && defined(__x86_64__)
|
||||
// Case for x64 with PIC. In theory this is only a problem with recent gcc and with medium or large code model, not with the default small code model.
|
||||
// However, we cannot detect which code model is used, and the xchg overhead is negligible anyway.
|
||||
# define EIGEN_CPUID(abcd,func,id) \
|
||||
__asm__ __volatile__ ("xchg{q}\t{%%}rbx, %q1; cpuid; xchg{q}\t{%%}rbx, %q1": "=a" (abcd[0]), "=&r" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "0" (func), "2" (id));
|
||||
# else
|
||||
// Case for x86_64 or x86 w/o PIC
|
||||
# define EIGEN_CPUID(abcd,func,id) \
|
||||
__asm__ __volatile__ ("cpuid": "=a" (abcd[0]), "=b" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "a" (func), "c" (id) );
|
||||
__asm__ __volatile__ ("cpuid": "=a" (abcd[0]), "=b" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "0" (func), "2" (id) );
|
||||
# endif
|
||||
# elif defined(_MSC_VER)
|
||||
# if (_MSC_VER > 1500) && ( defined(_M_IX86) || defined(_M_X64) )
|
||||
|
||||
@@ -186,23 +186,35 @@ template<int Y, int InfX, int SupX>
|
||||
class meta_sqrt<Y, InfX, SupX, true> { public: enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; };
|
||||
|
||||
/** \internal determines whether the product of two numeric types is allowed and what the return type is */
|
||||
template<typename T, typename U> struct scalar_product_traits;
|
||||
template<typename T, typename U> struct scalar_product_traits
|
||||
{
|
||||
enum { Defined = 0 };
|
||||
};
|
||||
|
||||
template<typename T> struct scalar_product_traits<T,T>
|
||||
{
|
||||
//enum { Cost = NumTraits<T>::MulCost };
|
||||
enum {
|
||||
// Cost = NumTraits<T>::MulCost,
|
||||
Defined = 1
|
||||
};
|
||||
typedef T ReturnType;
|
||||
};
|
||||
|
||||
template<typename T> struct scalar_product_traits<T,std::complex<T> >
|
||||
{
|
||||
//enum { Cost = 2*NumTraits<T>::MulCost };
|
||||
enum {
|
||||
// Cost = 2*NumTraits<T>::MulCost,
|
||||
Defined = 1
|
||||
};
|
||||
typedef std::complex<T> ReturnType;
|
||||
};
|
||||
|
||||
template<typename T> struct scalar_product_traits<std::complex<T>, T>
|
||||
{
|
||||
//enum { Cost = 2*NumTraits<T>::MulCost };
|
||||
enum {
|
||||
// Cost = 2*NumTraits<T>::MulCost,
|
||||
Defined = 1
|
||||
};
|
||||
typedef std::complex<T> ReturnType;
|
||||
};
|
||||
|
||||
|
||||
@@ -91,7 +91,8 @@ template<typename T> struct functor_traits
|
||||
enum
|
||||
{
|
||||
Cost = 10,
|
||||
PacketAccess = false
|
||||
PacketAccess = false,
|
||||
IsRepeatable = false
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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); }
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -364,7 +364,6 @@ struct complex_schur_reduce_to_hessenberg<MatrixType, false>
|
||||
static void run(ComplexSchur<MatrixType>& _this, const MatrixType& matrix, bool computeU)
|
||||
{
|
||||
typedef typename ComplexSchur<MatrixType>::ComplexScalar ComplexScalar;
|
||||
typedef typename ComplexSchur<MatrixType>::ComplexMatrixType ComplexMatrixType;
|
||||
|
||||
// Note: m_hess is over RealScalar; m_matT and m_matU is over ComplexScalar
|
||||
_this.m_hess.compute(matrix);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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;
|
||||
@@ -426,8 +426,6 @@ struct tridiagonalization_inplace_selector;
|
||||
template<typename MatrixType, typename DiagonalType, typename SubDiagonalType>
|
||||
void tridiagonalization_inplace(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ)
|
||||
{
|
||||
typedef typename MatrixType::Index Index;
|
||||
//Index n = mat.rows();
|
||||
eigen_assert(mat.cols()==mat.rows() && diag.size()==mat.rows() && subdiag.size()==mat.rows()-1);
|
||||
tridiagonalization_inplace_selector<MatrixType>::run(mat, diag, subdiag, extractQ);
|
||||
}
|
||||
@@ -470,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);
|
||||
@@ -482,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;
|
||||
@@ -512,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);
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -154,7 +154,7 @@ public:
|
||||
* \a t in [0;1]
|
||||
* see http://en.wikipedia.org/wiki/Slerp
|
||||
*/
|
||||
template<class OtherDerived> Quaternion<Scalar> slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const;
|
||||
template<class OtherDerived> Quaternion<Scalar> slerp(const Scalar& t, const QuaternionBase<OtherDerived>& other) const;
|
||||
|
||||
/** \returns \c true if \c *this is approximately equal to \a other, within the precision
|
||||
* determined by \a prec.
|
||||
@@ -683,7 +683,7 @@ QuaternionBase<Derived>::angularDistance(const QuaternionBase<OtherDerived>& oth
|
||||
template <class Derived>
|
||||
template <class OtherDerived>
|
||||
Quaternion<typename internal::traits<Derived>::Scalar>
|
||||
QuaternionBase<Derived>::slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const
|
||||
QuaternionBase<Derived>::slerp(const Scalar& t, const QuaternionBase<OtherDerived>& other) const
|
||||
{
|
||||
using std::acos;
|
||||
using std::sin;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -43,7 +43,13 @@ bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x,
|
||||
VectorType r = rhs - mat * x;
|
||||
VectorType r0 = r;
|
||||
|
||||
RealScalar r0_sqnorm = rhs.squaredNorm();
|
||||
RealScalar r0_sqnorm = r0.squaredNorm();
|
||||
RealScalar rhs_sqnorm = rhs.squaredNorm();
|
||||
if(rhs_sqnorm == 0)
|
||||
{
|
||||
x.setZero();
|
||||
return true;
|
||||
}
|
||||
Scalar rho = 1;
|
||||
Scalar alpha = 1;
|
||||
Scalar w = 1;
|
||||
@@ -56,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);
|
||||
|
||||
@@ -76,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;
|
||||
}
|
||||
|
||||
@@ -41,15 +41,29 @@ void conjugate_gradient(const MatrixType& mat, const Rhs& rhs, Dest& x,
|
||||
int n = mat.cols();
|
||||
|
||||
VectorType residual = rhs - mat * x; //initial residual
|
||||
VectorType p(n);
|
||||
|
||||
RealScalar rhsNorm2 = rhs.squaredNorm();
|
||||
if(rhsNorm2 == 0)
|
||||
{
|
||||
x.setZero();
|
||||
iters = 0;
|
||||
tol_error = 0;
|
||||
return;
|
||||
}
|
||||
RealScalar threshold = tol*tol*rhsNorm2;
|
||||
RealScalar residualNorm2 = residual.squaredNorm();
|
||||
if (residualNorm2 < threshold)
|
||||
{
|
||||
iters = 0;
|
||||
tol_error = sqrt(residualNorm2 / rhsNorm2);
|
||||
return;
|
||||
}
|
||||
|
||||
VectorType p(n);
|
||||
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 rhsNorm2 = rhs.squaredNorm();
|
||||
RealScalar residualNorm2 = 0;
|
||||
RealScalar threshold = tol*tol*rhsNorm2;
|
||||
RealScalar absNew = numext::real(residual.dot(p)); // the square of the absolute value of r scaled by invM
|
||||
int i = 0;
|
||||
while(i < maxIters)
|
||||
{
|
||||
@@ -66,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++;
|
||||
|
||||
@@ -24,14 +24,15 @@ namespace internal {
|
||||
* \param ind The array of index for the elements in @p row
|
||||
* \param ncut The number of largest elements to keep
|
||||
**/
|
||||
template <typename VectorV, typename VectorI>
|
||||
int QuickSplit(VectorV &row, VectorI &ind, int ncut)
|
||||
template <typename VectorV, typename VectorI, typename Index>
|
||||
Index QuickSplit(VectorV &row, VectorI &ind, Index ncut)
|
||||
{
|
||||
typedef typename VectorV::RealScalar RealScalar;
|
||||
using std::swap;
|
||||
int mid;
|
||||
int n = row.size(); /* length of the vector */
|
||||
int first, last ;
|
||||
using std::abs;
|
||||
Index mid;
|
||||
Index n = row.size(); /* length of the vector */
|
||||
Index first, last ;
|
||||
|
||||
ncut--; /* to fit the zero-based indices */
|
||||
first = 0;
|
||||
@@ -40,9 +41,9 @@ int QuickSplit(VectorV &row, VectorI &ind, int ncut)
|
||||
|
||||
do {
|
||||
mid = first;
|
||||
RealScalar abskey = std::abs(row(mid));
|
||||
for (int j = first + 1; j <= last; j++) {
|
||||
if ( std::abs(row(j)) > abskey) {
|
||||
RealScalar abskey = abs(row(mid));
|
||||
for (Index j = first + 1; j <= last; j++) {
|
||||
if ( abs(row(j)) > abskey) {
|
||||
++mid;
|
||||
swap(row(mid), row(j));
|
||||
swap(ind(mid), ind(j));
|
||||
@@ -149,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;
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
|
||||
using std::abs;
|
||||
|
||||
eigen_assert((amat.rows() == amat.cols()) && "The factorization should be done on a square matrix");
|
||||
int n = amat.cols(); // Size of the matrix
|
||||
Index n = amat.cols(); // Size of the matrix
|
||||
m_lu.resize(n,n);
|
||||
// Declare Working vectors and variables
|
||||
Vector u(n) ; // real values of the row -- maximum size is n --
|
||||
@@ -264,21 +264,21 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
|
||||
u.fill(0);
|
||||
|
||||
// number of largest elements to keep in each row:
|
||||
int fill_in = static_cast<int> (amat.nonZeros()*m_fillfactor)/n+1;
|
||||
Index fill_in = static_cast<Index> (amat.nonZeros()*m_fillfactor)/n+1;
|
||||
if (fill_in > n) fill_in = n;
|
||||
|
||||
// number of largest nonzero elements to keep in the L and the U part of the current row:
|
||||
int nnzL = fill_in/2;
|
||||
int nnzU = nnzL;
|
||||
Index nnzL = fill_in/2;
|
||||
Index nnzU = nnzL;
|
||||
m_lu.reserve(n * (nnzL + nnzU + 1));
|
||||
|
||||
// global loop over the rows of the sparse matrix
|
||||
for (int ii = 0; ii < n; ii++)
|
||||
for (Index ii = 0; ii < n; ii++)
|
||||
{
|
||||
// 1 - copy the lower and the upper part of the row i of mat in the working vector u
|
||||
|
||||
int sizeu = 1; // number of nonzero elements in the upper part of the current row
|
||||
int sizel = 0; // number of nonzero elements in the lower part of the current row
|
||||
Index sizeu = 1; // number of nonzero elements in the upper part of the current row
|
||||
Index sizel = 0; // number of nonzero elements in the lower part of the current row
|
||||
ju(ii) = ii;
|
||||
u(ii) = 0;
|
||||
jr(ii) = ii;
|
||||
@@ -287,7 +287,7 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
|
||||
typename FactorType::InnerIterator j_it(mat, ii); // Iterate through the current row ii
|
||||
for (; j_it; ++j_it)
|
||||
{
|
||||
int k = j_it.index();
|
||||
Index k = j_it.index();
|
||||
if (k < ii)
|
||||
{
|
||||
// copy the lower part
|
||||
@@ -303,13 +303,13 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
|
||||
else
|
||||
{
|
||||
// copy the upper part
|
||||
int jpos = ii + sizeu;
|
||||
Index jpos = ii + sizeu;
|
||||
ju(jpos) = k;
|
||||
u(jpos) = j_it.value();
|
||||
jr(k) = jpos;
|
||||
++sizeu;
|
||||
}
|
||||
rownorm += internal::abs2(j_it.value());
|
||||
rownorm += numext::abs2(j_it.value());
|
||||
}
|
||||
|
||||
// 2 - detect possible zero row
|
||||
@@ -322,19 +322,19 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
|
||||
rownorm = sqrt(rownorm);
|
||||
|
||||
// 3 - eliminate the previous nonzero rows
|
||||
int jj = 0;
|
||||
int len = 0;
|
||||
Index jj = 0;
|
||||
Index len = 0;
|
||||
while (jj < sizel)
|
||||
{
|
||||
// In order to eliminate in the correct order,
|
||||
// we must select first the smallest column index among ju(jj:sizel)
|
||||
int k;
|
||||
int minrow = ju.segment(jj,sizel-jj).minCoeff(&k); // k is relative to the segment
|
||||
Index k;
|
||||
Index minrow = ju.segment(jj,sizel-jj).minCoeff(&k); // k is relative to the segment
|
||||
k += jj;
|
||||
if (minrow != ju(jj))
|
||||
{
|
||||
// swap the two locations
|
||||
int j = ju(jj);
|
||||
Index j = ju(jj);
|
||||
swap(ju(jj), ju(k));
|
||||
jr(minrow) = jj; jr(j) = k;
|
||||
swap(u(jj), u(k));
|
||||
@@ -360,11 +360,11 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
|
||||
for (; ki_it; ++ki_it)
|
||||
{
|
||||
Scalar prod = fact * ki_it.value();
|
||||
int j = ki_it.index();
|
||||
int jpos = jr(j);
|
||||
Index j = ki_it.index();
|
||||
Index jpos = jr(j);
|
||||
if (jpos == -1) // fill-in element
|
||||
{
|
||||
int newpos;
|
||||
Index newpos;
|
||||
if (j >= ii) // dealing with the upper part
|
||||
{
|
||||
newpos = ii + sizeu;
|
||||
@@ -393,7 +393,7 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
|
||||
} // end of the elimination on the row ii
|
||||
|
||||
// reset the upper part of the pointer jr to zero
|
||||
for(int k = 0; k <sizeu; k++) jr(ju(ii+k)) = -1;
|
||||
for(Index k = 0; k <sizeu; k++) jr(ju(ii+k)) = -1;
|
||||
|
||||
// 4 - partially sort and insert the elements in the m_lu matrix
|
||||
|
||||
@@ -406,7 +406,7 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
|
||||
|
||||
// store the largest m_fill elements of the L part
|
||||
m_lu.startVec(ii);
|
||||
for(int k = 0; k < len; k++)
|
||||
for(Index k = 0; k < len; k++)
|
||||
m_lu.insertBackByOuterInnerUnordered(ii,ju(k)) = u(k);
|
||||
|
||||
// store the diagonal element
|
||||
@@ -418,7 +418,7 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
|
||||
// sort the U-part of the row
|
||||
// apply the dropping rule first
|
||||
len = 0;
|
||||
for(int k = 1; k < sizeu; k++)
|
||||
for(Index k = 1; k < sizeu; k++)
|
||||
{
|
||||
if(abs(u(ii+k)) > m_droptol * rownorm )
|
||||
{
|
||||
@@ -434,7 +434,7 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
|
||||
internal::QuickSplit(uu, juu, len);
|
||||
|
||||
// store the largest elements of the U part
|
||||
for(int k = ii + 1; k < ii + len; k++)
|
||||
for(Index k = ii + 1; k < ii + len; k++)
|
||||
m_lu.insertBackByOuterInnerUnordered(ii,ju(k)) = u(k);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -331,7 +331,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
|
||||
|
||||
@@ -242,7 +242,7 @@ struct partial_lu_impl
|
||||
const Index cols = lu.cols();
|
||||
const Index size = (std::min)(rows,cols);
|
||||
nb_transpositions = 0;
|
||||
int first_zero_pivot = -1;
|
||||
Index first_zero_pivot = -1;
|
||||
for(Index k = 0; k < size; ++k)
|
||||
{
|
||||
Index rrows = rows-k-1;
|
||||
@@ -253,7 +253,7 @@ struct partial_lu_impl
|
||||
= lu.col(k).tail(rows-k).cwiseAbs().maxCoeff(&row_of_biggest_in_col);
|
||||
row_of_biggest_in_col += k;
|
||||
|
||||
row_transpositions[k] = row_of_biggest_in_col;
|
||||
row_transpositions[k] = PivIndex(row_of_biggest_in_col);
|
||||
|
||||
if(biggest_in_corner != RealScalar(0))
|
||||
{
|
||||
@@ -318,7 +318,7 @@ struct partial_lu_impl
|
||||
}
|
||||
|
||||
nb_transpositions = 0;
|
||||
int first_zero_pivot = -1;
|
||||
Index first_zero_pivot = -1;
|
||||
for(Index k = 0; k < size; k+=blockSize)
|
||||
{
|
||||
Index bs = (std::min)(size-k,blockSize); // actual size of the block
|
||||
|
||||
@@ -134,4 +134,4 @@ public:
|
||||
};
|
||||
|
||||
}// end namespace eigen
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -91,7 +91,6 @@ template<typename Scalar, typename Index>
|
||||
void minimum_degree_ordering(SparseMatrix<Scalar,ColMajor,Index>& C, PermutationMatrix<Dynamic,Dynamic,Index>& perm)
|
||||
{
|
||||
using std::sqrt;
|
||||
typedef SparseMatrix<Scalar,ColMajor,Index> CCS;
|
||||
|
||||
int d, dk, dext, lemax = 0, e, elenk, eln, i, j, k, k1,
|
||||
k2, k3, jlast, ln, dense, nzmax, mindeg = 0, nvi, nvj, nvk, mark, wnvi,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -122,26 +122,26 @@ class COLAMDOrdering
|
||||
template <typename MatrixType>
|
||||
void operator() (const MatrixType& mat, PermutationType& perm)
|
||||
{
|
||||
int m = mat.rows();
|
||||
int n = mat.cols();
|
||||
int nnz = mat.nonZeros();
|
||||
Index m = mat.rows();
|
||||
Index n = mat.cols();
|
||||
Index nnz = mat.nonZeros();
|
||||
// Get the recommended value of Alen to be used by colamd
|
||||
int Alen = internal::colamd_recommended(nnz, m, n);
|
||||
Index Alen = internal::colamd_recommended(nnz, m, n);
|
||||
// Set the default parameters
|
||||
double knobs [COLAMD_KNOBS];
|
||||
int stats [COLAMD_STATS];
|
||||
Index stats [COLAMD_STATS];
|
||||
internal::colamd_set_defaults(knobs);
|
||||
|
||||
int info;
|
||||
Index info;
|
||||
IndexVector p(n+1), A(Alen);
|
||||
for(int i=0; i <= n; i++) p(i) = mat.outerIndexPtr()[i];
|
||||
for(int i=0; i < nnz; i++) A(i) = mat.innerIndexPtr()[i];
|
||||
for(Index i=0; i <= n; i++) p(i) = mat.outerIndexPtr()[i];
|
||||
for(Index i=0; i < nnz; i++) A(i) = mat.innerIndexPtr()[i];
|
||||
// Call Colamd routine to compute the ordering
|
||||
info = internal::colamd(m, n, Alen, A.data(), p.data(), knobs, stats);
|
||||
eigen_assert( info && "COLAMD failed " );
|
||||
|
||||
perm.resize(n);
|
||||
for (int i = 0; i < n; i++) perm.indices()(p(i)) = i;
|
||||
for (Index i = 0; i < n; i++) perm.indices()(p(i)) = i;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user