mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Compare commits
206 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a65053d80b | ||
|
|
adcb220db3 | ||
|
|
b21f9c3573 | ||
|
|
fe228fc50b | ||
|
|
4ab20b4cae | ||
|
|
5d5cf478ab | ||
|
|
55149df4e8 | ||
|
|
b2d10249b4 | ||
|
|
bdf0b0c47e | ||
|
|
ea7923c6f9 | ||
|
|
49b6e9143e | ||
|
|
f096553344 | ||
|
|
433b353013 | ||
|
|
3cb088c39f | ||
|
|
a99ea69b32 | ||
|
|
d03bbcbcbc | ||
|
|
fae2aa3fd9 | ||
|
|
13a17d968f | ||
|
|
135ba535a4 | ||
|
|
bbbf0559fe | ||
|
|
c91fed1eec | ||
|
|
f59b08f3bd | ||
|
|
9155002901 | ||
|
|
46f4bd9ed4 | ||
|
|
ebad34db21 | ||
|
|
c0f867ed10 | ||
|
|
d225bbe534 | ||
|
|
a6f8da7c48 | ||
|
|
33efb8ed62 | ||
|
|
63e5cf525f | ||
|
|
3cd1641dac | ||
|
|
4fe4ab8fc0 | ||
|
|
d7d76bf4ca | ||
|
|
cf76a50a34 | ||
|
|
ee46ae9ba7 | ||
|
|
b3c3627c72 | ||
|
|
e3a521be6b | ||
|
|
4c7d57490c | ||
|
|
fe21e084b4 | ||
|
|
282fd7a2da | ||
|
|
7d28c618a0 | ||
|
|
f07fca2c80 | ||
|
|
99ab2411e5 | ||
|
|
ffefe1bd2e | ||
|
|
55574053d0 | ||
|
|
ffee1d1c87 | ||
|
|
adf5992767 | ||
|
|
19e7c672bb | ||
|
|
99a6178e6a | ||
|
|
c3342b0bb4 | ||
|
|
84c8b6d5c5 | ||
|
|
18a8034348 | ||
|
|
697e1656ce | ||
|
|
c2a23c3e24 | ||
|
|
6d0e3154d7 | ||
|
|
7b122ed158 | ||
|
|
d9232a96aa | ||
|
|
4ecf67f5e4 | ||
|
|
860d66c0f1 | ||
|
|
ba3aafa85f | ||
|
|
b478521ecd | ||
|
|
e8fa6dde01 | ||
|
|
134b83c310 | ||
|
|
b0e810fb3f | ||
|
|
dee686f762 | ||
|
|
90cacfa610 | ||
|
|
de21678aab | ||
|
|
a700d3c506 | ||
|
|
fc4684fe97 | ||
|
|
c088ee78c8 | ||
|
|
e53539435d | ||
|
|
1e8b834ceb | ||
|
|
3c510db6bf | ||
|
|
72ffb63165 | ||
|
|
67e24b85a4 | ||
|
|
2359486129 | ||
|
|
dd2e4be741 | ||
|
|
c5ef8f9027 | ||
|
|
4931a719f4 | ||
|
|
27f34269d5 | ||
|
|
e7d2376688 | ||
|
|
dc36efbb8f | ||
|
|
9a47fb289b | ||
|
|
151e3294cf | ||
|
|
5d1263e7c5 | ||
|
|
c6c6c34909 | ||
|
|
931edea57d | ||
|
|
bfcad536e8 | ||
|
|
b464fc19bc | ||
|
|
c541d0a62e | ||
|
|
b43d92a5a2 | ||
|
|
56818d907e | ||
|
|
e9868f438b | ||
|
|
4f0909b5f0 | ||
|
|
6cac61ca3e | ||
|
|
1180ede36d | ||
|
|
99fa279ed1 | ||
|
|
dbab12d6b0 | ||
|
|
dc727d86f1 | ||
|
|
5cec29162b | ||
|
|
703c8a0cc6 | ||
|
|
d30f0c0953 | ||
|
|
adacacb285 | ||
|
|
c8e1b679fa | ||
|
|
951e238430 | ||
|
|
9c5c8d8916 | ||
|
|
77fc6a9914 | ||
|
|
eef03525b8 | ||
|
|
31621ff0ef | ||
|
|
0b44893b4e | ||
|
|
8cad73072e | ||
|
|
9be2712bf7 | ||
|
|
0612768c1c | ||
|
|
32025a2510 | ||
|
|
771e64200f | ||
|
|
4846c76d9d | ||
|
|
afc9efca15 | ||
|
|
ea7d872181 | ||
|
|
b6299c974f | ||
|
|
b3544ce2ae | ||
|
|
a8f5ef9388 | ||
|
|
58abf0eb98 | ||
|
|
ef73265987 | ||
|
|
4fbd78d993 | ||
|
|
5dfae4524b | ||
|
|
2064c59878 | ||
|
|
bb9a465c5a | ||
|
|
28d17c5390 | ||
|
|
4bfe38eda2 | ||
|
|
23aae0d63e | ||
|
|
0dfea7fce4 | ||
|
|
c121e6f390 | ||
|
|
955c099eb5 | ||
|
|
a00aaf7f7e | ||
|
|
6e01780541 | ||
|
|
939f0327b6 | ||
|
|
78e1a62c54 | ||
|
|
59eeb67187 | ||
|
|
b8374aec00 | ||
|
|
7dc18b20bb | ||
|
|
32e7dae776 | ||
|
|
9ab503903e | ||
|
|
14b164b00e | ||
|
|
c78b5fd9aa | ||
|
|
2fb5567e08 | ||
|
|
3df134dec2 | ||
|
|
c58a2ff03a | ||
|
|
9e1127619c | ||
|
|
720767ae40 | ||
|
|
d8e97aee89 | ||
|
|
625814464e | ||
|
|
39b27fb656 | ||
|
|
25579df2d4 | ||
|
|
3884308da7 | ||
|
|
68631e28d4 | ||
|
|
39d3bc2394 | ||
|
|
659c97ee49 | ||
|
|
769eeac35e | ||
|
|
51da67f211 | ||
|
|
05545d0197 | ||
|
|
8bee573a78 | ||
|
|
fb1a29fed5 | ||
|
|
e129e985c3 | ||
|
|
2d5ea82807 | ||
|
|
3c00e3da03 | ||
|
|
434817164e | ||
|
|
2c1ac23c62 | ||
|
|
a0e5b00280 | ||
|
|
6456b74a89 | ||
|
|
86ca05b324 | ||
|
|
8f8c67b8bd | ||
|
|
aa966ca319 | ||
|
|
f7cd63b964 | ||
|
|
69cecc45e5 | ||
|
|
abce49ea21 | ||
|
|
d271ad38ce | ||
|
|
3e2314dd67 | ||
|
|
444c1bc55b | ||
|
|
390724b4b6 | ||
|
|
d8ca948148 | ||
|
|
3345ea0ddd | ||
|
|
9195a224f3 | ||
|
|
b8ef48c46d | ||
|
|
a53a7d6e6a | ||
|
|
eda59ffc1b | ||
|
|
6f86c12339 | ||
|
|
aea630a98a | ||
|
|
2ba55e90db | ||
|
|
d0b8ce8f2a | ||
|
|
1c4e85ac7e | ||
|
|
78fa34e8ff | ||
|
|
8fb27fad36 | ||
|
|
be224d93f4 | ||
|
|
11402edfd3 | ||
|
|
fe8a710a21 | ||
|
|
03d86ea736 | ||
|
|
13a5582835 | ||
|
|
59596efdf7 | ||
|
|
6db8fa7d04 | ||
|
|
2f15f74218 | ||
|
|
578d6f7ced | ||
|
|
a1d7e9051e | ||
|
|
8e0a42350d | ||
|
|
ac465a0891 | ||
|
|
211e1f8044 | ||
|
|
d09b94e2ad |
@@ -101,6 +101,8 @@ if(EIGEN_DEFAULT_TO_ROW_MAJOR)
|
|||||||
add_definitions("-DEIGEN_DEFAULT_TO_ROW_MAJOR")
|
add_definitions("-DEIGEN_DEFAULT_TO_ROW_MAJOR")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_definitions("-DEIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS")
|
||||||
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
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")
|
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")
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-g3")
|
set(CMAKE_CXX_FLAGS_DEBUG "-g3")
|
||||||
@@ -205,6 +207,7 @@ endif(MSVC)
|
|||||||
|
|
||||||
option(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION "Disable explicit vectorization in tests/examples" OFF)
|
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)
|
option(EIGEN_TEST_X87 "Force using X87 instructions. Implies no vectorization." OFF)
|
||||||
|
option(EIGEN_TEST_32BIT "Force generating 32bit code." OFF)
|
||||||
|
|
||||||
if(EIGEN_TEST_X87)
|
if(EIGEN_TEST_X87)
|
||||||
set(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION ON)
|
set(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION ON)
|
||||||
@@ -216,6 +219,15 @@ if(EIGEN_TEST_X87)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(EIGEN_TEST_32BIT)
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
|
||||||
|
message(STATUS "Forcing generation of 32-bit code in tests/examples")
|
||||||
|
else()
|
||||||
|
message(STATUS "EIGEN_TEST_32BIT ignored on your compiler")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)
|
if(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)
|
||||||
add_definitions(-DEIGEN_DONT_VECTORIZE=1)
|
add_definitions(-DEIGEN_DONT_VECTORIZE=1)
|
||||||
message(STATUS "Disabling vectorization in tests/examples")
|
message(STATUS "Disabling vectorization in tests/examples")
|
||||||
@@ -277,21 +289,52 @@ add_subdirectory(Eigen)
|
|||||||
|
|
||||||
add_subdirectory(doc EXCLUDE_FROM_ALL)
|
add_subdirectory(doc EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
add_custom_target(buildtests)
|
||||||
|
add_custom_target(check COMMAND "ctest")
|
||||||
|
add_dependencies(check buildtests)
|
||||||
|
|
||||||
|
# CMake/Ctest does not allow us to change the build command,
|
||||||
|
# so we have to workaround by directly editing the generated DartConfiguration.tcl file
|
||||||
|
# save CMAKE_MAKE_PROGRAM
|
||||||
|
set(CMAKE_MAKE_PROGRAM_SAVE ${CMAKE_MAKE_PROGRAM})
|
||||||
|
# and set a fake one
|
||||||
|
set(CMAKE_MAKE_PROGRAM "@EIGEN_MAKECOMMAND_PLACEHOLDER@")
|
||||||
|
|
||||||
include(CTest)
|
include(CTest)
|
||||||
enable_testing() # must be called from the root CMakeLists, see man page
|
enable_testing() # must be called from the root CMakeLists, see man page
|
||||||
include(EigenTesting)
|
include(EigenTesting)
|
||||||
ei_init_testing()
|
ei_init_testing()
|
||||||
|
|
||||||
|
# overwrite default DartConfiguration.tcl
|
||||||
|
# The worarounds are different for each version of the MSVC IDE
|
||||||
|
if(MSVC_IDE)
|
||||||
|
if(MSVC_VERSION EQUAL 1600) # MSVC 2010
|
||||||
|
set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} buildtests.vcxproj /p:Configuration=\${CTEST_CONFIGURATION_TYPE} \n # ")
|
||||||
|
else() # MSVC 2008 (TODO check MSVC 2005)
|
||||||
|
set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} /project buildtests")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
# for make and nmake
|
||||||
|
set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} buildtests")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
configure_file(${CMAKE_BINARY_DIR}/DartConfiguration.tcl ${CMAKE_BINARY_DIR}/DartConfiguration.tcl)
|
||||||
|
# restore default CMAKE_MAKE_PROGRAM
|
||||||
|
set(CMAKE_MAKE_PROGRAM ${CMAKE_MAKE_PROGRAM_SAVE})
|
||||||
|
# un-set temporary variables so that it is like they never existed.
|
||||||
|
# CMake 2.6.3 introduces the more logical unset() syntax for this.
|
||||||
|
set(CMAKE_MAKE_PROGRAM_SAVE)
|
||||||
|
set(EIGEN_MAKECOMMAND_PLACEHOLDER)
|
||||||
|
|
||||||
|
configure_file(${CMAKE_SOURCE_DIR}/CTestCustom.cmake.in ${CMAKE_BINARY_DIR}/CTestCustom.cmake)
|
||||||
|
|
||||||
|
|
||||||
if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
|
if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
|
||||||
add_subdirectory(test) # can't do EXCLUDE_FROM_ALL here, breaks CTest
|
add_subdirectory(test) # can't do EXCLUDE_FROM_ALL here, breaks CTest
|
||||||
else()
|
else()
|
||||||
add_subdirectory(test EXCLUDE_FROM_ALL)
|
add_subdirectory(test EXCLUDE_FROM_ALL)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(unsupported)
|
|
||||||
|
|
||||||
add_subdirectory(demos EXCLUDE_FROM_ALL)
|
|
||||||
|
|
||||||
if(NOT MSVC)
|
if(NOT MSVC)
|
||||||
if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
|
if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
|
||||||
add_subdirectory(blas)
|
add_subdirectory(blas)
|
||||||
@@ -302,6 +345,10 @@ if(NOT MSVC)
|
|||||||
endif()
|
endif()
|
||||||
endif(NOT MSVC)
|
endif(NOT MSVC)
|
||||||
|
|
||||||
|
add_subdirectory(unsupported)
|
||||||
|
|
||||||
|
add_subdirectory(demos EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
# must be after test and unsupported, for configuring buildtests.in
|
# must be after test and unsupported, for configuring buildtests.in
|
||||||
add_subdirectory(scripts EXCLUDE_FROM_ALL)
|
add_subdirectory(scripts EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,3 @@ set(CTEST_DROP_METHOD "http")
|
|||||||
set(CTEST_DROP_SITE "eigen.tuxfamily.org")
|
set(CTEST_DROP_SITE "eigen.tuxfamily.org")
|
||||||
set(CTEST_DROP_LOCATION "/CDash/submit.php?project=Eigen")
|
set(CTEST_DROP_LOCATION "/CDash/submit.php?project=Eigen")
|
||||||
set(CTEST_DROP_SITE_CDASH TRUE)
|
set(CTEST_DROP_SITE_CDASH TRUE)
|
||||||
|
|
||||||
## A tribute to Dynamic!
|
|
||||||
set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS "33331")
|
|
||||||
set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS "33331")
|
|
||||||
4
CTestCustom.cmake.in
Normal file
4
CTestCustom.cmake.in
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
## A tribute to Dynamic!
|
||||||
|
set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS "33331")
|
||||||
|
set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS "33331")
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "Core"
|
#include "Core"
|
||||||
|
|
||||||
#include "src/Core/util/DisableMSVCWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ namespace Eigen {
|
|||||||
|
|
||||||
} // namespace Eigen
|
} // namespace Eigen
|
||||||
|
|
||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_CHOLESKY_MODULE_H
|
#endif // EIGEN_CHOLESKY_MODULE_H
|
||||||
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|||||||
31
Eigen/Core
31
Eigen/Core
@@ -26,8 +26,8 @@
|
|||||||
#ifndef EIGEN_CORE_H
|
#ifndef EIGEN_CORE_H
|
||||||
#define EIGEN_CORE_H
|
#define EIGEN_CORE_H
|
||||||
|
|
||||||
// first thing Eigen does: prevent MSVC from committing suicide
|
// first thing Eigen does: stop the compiler from committing suicide
|
||||||
#include "src/Core/util/DisableMSVCWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
// then include this file where all our macros are defined. It's really important to do it first because
|
// then include this file where all our macros are defined. It's really important to do it first because
|
||||||
// it's where we do all the alignment settings (platform detection and honoring the user's will if he
|
// it's where we do all the alignment settings (platform detection and honoring the user's will if he
|
||||||
@@ -51,16 +51,16 @@
|
|||||||
#define EIGEN_SSE2_ON_MSVC_2008_OR_LATER
|
#define EIGEN_SSE2_ON_MSVC_2008_OR_LATER
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#else
|
||||||
|
// Remember that usage of defined() in a #define is undefined by the standard
|
||||||
// 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__) || EIGEN_GNUC_AT_LEAST(4,2) )
|
#define EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC
|
||||||
#define EIGEN_SSE2_BUT_NOT_OLD_GCC
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef EIGEN_DONT_VECTORIZE
|
#ifndef EIGEN_DONT_VECTORIZE
|
||||||
|
|
||||||
#if defined (EIGEN_SSE2_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
|
#if defined (EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
|
||||||
|
|
||||||
// Defines symbols for compile-time detection of which instructions are
|
// Defines symbols for compile-time detection of which instructions are
|
||||||
// used.
|
// used.
|
||||||
@@ -143,6 +143,7 @@
|
|||||||
#ifdef EIGEN_HAS_ERRNO
|
#ifdef EIGEN_HAS_ERRNO
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#endif
|
#endif
|
||||||
|
#include <cstddef>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <complex>
|
#include <complex>
|
||||||
@@ -158,7 +159,7 @@
|
|||||||
|
|
||||||
// for outputting debug info
|
// for outputting debug info
|
||||||
#ifdef EIGEN_DEBUG_ASSIGN
|
#ifdef EIGEN_DEBUG_ASSIGN
|
||||||
#include<iostream>
|
#include <iostream>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// required for __cpuid, needs to be included after cmath
|
// required for __cpuid, needs to be included after cmath
|
||||||
@@ -174,16 +175,10 @@
|
|||||||
#include <new>
|
#include <new>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// this needs to be done after all possible windows C header includes and before any Eigen source includes
|
|
||||||
// (system C++ includes are supposed to be able to deal with this already):
|
|
||||||
// windows.h defines min and max macros which would make Eigen fail to compile.
|
|
||||||
#if defined(min) || defined(max)
|
|
||||||
#error The preprocessor symbols 'min' or 'max' are defined. If you are compiling on Windows, do #define NOMINMAX to prevent windows.h from defining these symbols.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// defined in bits/termios.h
|
// defined in bits/termios.h
|
||||||
#undef B0
|
#undef B0
|
||||||
|
|
||||||
|
/** \brief Namespace containing all symbols from the %Eigen library. */
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
inline static const char *SimdInstructionSetsInUse(void) {
|
inline static const char *SimdInstructionSetsInUse(void) {
|
||||||
@@ -239,6 +234,8 @@ inline static const char *SimdInstructionSetsInUse(void) {
|
|||||||
// we use size_t frequently and we'll never remember to prepend it with std:: everytime just to
|
// we use size_t frequently and we'll never remember to prepend it with std:: everytime just to
|
||||||
// ensure QNX/QCC support
|
// ensure QNX/QCC support
|
||||||
using std::size_t;
|
using std::size_t;
|
||||||
|
// gcc 4.6.0 wants std:: for ptrdiff_t
|
||||||
|
using std::ptrdiff_t;
|
||||||
|
|
||||||
/** \defgroup Core_Module Core module
|
/** \defgroup Core_Module Core module
|
||||||
* This is the main module of Eigen providing dense matrix and vector support
|
* This is the main module of Eigen providing dense matrix and vector support
|
||||||
@@ -354,7 +351,7 @@ using std::size_t;
|
|||||||
|
|
||||||
#include "src/Core/GlobalFunctions.h"
|
#include "src/Core/GlobalFunctions.h"
|
||||||
|
|
||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#ifdef EIGEN2_SUPPORT
|
#ifdef EIGEN2_SUPPORT
|
||||||
#include "Eigen2Support"
|
#include "Eigen2Support"
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
#error Eigen2 support must be enabled by defining EIGEN2_SUPPORT before including any Eigen header
|
#error Eigen2 support must be enabled by defining EIGEN2_SUPPORT before including any Eigen header
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "src/Core/util/DisableMSVCWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ namespace Eigen {
|
|||||||
|
|
||||||
} // namespace Eigen
|
} // namespace Eigen
|
||||||
|
|
||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
// Eigen2 used to include iostream
|
// Eigen2 used to include iostream
|
||||||
#include<iostream>
|
#include<iostream>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "Core"
|
#include "Core"
|
||||||
|
|
||||||
#include "src/Core/util/DisableMSVCWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
#include "Cholesky"
|
#include "Cholesky"
|
||||||
#include "Jacobi"
|
#include "Jacobi"
|
||||||
@@ -38,7 +38,7 @@ namespace Eigen {
|
|||||||
|
|
||||||
} // namespace Eigen
|
} // namespace Eigen
|
||||||
|
|
||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_EIGENVALUES_MODULE_H
|
#endif // EIGEN_EIGENVALUES_MODULE_H
|
||||||
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "Core"
|
#include "Core"
|
||||||
|
|
||||||
#include "src/Core/util/DisableMSVCWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
#include "SVD"
|
#include "SVD"
|
||||||
#include "LU"
|
#include "LU"
|
||||||
@@ -60,7 +60,7 @@ namespace Eigen {
|
|||||||
|
|
||||||
} // namespace Eigen
|
} // namespace Eigen
|
||||||
|
|
||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_GEOMETRY_MODULE_H
|
#endif // EIGEN_GEOMETRY_MODULE_H
|
||||||
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "Core"
|
#include "Core"
|
||||||
|
|
||||||
#include "src/Core/util/DisableMSVCWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ namespace Eigen {
|
|||||||
|
|
||||||
} // namespace Eigen
|
} // namespace Eigen
|
||||||
|
|
||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_HOUSEHOLDER_MODULE_H
|
#endif // EIGEN_HOUSEHOLDER_MODULE_H
|
||||||
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "Core"
|
#include "Core"
|
||||||
|
|
||||||
#include "src/Core/util/DisableMSVCWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ namespace Eigen {
|
|||||||
|
|
||||||
} // namespace Eigen
|
} // namespace Eigen
|
||||||
|
|
||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_JACOBI_MODULE_H
|
#endif // EIGEN_JACOBI_MODULE_H
|
||||||
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|||||||
4
Eigen/LU
4
Eigen/LU
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "Core"
|
#include "Core"
|
||||||
|
|
||||||
#include "src/Core/util/DisableMSVCWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ namespace Eigen {
|
|||||||
|
|
||||||
} // namespace Eigen
|
} // namespace Eigen
|
||||||
|
|
||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_LU_MODULE_H
|
#endif // EIGEN_LU_MODULE_H
|
||||||
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|||||||
@@ -5,9 +5,12 @@
|
|||||||
#error LeastSquares is only available in Eigen2 support mode (define EIGEN2_SUPPORT)
|
#error LeastSquares is only available in Eigen2 support mode (define EIGEN2_SUPPORT)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// exclude from normal eigen3-only documentation
|
||||||
|
#ifdef EIGEN2_SUPPORT
|
||||||
|
|
||||||
#include "Core"
|
#include "Core"
|
||||||
|
|
||||||
#include "src/Core/util/DisableMSVCWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
#include "Eigenvalues"
|
#include "Eigenvalues"
|
||||||
#include "Geometry"
|
#include "Geometry"
|
||||||
@@ -26,6 +29,8 @@ namespace Eigen {
|
|||||||
|
|
||||||
} // namespace Eigen
|
} // namespace Eigen
|
||||||
|
|
||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
|
#endif // EIGEN2_SUPPORT
|
||||||
|
|
||||||
#endif // EIGEN_REGRESSION_MODULE_H
|
#endif // EIGEN_REGRESSION_MODULE_H
|
||||||
|
|||||||
4
Eigen/QR
4
Eigen/QR
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "Core"
|
#include "Core"
|
||||||
|
|
||||||
#include "src/Core/util/DisableMSVCWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
#include "Cholesky"
|
#include "Cholesky"
|
||||||
#include "Jacobi"
|
#include "Jacobi"
|
||||||
@@ -35,7 +35,7 @@ namespace Eigen {
|
|||||||
|
|
||||||
} // namespace Eigen
|
} // namespace Eigen
|
||||||
|
|
||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#ifdef EIGEN2_SUPPORT
|
#ifdef EIGEN2_SUPPORT
|
||||||
#include "Eigenvalues"
|
#include "Eigenvalues"
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#if (!EIGEN_MALLOC_ALREADY_ALIGNED)
|
#if (!EIGEN_MALLOC_ALREADY_ALIGNED)
|
||||||
|
|
||||||
#include "src/Core/util/DisableMSVCWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
void *qMalloc(size_t size)
|
void *qMalloc(size_t size)
|
||||||
{
|
{
|
||||||
@@ -26,7 +26,7 @@ void *qRealloc(void *ptr, size_t size)
|
|||||||
return newPtr;
|
return newPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include "Householder"
|
#include "Householder"
|
||||||
#include "Jacobi"
|
#include "Jacobi"
|
||||||
|
|
||||||
#include "src/Core/util/DisableMSVCWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ namespace Eigen {
|
|||||||
|
|
||||||
} // namespace Eigen
|
} // namespace Eigen
|
||||||
|
|
||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_SVD_MODULE_H
|
#endif // EIGEN_SVD_MODULE_H
|
||||||
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "Core"
|
#include "Core"
|
||||||
|
|
||||||
#include "src/Core/util/DisableMSVCWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
@@ -63,7 +63,7 @@ struct Sparse {};
|
|||||||
|
|
||||||
} // namespace Eigen
|
} // namespace Eigen
|
||||||
|
|
||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_SPARSE_MODULE_H
|
#endif // EIGEN_SPARSE_MODULE_H
|
||||||
|
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ template<> struct llt_inplace<Lower>
|
|||||||
|
|
||||||
Index blockSize = size/8;
|
Index blockSize = size/8;
|
||||||
blockSize = (blockSize/16)*16;
|
blockSize = (blockSize/16)*16;
|
||||||
blockSize = std::min(std::max(blockSize,Index(8)), Index(128));
|
blockSize = (std::min)((std::max)(blockSize,Index(8)), Index(128));
|
||||||
|
|
||||||
for (Index k=0; k<size; k+=blockSize)
|
for (Index k=0; k<size; k+=blockSize)
|
||||||
{
|
{
|
||||||
@@ -241,7 +241,7 @@ template<> struct llt_inplace<Lower>
|
|||||||
// A00 | - | -
|
// A00 | - | -
|
||||||
// lu = A10 | A11 | -
|
// lu = A10 | A11 | -
|
||||||
// A20 | A21 | A22
|
// A20 | A21 | A22
|
||||||
Index bs = std::min(blockSize, size-k);
|
Index bs = (std::min)(blockSize, size-k);
|
||||||
Index rs = size - k - bs;
|
Index rs = size - k - bs;
|
||||||
Block<MatrixType,Dynamic,Dynamic> A11(m,k, k, bs,bs);
|
Block<MatrixType,Dynamic,Dynamic> A11(m,k, k, bs,bs);
|
||||||
Block<MatrixType,Dynamic,Dynamic> A21(m,k+bs,k, rs,bs);
|
Block<MatrixType,Dynamic,Dynamic> A21(m,k+bs,k, rs,bs);
|
||||||
|
|||||||
@@ -37,6 +37,9 @@
|
|||||||
* API for the %Matrix class provides easy access to linear-algebra
|
* API for the %Matrix class provides easy access to linear-algebra
|
||||||
* operations.
|
* operations.
|
||||||
*
|
*
|
||||||
|
* This class can be extended with the help of the plugin mechanism described on the page
|
||||||
|
* \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_ARRAY_PLUGIN.
|
||||||
|
*
|
||||||
* \sa \ref TutorialArrayClass, \ref TopicClassHierarchy
|
* \sa \ref TutorialArrayClass, \ref TopicClassHierarchy
|
||||||
*/
|
*/
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|||||||
@@ -42,7 +42,10 @@ template<typename ExpressionType> class MatrixWrapper;
|
|||||||
*
|
*
|
||||||
* This class is the base that is inherited by all array expression types.
|
* This class is the base that is inherited by all array expression types.
|
||||||
*
|
*
|
||||||
* \param Derived is the derived type, e.g., an array or an expression type.
|
* \tparam Derived is the derived type, e.g., an array or an expression type.
|
||||||
|
*
|
||||||
|
* This class can be extended with the help of the plugin mechanism described on the page
|
||||||
|
* \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_ARRAYBASE_PLUGIN.
|
||||||
*
|
*
|
||||||
* \sa class MatrixBase, \ref TopicClassHierarchy
|
* \sa class MatrixBase, \ref TopicClassHierarchy
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -53,6 +53,12 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
|
|||||||
EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper)
|
EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper)
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ArrayWrapper)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ArrayWrapper)
|
||||||
|
|
||||||
|
typedef typename internal::conditional<
|
||||||
|
internal::is_lvalue<ExpressionType>::value,
|
||||||
|
Scalar,
|
||||||
|
const Scalar
|
||||||
|
>::type ScalarWithConstIfNotLvalue;
|
||||||
|
|
||||||
typedef typename internal::nested<ExpressionType>::type NestedExpressionType;
|
typedef typename internal::nested<ExpressionType>::type NestedExpressionType;
|
||||||
|
|
||||||
inline ArrayWrapper(const ExpressionType& matrix) : m_expression(matrix) {}
|
inline ArrayWrapper(const ExpressionType& matrix) : m_expression(matrix) {}
|
||||||
@@ -62,6 +68,9 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
|
|||||||
inline Index outerStride() const { return m_expression.outerStride(); }
|
inline Index outerStride() const { return m_expression.outerStride(); }
|
||||||
inline Index innerStride() const { return m_expression.innerStride(); }
|
inline Index innerStride() const { return m_expression.innerStride(); }
|
||||||
|
|
||||||
|
inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
|
||||||
|
inline const Scalar* data() const { return m_expression.data(); }
|
||||||
|
|
||||||
inline const CoeffReturnType coeff(Index row, Index col) const
|
inline const CoeffReturnType coeff(Index row, Index col) const
|
||||||
{
|
{
|
||||||
return m_expression.coeff(row, col);
|
return m_expression.coeff(row, col);
|
||||||
@@ -151,6 +160,12 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
|
|||||||
EIGEN_DENSE_PUBLIC_INTERFACE(MatrixWrapper)
|
EIGEN_DENSE_PUBLIC_INTERFACE(MatrixWrapper)
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper)
|
||||||
|
|
||||||
|
typedef typename internal::conditional<
|
||||||
|
internal::is_lvalue<ExpressionType>::value,
|
||||||
|
Scalar,
|
||||||
|
const Scalar
|
||||||
|
>::type ScalarWithConstIfNotLvalue;
|
||||||
|
|
||||||
typedef typename internal::nested<ExpressionType>::type NestedExpressionType;
|
typedef typename internal::nested<ExpressionType>::type NestedExpressionType;
|
||||||
|
|
||||||
inline MatrixWrapper(const ExpressionType& matrix) : m_expression(matrix) {}
|
inline MatrixWrapper(const ExpressionType& matrix) : m_expression(matrix) {}
|
||||||
@@ -160,6 +175,9 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
|
|||||||
inline Index outerStride() const { return m_expression.outerStride(); }
|
inline Index outerStride() const { return m_expression.outerStride(); }
|
||||||
inline Index innerStride() const { return m_expression.innerStride(); }
|
inline Index innerStride() const { return m_expression.innerStride(); }
|
||||||
|
|
||||||
|
inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
|
||||||
|
inline const Scalar* data() const { return m_expression.data(); }
|
||||||
|
|
||||||
inline const CoeffReturnType coeff(Index row, Index col) const
|
inline const CoeffReturnType coeff(Index row, Index col) const
|
||||||
{
|
{
|
||||||
return m_expression.coeff(row, col);
|
return m_expression.coeff(row, col);
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public:
|
|||||||
DstIsAligned = Derived::Flags & AlignedBit,
|
DstIsAligned = Derived::Flags & AlignedBit,
|
||||||
DstHasDirectAccess = Derived::Flags & DirectAccessBit,
|
DstHasDirectAccess = Derived::Flags & DirectAccessBit,
|
||||||
SrcIsAligned = OtherDerived::Flags & AlignedBit,
|
SrcIsAligned = OtherDerived::Flags & AlignedBit,
|
||||||
JointAlignment = DstIsAligned && SrcIsAligned ? Aligned : Unaligned
|
JointAlignment = bool(DstIsAligned) && bool(SrcIsAligned) ? Aligned : Unaligned
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -106,9 +106,9 @@ public:
|
|||||||
: int(NoUnrolling)
|
: int(NoUnrolling)
|
||||||
)
|
)
|
||||||
: int(Traversal) == int(LinearVectorizedTraversal)
|
: int(Traversal) == int(LinearVectorizedTraversal)
|
||||||
? ( int(MayUnrollCompletely) && int(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) )
|
? ( bool(MayUnrollCompletely) && bool(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) )
|
||||||
: int(Traversal) == int(LinearTraversal)
|
: int(Traversal) == int(LinearTraversal)
|
||||||
? ( int(MayUnrollCompletely) ? int(CompleteUnrolling) : int(NoUnrolling) )
|
? ( bool(MayUnrollCompletely) ? int(CompleteUnrolling) : int(NoUnrolling) )
|
||||||
: int(NoUnrolling)
|
: int(NoUnrolling)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -474,7 +474,7 @@ struct assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling>
|
|||||||
|
|
||||||
// do the vectorizable part of the assignment
|
// do the vectorizable part of the assignment
|
||||||
for(Index inner = alignedStart; inner<alignedEnd; inner+=packetSize)
|
for(Index inner = alignedStart; inner<alignedEnd; inner+=packetSize)
|
||||||
dst.template copyPacketByOuterInner<Derived2, Aligned, Unaligned>(outer, inner, src);
|
dst.template copyPacketByOuterInner<Derived2, dstAlignment, Unaligned>(outer, inner, src);
|
||||||
|
|
||||||
// do the non-vectorizable part of the assignment
|
// do the non-vectorizable part of the assignment
|
||||||
for(Index inner = alignedEnd; inner<innerSize ; ++inner)
|
for(Index inner = alignedEnd; inner<innerSize ; ++inner)
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ class BandMatrixBase : public EigenBase<Derived>
|
|||||||
if (i<=supers())
|
if (i<=supers())
|
||||||
{
|
{
|
||||||
start = supers()-i;
|
start = supers()-i;
|
||||||
len = std::min(rows(),std::max<Index>(0,coeffs().rows() - (supers()-i)));
|
len = (std::min)(rows(),std::max<Index>(0,coeffs().rows() - (supers()-i)));
|
||||||
}
|
}
|
||||||
else if (i>=rows()-subs())
|
else if (i>=rows()-subs())
|
||||||
len = std::max<Index>(0,coeffs().rows() - (i + 1 - rows() + subs()));
|
len = std::max<Index>(0,coeffs().rows() - (i + 1 - rows() + subs()));
|
||||||
@@ -96,11 +96,11 @@ class BandMatrixBase : public EigenBase<Derived>
|
|||||||
|
|
||||||
/** \returns a vector expression of the main diagonal */
|
/** \returns a vector expression of the main diagonal */
|
||||||
inline Block<CoefficientsType,1,SizeAtCompileTime> diagonal()
|
inline Block<CoefficientsType,1,SizeAtCompileTime> diagonal()
|
||||||
{ return Block<CoefficientsType,1,SizeAtCompileTime>(coeffs(),supers(),0,1,std::min(rows(),cols())); }
|
{ return Block<CoefficientsType,1,SizeAtCompileTime>(coeffs(),supers(),0,1,(std::min)(rows(),cols())); }
|
||||||
|
|
||||||
/** \returns a vector expression of the main diagonal (const version) */
|
/** \returns a vector expression of the main diagonal (const version) */
|
||||||
inline const Block<const CoefficientsType,1,SizeAtCompileTime> diagonal() const
|
inline const Block<const CoefficientsType,1,SizeAtCompileTime> diagonal() const
|
||||||
{ return Block<const CoefficientsType,1,SizeAtCompileTime>(coeffs(),supers(),0,1,std::min(rows(),cols())); }
|
{ return Block<const CoefficientsType,1,SizeAtCompileTime>(coeffs(),supers(),0,1,(std::min)(rows(),cols())); }
|
||||||
|
|
||||||
template<int Index> struct DiagonalIntReturnType {
|
template<int Index> struct DiagonalIntReturnType {
|
||||||
enum {
|
enum {
|
||||||
@@ -122,13 +122,13 @@ class BandMatrixBase : public EigenBase<Derived>
|
|||||||
/** \returns a vector expression of the \a N -th sub or super diagonal */
|
/** \returns a vector expression of the \a N -th sub or super diagonal */
|
||||||
template<int N> inline typename DiagonalIntReturnType<N>::Type diagonal()
|
template<int N> inline typename DiagonalIntReturnType<N>::Type diagonal()
|
||||||
{
|
{
|
||||||
return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, std::max(0,N), 1, diagonalLength(N));
|
return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns a vector expression of the \a N -th sub or super diagonal */
|
/** \returns a vector expression of the \a N -th sub or super diagonal */
|
||||||
template<int N> inline const typename DiagonalIntReturnType<N>::Type diagonal() const
|
template<int N> inline const typename DiagonalIntReturnType<N>::Type diagonal() const
|
||||||
{
|
{
|
||||||
return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, std::max(0,N), 1, diagonalLength(N));
|
return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns a vector expression of the \a i -th sub or super diagonal */
|
/** \returns a vector expression of the \a i -th sub or super diagonal */
|
||||||
@@ -166,7 +166,7 @@ class BandMatrixBase : public EigenBase<Derived>
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
inline Index diagonalLength(Index i) const
|
inline Index diagonalLength(Index i) const
|
||||||
{ return i<0 ? std::min(cols(),rows()+i) : std::min(rows(),cols()-i); }
|
{ return i<0 ? (std::min)(cols(),rows()+i) : (std::min)(rows(),cols()-i); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -180,7 +180,7 @@ class BandMatrixBase : public EigenBase<Derived>
|
|||||||
* \param Cols Number of columns, or \b Dynamic
|
* \param Cols Number of columns, or \b Dynamic
|
||||||
* \param Supers Number of super diagonal
|
* \param Supers Number of super diagonal
|
||||||
* \param Subs Number of sub diagonal
|
* \param Subs Number of sub diagonal
|
||||||
* \param _Options A combination of either \b RowMajor or \b ColMajor, and of \b SelfAdjoint
|
* \param _Options A combination of either \b #RowMajor or \b #ColMajor, and of \b #SelfAdjoint
|
||||||
* The former controls \ref TopicStorageOrders "storage order", and defaults to
|
* The former controls \ref TopicStorageOrders "storage order", and defaults to
|
||||||
* column-major. The latter controls whether the matrix represents a selfadjoint
|
* column-major. The latter controls whether the matrix represents a selfadjoint
|
||||||
* matrix in which case either Supers of Subs have to be null.
|
* matrix in which case either Supers of Subs have to be null.
|
||||||
@@ -284,6 +284,7 @@ class BandMatrixWrapper : public BandMatrixBase<BandMatrixWrapper<_CoefficientsT
|
|||||||
: m_coeffs(coeffs),
|
: m_coeffs(coeffs),
|
||||||
m_rows(rows), m_supers(supers), m_subs(subs)
|
m_rows(rows), m_supers(supers), m_subs(subs)
|
||||||
{
|
{
|
||||||
|
EIGEN_UNUSED_VARIABLE(cols);
|
||||||
//internal::assert(coeffs.cols()==cols() && (supers()+subs()+1)==coeffs.rows());
|
//internal::assert(coeffs.cols()==cols() && (supers()+subs()+1)==coeffs.rows());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -742,7 +742,7 @@ struct setIdentity_impl<Derived, true>
|
|||||||
static EIGEN_STRONG_INLINE Derived& run(Derived& m)
|
static EIGEN_STRONG_INLINE Derived& run(Derived& m)
|
||||||
{
|
{
|
||||||
m.setZero();
|
m.setZero();
|
||||||
const Index size = std::min(m.rows(), m.cols());
|
const Index size = (std::min)(m.rows(), m.cols());
|
||||||
for(Index i = 0; i < size; ++i) m.coeffRef(i,i) = typename Derived::Scalar(1);
|
for(Index i = 0; i < size; ++i) m.coeffRef(i,i) = typename Derived::Scalar(1);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,10 @@
|
|||||||
* This class is the base that is inherited by all dense objects (matrix, vector, arrays,
|
* This class is the base that is inherited by all dense objects (matrix, vector, arrays,
|
||||||
* and related expression types). The common Eigen API for dense objects is contained in this class.
|
* and related expression types). The common Eigen API for dense objects is contained in this class.
|
||||||
*
|
*
|
||||||
* \param Derived is the derived type, e.g., a matrix type or an expression.
|
* \tparam Derived is the derived type, e.g., a matrix type or an expression.
|
||||||
|
*
|
||||||
|
* This class can be extended with the help of the plugin mechanism described on the page
|
||||||
|
* \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_DENSEBASE_PLUGIN.
|
||||||
*
|
*
|
||||||
* \sa \ref TopicClassHierarchy
|
* \sa \ref TopicClassHierarchy
|
||||||
*/
|
*/
|
||||||
@@ -53,7 +56,13 @@ template<typename Derived> class DenseBase
|
|||||||
class InnerIterator;
|
class InnerIterator;
|
||||||
|
|
||||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||||
typedef typename internal::traits<Derived>::Index Index; /**< The type of indices */
|
|
||||||
|
/** \brief The type of indices
|
||||||
|
* \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
|
||||||
|
* \sa \ref TopicPreprocessorDirectives.
|
||||||
|
*/
|
||||||
|
typedef typename internal::traits<Derived>::Index Index;
|
||||||
|
|
||||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||||
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
|
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
|
||||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ template<typename T> struct add_const_on_value_type_if_arithmetic
|
|||||||
/** \brief Base class providing read-only coefficient access to matrices and arrays.
|
/** \brief Base class providing read-only coefficient access to matrices and arrays.
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
* \tparam Derived Type of the derived class
|
* \tparam Derived Type of the derived class
|
||||||
* \tparam ReadOnlyAccessors Constant indicating read-only access
|
* \tparam #ReadOnlyAccessors Constant indicating read-only access
|
||||||
*
|
*
|
||||||
* This class defines the \c operator() \c const function and friends, which can be used to read specific
|
* This class defines the \c operator() \c const function and friends, which can be used to read specific
|
||||||
* entries of a matrix or array.
|
* entries of a matrix or array.
|
||||||
@@ -212,7 +212,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
|||||||
* to ensure that a packet really starts there. This method is only available on expressions having the
|
* to ensure that a packet really starts there. This method is only available on expressions having the
|
||||||
* PacketAccessBit.
|
* PacketAccessBit.
|
||||||
*
|
*
|
||||||
* The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select
|
* The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select
|
||||||
* the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
|
* the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
|
||||||
* starting at an address which is a multiple of the packet size.
|
* starting at an address which is a multiple of the packet size.
|
||||||
*/
|
*/
|
||||||
@@ -239,7 +239,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
|||||||
* to ensure that a packet really starts there. This method is only available on expressions having the
|
* to ensure that a packet really starts there. This method is only available on expressions having the
|
||||||
* PacketAccessBit and the LinearAccessBit.
|
* PacketAccessBit and the LinearAccessBit.
|
||||||
*
|
*
|
||||||
* The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select
|
* The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select
|
||||||
* the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
|
* the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
|
||||||
* starting at an address which is a multiple of the packet size.
|
* starting at an address which is a multiple of the packet size.
|
||||||
*/
|
*/
|
||||||
@@ -275,7 +275,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
|||||||
/** \brief Base class providing read/write coefficient access to matrices and arrays.
|
/** \brief Base class providing read/write coefficient access to matrices and arrays.
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
* \tparam Derived Type of the derived class
|
* \tparam Derived Type of the derived class
|
||||||
* \tparam WriteAccessors Constant indicating read/write access
|
* \tparam #WriteAccessors Constant indicating read/write access
|
||||||
*
|
*
|
||||||
* This class defines the non-const \c operator() function and friends, which can be used to write specific
|
* This class defines the non-const \c operator() function and friends, which can be used to write specific
|
||||||
* entries of a matrix or array. This class inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which
|
* entries of a matrix or array. This class inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which
|
||||||
@@ -433,7 +433,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
|||||||
* to ensure that a packet really starts there. This method is only available on expressions having the
|
* to ensure that a packet really starts there. This method is only available on expressions having the
|
||||||
* PacketAccessBit.
|
* PacketAccessBit.
|
||||||
*
|
*
|
||||||
* The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select
|
* The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select
|
||||||
* the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
|
* the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
|
||||||
* starting at an address which is a multiple of the packet size.
|
* starting at an address which is a multiple of the packet size.
|
||||||
*/
|
*/
|
||||||
@@ -567,7 +567,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
|||||||
/** \brief Base class providing direct read-only coefficient access to matrices and arrays.
|
/** \brief Base class providing direct read-only coefficient access to matrices and arrays.
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
* \tparam Derived Type of the derived class
|
* \tparam Derived Type of the derived class
|
||||||
* \tparam DirectAccessors Constant indicating direct access
|
* \tparam #DirectAccessors Constant indicating direct access
|
||||||
*
|
*
|
||||||
* This class defines functions to work with strides which can be used to access entries directly. This class
|
* This class defines functions to work with strides which can be used to access entries directly. This class
|
||||||
* inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which defines functions to access entries read-only using
|
* inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which defines functions to access entries read-only using
|
||||||
@@ -637,7 +637,7 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
|||||||
/** \brief Base class providing direct read/write coefficient access to matrices and arrays.
|
/** \brief Base class providing direct read/write coefficient access to matrices and arrays.
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
* \tparam Derived Type of the derived class
|
* \tparam Derived Type of the derived class
|
||||||
* \tparam DirectAccessors Constant indicating direct access
|
* \tparam #DirectWriteAccessors Constant indicating direct access
|
||||||
*
|
*
|
||||||
* This class defines functions to work with strides which can be used to access entries directly. This class
|
* This class defines functions to work with strides which can be used to access entries directly. This class
|
||||||
* inherits DenseCoeffsBase<Derived, WriteAccessors> which defines functions to access entries read/write using
|
* inherits DenseCoeffsBase<Derived, WriteAccessors> which defines functions to access entries read/write using
|
||||||
|
|||||||
@@ -58,14 +58,14 @@ struct plain_array
|
|||||||
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
|
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
|
||||||
eigen_assert((reinterpret_cast<size_t>(array) & sizemask) == 0 \
|
eigen_assert((reinterpret_cast<size_t>(array) & sizemask) == 0 \
|
||||||
&& "this assertion is explained here: " \
|
&& "this assertion is explained here: " \
|
||||||
"http://eigen.tuxfamily.org/dox/UnalignedArrayAssert.html" \
|
"http://eigen.tuxfamily.org/dox-devel/TopicUnalignedArrayAssert.html" \
|
||||||
" **** READ THIS WEB PAGE !!! ****");
|
" **** READ THIS WEB PAGE !!! ****");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename T, int Size, int MatrixOrArrayOptions>
|
template <typename T, int Size, int MatrixOrArrayOptions>
|
||||||
struct plain_array<T, Size, MatrixOrArrayOptions, 16>
|
struct plain_array<T, Size, MatrixOrArrayOptions, 16>
|
||||||
{
|
{
|
||||||
EIGEN_ALIGN16 T array[Size];
|
EIGEN_USER_ALIGN16 T array[Size];
|
||||||
plain_array() { EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(0xf) }
|
plain_array() { EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(0xf) }
|
||||||
plain_array(constructor_without_unaligned_array_assert) {}
|
plain_array(constructor_without_unaligned_array_assert) {}
|
||||||
};
|
};
|
||||||
@@ -73,7 +73,7 @@ struct plain_array<T, Size, MatrixOrArrayOptions, 16>
|
|||||||
template <typename T, int MatrixOrArrayOptions, int Alignment>
|
template <typename T, int MatrixOrArrayOptions, int Alignment>
|
||||||
struct plain_array<T, 0, MatrixOrArrayOptions, Alignment>
|
struct plain_array<T, 0, MatrixOrArrayOptions, Alignment>
|
||||||
{
|
{
|
||||||
EIGEN_ALIGN16 T array[1];
|
EIGEN_USER_ALIGN16 T array[1];
|
||||||
plain_array() {}
|
plain_array() {}
|
||||||
plain_array(constructor_without_unaligned_array_assert) {}
|
plain_array(constructor_without_unaligned_array_assert) {}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ template<typename MatrixType, int DiagIndex> class Diagonal
|
|||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Diagonal)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Diagonal)
|
||||||
|
|
||||||
inline Index rows() const
|
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)(m_matrix.cols(),m_matrix.rows()+m_index.value()) : (std::min)(m_matrix.rows(),m_matrix.cols()-m_index.value()); }
|
||||||
|
|
||||||
inline Index cols() const { return 1; }
|
inline Index cols() const { return 1; }
|
||||||
|
|
||||||
|
|||||||
@@ -116,7 +116,9 @@ MatrixBase<Derived>::eigen2_dot(const MatrixBase<OtherDerived>& other) const
|
|||||||
|
|
||||||
//---------- implementation of L2 norm and related functions ----------
|
//---------- implementation of L2 norm and related functions ----------
|
||||||
|
|
||||||
/** \returns the squared \em l2 norm of *this, i.e., for vectors, the dot product of *this with itself.
|
/** \returns, for vectors, the squared \em l2 norm of \c *this, and for matrices the Frobenius norm.
|
||||||
|
* In both cases, it consists in the sum of the square of all the matrix entries.
|
||||||
|
* For vectors, this is also equals to the dot product of \c *this with itself.
|
||||||
*
|
*
|
||||||
* \sa dot(), norm()
|
* \sa dot(), norm()
|
||||||
*/
|
*/
|
||||||
@@ -126,7 +128,9 @@ EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scala
|
|||||||
return internal::real((*this).cwiseAbs2().sum());
|
return internal::real((*this).cwiseAbs2().sum());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the \em l2 norm of *this, i.e., for vectors, the square root of the dot product of *this with itself.
|
/** \returns, for vectors, the \em l2 norm of \c *this, and for matrices the Frobenius norm.
|
||||||
|
* In both cases, it consists in the square root of the sum of the square of all the matrix entries.
|
||||||
|
* For vectors, this is also equals to the square root of the dot product of \c *this with itself.
|
||||||
*
|
*
|
||||||
* \sa dot(), squaredNorm()
|
* \sa dot(), squaredNorm()
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ struct functor_traits<scalar_conj_product_op<LhsScalar,RhsScalar> > {
|
|||||||
*/
|
*/
|
||||||
template<typename Scalar> struct scalar_min_op {
|
template<typename Scalar> struct scalar_min_op {
|
||||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_min_op)
|
EIGEN_EMPTY_STRUCT_CTOR(scalar_min_op)
|
||||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::min(a, b); }
|
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { using std::min; return (min)(a, b); }
|
||||||
template<typename Packet>
|
template<typename Packet>
|
||||||
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||||
{ return internal::pmin(a,b); }
|
{ return internal::pmin(a,b); }
|
||||||
@@ -139,7 +139,7 @@ struct functor_traits<scalar_min_op<Scalar> > {
|
|||||||
*/
|
*/
|
||||||
template<typename Scalar> struct scalar_max_op {
|
template<typename Scalar> struct scalar_max_op {
|
||||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_max_op)
|
EIGEN_EMPTY_STRUCT_CTOR(scalar_max_op)
|
||||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::max(a, b); }
|
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { using std::max; return (max)(a, b); }
|
||||||
template<typename Packet>
|
template<typename Packet>
|
||||||
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||||
{ return internal::pmax(a,b); }
|
{ return internal::pmax(a,b); }
|
||||||
@@ -165,8 +165,10 @@ template<typename Scalar> struct scalar_hypot_op {
|
|||||||
// typedef typename NumTraits<Scalar>::Real result_type;
|
// typedef typename NumTraits<Scalar>::Real result_type;
|
||||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const
|
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const
|
||||||
{
|
{
|
||||||
Scalar p = std::max(_x, _y);
|
using std::max;
|
||||||
Scalar q = std::min(_x, _y);
|
using std::min;
|
||||||
|
Scalar p = (max)(_x, _y);
|
||||||
|
Scalar q = (min)(_x, _y);
|
||||||
Scalar qp = q/p;
|
Scalar qp = q/p;
|
||||||
return p * sqrt(Scalar(1) + qp*qp);
|
return p * sqrt(Scalar(1) + qp*qp);
|
||||||
}
|
}
|
||||||
@@ -605,7 +607,7 @@ template <typename Scalar, bool RandomAccess> struct linspaced_op
|
|||||||
EIGEN_STRONG_INLINE const Packet packetOp(Index row, Index col) const
|
EIGEN_STRONG_INLINE const Packet packetOp(Index row, Index col) const
|
||||||
{
|
{
|
||||||
eigen_assert(col==0 || row==0);
|
eigen_assert(col==0 || row==0);
|
||||||
return impl(col + row);
|
return impl.packetOp(col + row);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This proxy object handles the actual required temporaries, the different
|
// This proxy object handles the actual required temporaries, the different
|
||||||
@@ -669,7 +671,7 @@ struct functor_traits<scalar_sqrt_op<Scalar> >
|
|||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* \brief Template functor to compute the cosine of a scalar
|
* \brief Template functor to compute the cosine of a scalar
|
||||||
* \sa class CwiseUnaryOp, Cwise::cos()
|
* \sa class CwiseUnaryOp, ArrayBase::cos()
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct scalar_cos_op {
|
template<typename Scalar> struct scalar_cos_op {
|
||||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op)
|
EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op)
|
||||||
@@ -688,7 +690,7 @@ struct functor_traits<scalar_cos_op<Scalar> >
|
|||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* \brief Template functor to compute the sine of a scalar
|
* \brief Template functor to compute the sine of a scalar
|
||||||
* \sa class CwiseUnaryOp, Cwise::sin()
|
* \sa class CwiseUnaryOp, ArrayBase::sin()
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct scalar_sin_op {
|
template<typename Scalar> struct scalar_sin_op {
|
||||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op)
|
EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op)
|
||||||
@@ -708,7 +710,7 @@ struct functor_traits<scalar_sin_op<Scalar> >
|
|||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* \brief Template functor to compute the tan of a scalar
|
* \brief Template functor to compute the tan of a scalar
|
||||||
* \sa class CwiseUnaryOp, Cwise::tan()
|
* \sa class CwiseUnaryOp, ArrayBase::tan()
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct scalar_tan_op {
|
template<typename Scalar> struct scalar_tan_op {
|
||||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op)
|
EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op)
|
||||||
@@ -725,6 +727,44 @@ struct functor_traits<scalar_tan_op<Scalar> >
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** \internal
|
||||||
|
* \brief Template functor to compute the arc cosine of a scalar
|
||||||
|
* \sa class CwiseUnaryOp, ArrayBase::acos()
|
||||||
|
*/
|
||||||
|
template<typename Scalar> struct scalar_acos_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op)
|
||||||
|
inline const Scalar operator() (const Scalar& a) const { return acos(a); }
|
||||||
|
typedef typename packet_traits<Scalar>::type Packet;
|
||||||
|
inline Packet packetOp(const Packet& a) const { return internal::pacos(a); }
|
||||||
|
};
|
||||||
|
template<typename Scalar>
|
||||||
|
struct functor_traits<scalar_acos_op<Scalar> >
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
Cost = 5 * NumTraits<Scalar>::MulCost,
|
||||||
|
PacketAccess = packet_traits<Scalar>::HasACos
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \internal
|
||||||
|
* \brief Template functor to compute the arc sine of a scalar
|
||||||
|
* \sa class CwiseUnaryOp, ArrayBase::asin()
|
||||||
|
*/
|
||||||
|
template<typename Scalar> struct scalar_asin_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op)
|
||||||
|
inline const Scalar operator() (const Scalar& a) const { return asin(a); }
|
||||||
|
typedef typename packet_traits<Scalar>::type Packet;
|
||||||
|
inline Packet packetOp(const Packet& a) const { return internal::pasin(a); }
|
||||||
|
};
|
||||||
|
template<typename Scalar>
|
||||||
|
struct functor_traits<scalar_asin_op<Scalar> >
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
Cost = 5 * NumTraits<Scalar>::MulCost,
|
||||||
|
PacketAccess = packet_traits<Scalar>::HasASin
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* \brief Template functor to raise a scalar to a power
|
* \brief Template functor to raise a scalar to a power
|
||||||
* \sa class CwiseUnaryOp, Cwise::pow
|
* \sa class CwiseUnaryOp, Cwise::pow
|
||||||
|
|||||||
@@ -34,9 +34,10 @@ struct isApprox_selector
|
|||||||
{
|
{
|
||||||
static bool run(const Derived& x, const OtherDerived& y, typename Derived::RealScalar prec)
|
static bool run(const Derived& x, const OtherDerived& y, typename Derived::RealScalar prec)
|
||||||
{
|
{
|
||||||
|
using std::min;
|
||||||
const typename internal::nested<Derived,2>::type nested(x);
|
const typename internal::nested<Derived,2>::type nested(x);
|
||||||
const typename internal::nested<OtherDerived,2>::type otherNested(y);
|
const typename internal::nested<OtherDerived,2>::type otherNested(y);
|
||||||
return (nested - otherNested).cwiseAbs2().sum() <= prec * prec * std::min(nested.cwiseAbs2().sum(), otherNested.cwiseAbs2().sum());
|
return (nested - otherNested).cwiseAbs2().sum() <= prec * prec * (min)(nested.cwiseAbs2().sum(), otherNested.cwiseAbs2().sum());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -93,7 +94,7 @@ struct isMuchSmallerThan_scalar_selector<Derived, true>
|
|||||||
*
|
*
|
||||||
* \note The fuzzy compares are done multiplicatively. Two vectors \f$ v \f$ and \f$ w \f$
|
* \note The fuzzy compares are done multiplicatively. Two vectors \f$ v \f$ and \f$ w \f$
|
||||||
* are considered to be approximately equal within precision \f$ p \f$ if
|
* are considered to be approximately equal within precision \f$ p \f$ if
|
||||||
* \f[ \Vert v - w \Vert \leqslant p\,\min(\Vert v\Vert, \Vert w\Vert). \f]
|
* \f[ \Vert v - w \Vert \leqslant p\,\(min)(\Vert v\Vert, \Vert w\Vert). \f]
|
||||||
* For matrices, the comparison is done using the Hilbert-Schmidt norm (aka Frobenius norm
|
* For matrices, the comparison is done using the Hilbert-Schmidt norm (aka Frobenius norm
|
||||||
* L2 norm).
|
* L2 norm).
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -134,12 +134,12 @@ pdiv(const Packet& a,
|
|||||||
/** \internal \returns the min of \a a and \a b (coeff-wise) */
|
/** \internal \returns the min of \a a and \a b (coeff-wise) */
|
||||||
template<typename Packet> inline Packet
|
template<typename Packet> inline Packet
|
||||||
pmin(const Packet& a,
|
pmin(const Packet& a,
|
||||||
const Packet& b) { return std::min(a, b); }
|
const Packet& b) { using std::min; return (min)(a, b); }
|
||||||
|
|
||||||
/** \internal \returns the max of \a a and \a b (coeff-wise) */
|
/** \internal \returns the max of \a a and \a b (coeff-wise) */
|
||||||
template<typename Packet> inline Packet
|
template<typename Packet> inline Packet
|
||||||
pmax(const Packet& a,
|
pmax(const Packet& a,
|
||||||
const Packet& b) { return std::max(a, b); }
|
const Packet& b) { using std::max; return (max)(a, b); }
|
||||||
|
|
||||||
/** \internal \returns the absolute value of \a a */
|
/** \internal \returns the absolute value of \a a */
|
||||||
template<typename Packet> inline Packet
|
template<typename Packet> inline Packet
|
||||||
@@ -225,15 +225,20 @@ template<typename Packet> inline typename unpacket_traits<Packet>::type predux_m
|
|||||||
template<typename Packet> inline Packet preverse(const Packet& a)
|
template<typename Packet> inline Packet preverse(const Packet& a)
|
||||||
{ return a; }
|
{ return a; }
|
||||||
|
|
||||||
|
|
||||||
|
/** \internal \returns \a a with real and imaginary part flipped (for complex type only) */
|
||||||
|
template<typename Packet> inline Packet pcplxflip(const Packet& a)
|
||||||
|
{ return Packet(imag(a),real(a)); }
|
||||||
|
|
||||||
/**************************
|
/**************************
|
||||||
* Special math functions
|
* Special math functions
|
||||||
***************************/
|
***************************/
|
||||||
|
|
||||||
/** \internal \returns the sin of \a a (coeff-wise) */
|
/** \internal \returns the sine of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet psin(const Packet& a) { return sin(a); }
|
Packet psin(const Packet& a) { return sin(a); }
|
||||||
|
|
||||||
/** \internal \returns the cos of \a a (coeff-wise) */
|
/** \internal \returns the cosine of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet pcos(const Packet& a) { return cos(a); }
|
Packet pcos(const Packet& a) { return cos(a); }
|
||||||
|
|
||||||
@@ -241,6 +246,14 @@ Packet pcos(const Packet& a) { return cos(a); }
|
|||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet ptan(const Packet& a) { return tan(a); }
|
Packet ptan(const Packet& a) { return tan(a); }
|
||||||
|
|
||||||
|
/** \internal \returns the arc sine of \a a (coeff-wise) */
|
||||||
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
|
Packet pasin(const Packet& a) { return asin(a); }
|
||||||
|
|
||||||
|
/** \internal \returns the arc cosine of \a a (coeff-wise) */
|
||||||
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
|
Packet pacos(const Packet& a) { return acos(a); }
|
||||||
|
|
||||||
/** \internal \returns the exp of \a a (coeff-wise) */
|
/** \internal \returns the exp of \a a (coeff-wise) */
|
||||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
Packet pexp(const Packet& a) { return exp(a); }
|
Packet pexp(const Packet& a) { return exp(a); }
|
||||||
@@ -257,6 +270,14 @@ Packet psqrt(const Packet& a) { return sqrt(a); }
|
|||||||
* The following functions might not have to be overwritten for vectorized types
|
* The following functions might not have to be overwritten for vectorized types
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
/** \internal copy a packet with constant coeficient \a a (e.g., [a,a,a,a]) to \a *to. \a to must be 16 bytes aligned */
|
||||||
|
// NOTE: this function must really be templated on the packet type (think about different packet types for the same scalar type)
|
||||||
|
template<typename Packet>
|
||||||
|
inline void pstore1(typename unpacket_traits<Packet>::type* to, const typename unpacket_traits<Packet>::type& a)
|
||||||
|
{
|
||||||
|
pstore(to, pset1<Packet>(a));
|
||||||
|
}
|
||||||
|
|
||||||
/** \internal \returns a * b + c (coeff-wise) */
|
/** \internal \returns a * b + c (coeff-wise) */
|
||||||
template<typename Packet> inline Packet
|
template<typename Packet> inline Packet
|
||||||
pmadd(const Packet& a,
|
pmadd(const Packet& a,
|
||||||
@@ -265,7 +286,7 @@ pmadd(const Packet& a,
|
|||||||
{ return padd(pmul(a, b),c); }
|
{ return padd(pmul(a, b),c); }
|
||||||
|
|
||||||
/** \internal \returns a packet version of \a *from.
|
/** \internal \returns a packet version of \a *from.
|
||||||
* \If LoadMode equals Aligned, \a from must be 16 bytes aligned */
|
* If LoadMode equals #Aligned, \a from must be 16 bytes aligned */
|
||||||
template<typename Packet, int LoadMode>
|
template<typename Packet, int LoadMode>
|
||||||
inline Packet ploadt(const typename unpacket_traits<Packet>::type* from)
|
inline Packet ploadt(const typename unpacket_traits<Packet>::type* from)
|
||||||
{
|
{
|
||||||
@@ -276,7 +297,7 @@ inline Packet ploadt(const typename unpacket_traits<Packet>::type* from)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** \internal copy the packet \a from to \a *to.
|
/** \internal copy the packet \a from to \a *to.
|
||||||
* If StoreMode equals Aligned, \a to must be 16 bytes aligned */
|
* If StoreMode equals #Aligned, \a to must be 16 bytes aligned */
|
||||||
template<typename Scalar, typename Packet, int LoadMode>
|
template<typename Scalar, typename Packet, int LoadMode>
|
||||||
inline void pstoret(Scalar* to, const Packet& from)
|
inline void pstoret(Scalar* to, const Packet& from)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ namespace std
|
|||||||
EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(imag,scalar_imag_op)
|
EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(imag,scalar_imag_op)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(sin,scalar_sin_op)
|
EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(sin,scalar_sin_op)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(cos,scalar_cos_op)
|
EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(cos,scalar_cos_op)
|
||||||
|
EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(asin,scalar_asin_op)
|
||||||
|
EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(acos,scalar_acos_op)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(tan,scalar_tan_op)
|
EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(tan,scalar_tan_op)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(exp,scalar_exp_op)
|
EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(exp,scalar_exp_op)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(log,scalar_log_op)
|
EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(log,scalar_log_op)
|
||||||
@@ -77,6 +79,8 @@ namespace Eigen
|
|||||||
EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(imag,scalar_imag_op)
|
EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(imag,scalar_imag_op)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(sin,scalar_sin_op)
|
EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(sin,scalar_sin_op)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(cos,scalar_cos_op)
|
EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(cos,scalar_cos_op)
|
||||||
|
EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(asin,scalar_asin_op)
|
||||||
|
EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(acos,scalar_acos_op)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(tan,scalar_tan_op)
|
EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(tan,scalar_tan_op)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(exp,scalar_exp_op)
|
EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(exp,scalar_exp_op)
|
||||||
EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(log,scalar_log_op)
|
EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(log,scalar_log_op)
|
||||||
|
|||||||
@@ -141,7 +141,8 @@ struct significant_decimals_default_impl
|
|||||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||||
static inline int run()
|
static inline int run()
|
||||||
{
|
{
|
||||||
return cast<RealScalar,int>(std::ceil(-log(NumTraits<RealScalar>::epsilon())/log(RealScalar(10))));
|
using std::ceil;
|
||||||
|
return cast<RealScalar,int>(ceil(-log(NumTraits<RealScalar>::epsilon())/log(RealScalar(10))));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -31,10 +31,10 @@
|
|||||||
*
|
*
|
||||||
* \brief A matrix or vector expression mapping an existing array of data.
|
* \brief A matrix or vector expression mapping an existing array of data.
|
||||||
*
|
*
|
||||||
* \param PlainObjectType the equivalent matrix type of the mapped data
|
* \tparam PlainObjectType the equivalent matrix type of the mapped data
|
||||||
* \param MapOptions specifies whether the pointer is \c Aligned, or \c Unaligned.
|
* \tparam MapOptions specifies whether the pointer is \c #Aligned, or \c #Unaligned.
|
||||||
* The default is \c Unaligned.
|
* The default is \c #Unaligned.
|
||||||
* \param StrideType optionnally specifies strides. By default, Map assumes the memory layout
|
* \tparam StrideType optionnally specifies strides. By default, Map assumes the memory layout
|
||||||
* of an ordinary, contiguous array. This can be overridden by specifying strides.
|
* of an ordinary, contiguous array. This can be overridden by specifying strides.
|
||||||
* The type passed here must be a specialization of the Stride template, see examples below.
|
* The type passed here must be a specialization of the Stride template, see examples below.
|
||||||
*
|
*
|
||||||
@@ -95,7 +95,7 @@ struct traits<Map<PlainObjectType, MapOptions, StrideType> >
|
|||||||
HasNoInnerStride = InnerStrideAtCompileTime == 1,
|
HasNoInnerStride = InnerStrideAtCompileTime == 1,
|
||||||
HasNoOuterStride = StrideType::OuterStrideAtCompileTime == 0,
|
HasNoOuterStride = StrideType::OuterStrideAtCompileTime == 0,
|
||||||
HasNoStride = HasNoInnerStride && HasNoOuterStride,
|
HasNoStride = HasNoInnerStride && HasNoOuterStride,
|
||||||
IsAligned = int(int(MapOptions)&Aligned)==Aligned,
|
IsAligned = bool(EIGEN_ALIGN) && ((int(MapOptions)&Aligned)==Aligned),
|
||||||
IsDynamicSize = PlainObjectType::SizeAtCompileTime==Dynamic,
|
IsDynamicSize = PlainObjectType::SizeAtCompileTime==Dynamic,
|
||||||
KeepsPacketAccess = bool(HasNoInnerStride)
|
KeepsPacketAccess = bool(HasNoInnerStride)
|
||||||
&& ( bool(IsDynamicSize)
|
&& ( bool(IsDynamicSize)
|
||||||
@@ -192,14 +192,14 @@ template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int
|
|||||||
inline Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>
|
inline Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>
|
||||||
::Array(const Scalar *data)
|
::Array(const Scalar *data)
|
||||||
{
|
{
|
||||||
_set_noalias(Eigen::Map<const Array>(data));
|
this->_set_noalias(Eigen::Map<const Array>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
||||||
inline Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>
|
inline Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>
|
||||||
::Matrix(const Scalar *data)
|
::Matrix(const Scalar *data)
|
||||||
{
|
{
|
||||||
_set_noalias(Eigen::Map<const Matrix>(data));
|
this->_set_noalias(Eigen::Map<const Matrix>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // EIGEN_MAP_H
|
#endif // EIGEN_MAP_H
|
||||||
|
|||||||
@@ -85,6 +85,8 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
|||||||
using Base::rowStride;
|
using Base::rowStride;
|
||||||
using Base::colStride;
|
using Base::colStride;
|
||||||
|
|
||||||
|
// bug 217 - compile error on ICC 11.1
|
||||||
|
using Base::operator=;
|
||||||
|
|
||||||
typedef typename Base::CoeffReturnType CoeffReturnType;
|
typedef typename Base::CoeffReturnType CoeffReturnType;
|
||||||
|
|
||||||
@@ -236,7 +238,7 @@ template<typename Derived> class MapBase<Derived, WriteAccessors>
|
|||||||
(this->m_data + index * innerStride(), x);
|
(this->m_data + index * innerStride(), x);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline MapBase(PointerType data) : Base(data) {}
|
explicit inline MapBase(PointerType data) : Base(data) {}
|
||||||
inline MapBase(PointerType data, Index size) : Base(data, size) {}
|
inline MapBase(PointerType data, Index size) : Base(data, size) {}
|
||||||
inline MapBase(PointerType data, Index rows, Index cols) : Base(data, rows, cols) {}
|
inline MapBase(PointerType data, Index rows, Index cols) : Base(data, rows, cols) {}
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,8 @@ struct real_impl<std::complex<RealScalar> >
|
|||||||
{
|
{
|
||||||
static inline RealScalar run(const std::complex<RealScalar>& x)
|
static inline RealScalar run(const std::complex<RealScalar>& x)
|
||||||
{
|
{
|
||||||
return std::real(x);
|
using std::real;
|
||||||
|
return real(x);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -122,7 +123,8 @@ struct imag_impl<std::complex<RealScalar> >
|
|||||||
{
|
{
|
||||||
static inline RealScalar run(const std::complex<RealScalar>& x)
|
static inline RealScalar run(const std::complex<RealScalar>& x)
|
||||||
{
|
{
|
||||||
return std::imag(x);
|
using std::imag;
|
||||||
|
return imag(x);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -244,7 +246,8 @@ struct conj_impl<std::complex<RealScalar> >
|
|||||||
{
|
{
|
||||||
static inline std::complex<RealScalar> run(const std::complex<RealScalar>& x)
|
static inline std::complex<RealScalar> run(const std::complex<RealScalar>& x)
|
||||||
{
|
{
|
||||||
return std::conj(x);
|
using std::conj;
|
||||||
|
return conj(x);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -270,7 +273,8 @@ struct abs_impl
|
|||||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||||
static inline RealScalar run(const Scalar& x)
|
static inline RealScalar run(const Scalar& x)
|
||||||
{
|
{
|
||||||
return std::abs(x);
|
using std::abs;
|
||||||
|
return abs(x);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -305,7 +309,8 @@ struct abs2_impl<std::complex<RealScalar> >
|
|||||||
{
|
{
|
||||||
static inline RealScalar run(const std::complex<RealScalar>& x)
|
static inline RealScalar run(const std::complex<RealScalar>& x)
|
||||||
{
|
{
|
||||||
return std::norm(x);
|
using std::norm;
|
||||||
|
return norm(x);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -369,10 +374,12 @@ struct hypot_impl
|
|||||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||||
static inline RealScalar run(const Scalar& x, const Scalar& y)
|
static inline RealScalar run(const Scalar& x, const Scalar& y)
|
||||||
{
|
{
|
||||||
|
using std::max;
|
||||||
|
using std::min;
|
||||||
RealScalar _x = abs(x);
|
RealScalar _x = abs(x);
|
||||||
RealScalar _y = abs(y);
|
RealScalar _y = abs(y);
|
||||||
RealScalar p = std::max(_x, _y);
|
RealScalar p = (max)(_x, _y);
|
||||||
RealScalar q = std::min(_x, _y);
|
RealScalar q = (min)(_x, _y);
|
||||||
RealScalar qp = q/p;
|
RealScalar qp = q/p;
|
||||||
return p * sqrt(RealScalar(1) + qp*qp);
|
return p * sqrt(RealScalar(1) + qp*qp);
|
||||||
}
|
}
|
||||||
@@ -420,7 +427,8 @@ struct sqrt_default_impl
|
|||||||
{
|
{
|
||||||
static inline Scalar run(const Scalar& x)
|
static inline Scalar run(const Scalar& x)
|
||||||
{
|
{
|
||||||
return std::sqrt(x);
|
using std::sqrt;
|
||||||
|
return sqrt(x);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -454,194 +462,36 @@ inline EIGEN_MATHFUNC_RETVAL(sqrt, Scalar) sqrt(const Scalar& x)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Implementation of exp *
|
* Implementation of standard unary real functions (exp, log, sin, cos, ... *
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
template<typename Scalar, bool IsInteger>
|
// This macro instanciate all the necessary template mechanism which is common to all unary real functions.
|
||||||
struct exp_default_impl
|
#define EIGEN_MATHFUNC_STANDARD_REAL_UNARY(NAME) \
|
||||||
{
|
template<typename Scalar, bool IsInteger> struct NAME##_default_impl { \
|
||||||
static inline Scalar run(const Scalar& x)
|
static inline Scalar run(const Scalar& x) { using std::NAME; return NAME(x); } \
|
||||||
{
|
}; \
|
||||||
return std::exp(x);
|
template<typename Scalar> struct NAME##_default_impl<Scalar, true> { \
|
||||||
|
static inline Scalar run(const Scalar&) { \
|
||||||
|
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar) \
|
||||||
|
return Scalar(0); \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
template<typename Scalar> struct NAME##_impl \
|
||||||
|
: NAME##_default_impl<Scalar, NumTraits<Scalar>::IsInteger> \
|
||||||
|
{}; \
|
||||||
|
template<typename Scalar> struct NAME##_retval { typedef Scalar type; }; \
|
||||||
|
template<typename Scalar> \
|
||||||
|
inline EIGEN_MATHFUNC_RETVAL(NAME, Scalar) NAME(const Scalar& x) { \
|
||||||
|
return EIGEN_MATHFUNC_IMPL(NAME, Scalar)::run(x); \
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
EIGEN_MATHFUNC_STANDARD_REAL_UNARY(exp)
|
||||||
struct exp_default_impl<Scalar, true>
|
EIGEN_MATHFUNC_STANDARD_REAL_UNARY(log)
|
||||||
{
|
EIGEN_MATHFUNC_STANDARD_REAL_UNARY(sin)
|
||||||
static inline Scalar run(const Scalar&)
|
EIGEN_MATHFUNC_STANDARD_REAL_UNARY(cos)
|
||||||
{
|
EIGEN_MATHFUNC_STANDARD_REAL_UNARY(tan)
|
||||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
|
EIGEN_MATHFUNC_STANDARD_REAL_UNARY(asin)
|
||||||
return Scalar(0);
|
EIGEN_MATHFUNC_STANDARD_REAL_UNARY(acos)
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
|
||||||
struct exp_impl : exp_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
|
||||||
struct exp_retval
|
|
||||||
{
|
|
||||||
typedef Scalar type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
|
||||||
inline EIGEN_MATHFUNC_RETVAL(exp, Scalar) exp(const Scalar& x)
|
|
||||||
{
|
|
||||||
return EIGEN_MATHFUNC_IMPL(exp, Scalar)::run(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Implementation of cos *
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
template<typename Scalar, bool IsInteger>
|
|
||||||
struct cos_default_impl
|
|
||||||
{
|
|
||||||
static inline Scalar run(const Scalar& x)
|
|
||||||
{
|
|
||||||
return std::cos(x);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
|
||||||
struct cos_default_impl<Scalar, true>
|
|
||||||
{
|
|
||||||
static inline Scalar run(const Scalar&)
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
|
|
||||||
return Scalar(0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
|
||||||
struct cos_impl : cos_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
|
||||||
struct cos_retval
|
|
||||||
{
|
|
||||||
typedef Scalar type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
|
||||||
inline EIGEN_MATHFUNC_RETVAL(cos, Scalar) cos(const Scalar& x)
|
|
||||||
{
|
|
||||||
return EIGEN_MATHFUNC_IMPL(cos, Scalar)::run(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Implementation of sin *
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
template<typename Scalar, bool IsInteger>
|
|
||||||
struct sin_default_impl
|
|
||||||
{
|
|
||||||
static inline Scalar run(const Scalar& x)
|
|
||||||
{
|
|
||||||
return std::sin(x);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
|
||||||
struct sin_default_impl<Scalar, true>
|
|
||||||
{
|
|
||||||
static inline Scalar run(const Scalar&)
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
|
|
||||||
return Scalar(0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
|
||||||
struct sin_impl : sin_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
|
||||||
struct sin_retval
|
|
||||||
{
|
|
||||||
typedef Scalar type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
|
||||||
inline EIGEN_MATHFUNC_RETVAL(sin, Scalar) sin(const Scalar& x)
|
|
||||||
{
|
|
||||||
return EIGEN_MATHFUNC_IMPL(sin, Scalar)::run(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Implementation of tan *
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
template<typename Scalar, bool IsInteger>
|
|
||||||
struct tan_default_impl
|
|
||||||
{
|
|
||||||
static inline Scalar run(const Scalar& x)
|
|
||||||
{
|
|
||||||
return std::tan(x);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
|
||||||
struct tan_default_impl<Scalar, true>
|
|
||||||
{
|
|
||||||
static inline Scalar run(const Scalar&)
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
|
|
||||||
return Scalar(0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
|
||||||
struct tan_impl : tan_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
|
||||||
struct tan_retval
|
|
||||||
{
|
|
||||||
typedef Scalar type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
|
||||||
inline EIGEN_MATHFUNC_RETVAL(tan, Scalar) tan(const Scalar& x)
|
|
||||||
{
|
|
||||||
return EIGEN_MATHFUNC_IMPL(tan, Scalar)::run(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Implementation of log *
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
template<typename Scalar, bool IsInteger>
|
|
||||||
struct log_default_impl
|
|
||||||
{
|
|
||||||
static inline Scalar run(const Scalar& x)
|
|
||||||
{
|
|
||||||
return std::log(x);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
|
||||||
struct log_default_impl<Scalar, true>
|
|
||||||
{
|
|
||||||
static inline Scalar run(const Scalar&)
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
|
|
||||||
return Scalar(0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
|
||||||
struct log_impl : log_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
|
||||||
struct log_retval
|
|
||||||
{
|
|
||||||
typedef Scalar type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Scalar>
|
|
||||||
inline EIGEN_MATHFUNC_RETVAL(log, Scalar) log(const Scalar& x)
|
|
||||||
{
|
|
||||||
return EIGEN_MATHFUNC_IMPL(log, Scalar)::run(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Implementation of atan2 *
|
* Implementation of atan2 *
|
||||||
@@ -653,7 +503,8 @@ struct atan2_default_impl
|
|||||||
typedef Scalar retval;
|
typedef Scalar retval;
|
||||||
static inline Scalar run(const Scalar& x, const Scalar& y)
|
static inline Scalar run(const Scalar& x, const Scalar& y)
|
||||||
{
|
{
|
||||||
return std::atan2(x, y);
|
using std::atan2;
|
||||||
|
return atan2(x, y);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -692,7 +543,8 @@ struct pow_default_impl
|
|||||||
typedef Scalar retval;
|
typedef Scalar retval;
|
||||||
static inline Scalar run(const Scalar& x, const Scalar& y)
|
static inline Scalar run(const Scalar& x, const Scalar& y)
|
||||||
{
|
{
|
||||||
return std::pow(x, y);
|
using std::pow;
|
||||||
|
return pow(x, y);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -884,7 +736,8 @@ struct scalar_fuzzy_default_impl<Scalar, false, false>
|
|||||||
}
|
}
|
||||||
static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
|
static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
|
||||||
{
|
{
|
||||||
return abs(x - y) <= std::min(abs(x), abs(y)) * prec;
|
using std::min;
|
||||||
|
return abs(x - y) <= (min)(abs(x), abs(y)) * prec;
|
||||||
}
|
}
|
||||||
static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar& prec)
|
static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar& prec)
|
||||||
{
|
{
|
||||||
@@ -922,7 +775,8 @@ struct scalar_fuzzy_default_impl<Scalar, true, false>
|
|||||||
}
|
}
|
||||||
static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
|
static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
|
||||||
{
|
{
|
||||||
return abs2(x - y) <= std::min(abs2(x), abs2(y)) * prec * prec;
|
using std::min;
|
||||||
|
return abs2(x - y) <= (min)(abs2(x), abs2(y)) * prec * prec;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -43,8 +43,8 @@
|
|||||||
* \tparam _Cols Number of columns, or \b Dynamic
|
* \tparam _Cols Number of columns, or \b Dynamic
|
||||||
*
|
*
|
||||||
* The remaining template parameters are optional -- in most cases you don't have to worry about them.
|
* The remaining template parameters are optional -- in most cases you don't have to worry about them.
|
||||||
* \tparam _Options \anchor matrix_tparam_options A combination of either \b RowMajor or \b ColMajor, and of either
|
* \tparam _Options \anchor matrix_tparam_options A combination of either \b #RowMajor or \b #ColMajor, and of either
|
||||||
* \b AutoAlign or \b DontAlign.
|
* \b #AutoAlign or \b #DontAlign.
|
||||||
* The former controls \ref TopicStorageOrders "storage order", and defaults to column-major. The latter controls alignment, which is required
|
* The former controls \ref TopicStorageOrders "storage order", and defaults to column-major. The latter controls alignment, which is required
|
||||||
* for vectorization. It defaults to aligning matrices except for fixed sizes that aren't a multiple of the packet size.
|
* for vectorization. It defaults to aligning matrices except for fixed sizes that aren't a multiple of the packet size.
|
||||||
* \tparam _MaxRows Maximum number of rows. Defaults to \a _Rows (\ref maxrows "note").
|
* \tparam _MaxRows Maximum number of rows. Defaults to \a _Rows (\ref maxrows "note").
|
||||||
@@ -79,6 +79,9 @@
|
|||||||
* m(0, 3) = 3;
|
* m(0, 3) = 3;
|
||||||
* \endcode
|
* \endcode
|
||||||
*
|
*
|
||||||
|
* This class can be extended with the help of the plugin mechanism described on the page
|
||||||
|
* \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_MATRIX_PLUGIN.
|
||||||
|
*
|
||||||
* <i><b>Some notes:</b></i>
|
* <i><b>Some notes:</b></i>
|
||||||
*
|
*
|
||||||
* <dl>
|
* <dl>
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
* Note that some methods are defined in other modules such as the \ref LU_Module LU module
|
* Note that some methods are defined in other modules such as the \ref LU_Module LU module
|
||||||
* for all functions related to matrix inversions.
|
* for all functions related to matrix inversions.
|
||||||
*
|
*
|
||||||
* \param Derived is the derived type, e.g. a matrix type, or an expression, etc.
|
* \tparam Derived is the derived type, e.g. a matrix type, or an expression, etc.
|
||||||
*
|
*
|
||||||
* When writing a function taking Eigen objects as argument, if you want your function
|
* When writing a function taking Eigen objects as argument, if you want your function
|
||||||
* to take as argument any matrix, vector, or expression, just let it take a
|
* to take as argument any matrix, vector, or expression, just let it take a
|
||||||
@@ -53,6 +53,9 @@
|
|||||||
}
|
}
|
||||||
* \endcode
|
* \endcode
|
||||||
*
|
*
|
||||||
|
* This class can be extended with the help of the plugin mechanism described on the page
|
||||||
|
* \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_MATRIXBASE_PLUGIN.
|
||||||
|
*
|
||||||
* \sa \ref TopicClassHierarchy
|
* \sa \ref TopicClassHierarchy
|
||||||
*/
|
*/
|
||||||
template<typename Derived> class MatrixBase
|
template<typename Derived> class MatrixBase
|
||||||
@@ -108,7 +111,7 @@ template<typename Derived> class MatrixBase
|
|||||||
|
|
||||||
/** \returns the size of the main diagonal, which is min(rows(),cols()).
|
/** \returns the size of the main diagonal, which is min(rows(),cols()).
|
||||||
* \sa rows(), cols(), SizeAtCompileTime. */
|
* \sa rows(), cols(), SizeAtCompileTime. */
|
||||||
inline Index diagonalSize() const { return std::min(rows(),cols()); }
|
inline Index diagonalSize() const { return (std::min)(rows(),cols()); }
|
||||||
|
|
||||||
/** \brief The plain matrix type corresponding to this expression.
|
/** \brief The plain matrix type corresponding to this expression.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -87,8 +87,8 @@ template<typename T> struct GenericNumTraits
|
|||||||
// make sure to override this for floating-point types
|
// make sure to override this for floating-point types
|
||||||
return Real(0);
|
return Real(0);
|
||||||
}
|
}
|
||||||
inline static T highest() { return std::numeric_limits<T>::max(); }
|
inline static T highest() { return (std::numeric_limits<T>::max)(); }
|
||||||
inline static T lowest() { return IsInteger ? std::numeric_limits<T>::min() : (-std::numeric_limits<T>::max()); }
|
inline static T lowest() { return IsInteger ? (std::numeric_limits<T>::min)() : (-(std::numeric_limits<T>::max)()); }
|
||||||
|
|
||||||
#ifdef EIGEN2_SUPPORT
|
#ifdef EIGEN2_SUPPORT
|
||||||
enum {
|
enum {
|
||||||
|
|||||||
@@ -42,6 +42,10 @@ template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct m
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief %Dense storage base class for matrices and arrays.
|
* \brief %Dense storage base class for matrices and arrays.
|
||||||
|
*
|
||||||
|
* This class can be extended with the help of the plugin mechanism described on the page
|
||||||
|
* \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_PLAINOBJECTBASE_PLUGIN.
|
||||||
|
*
|
||||||
* \sa \ref TopicClassHierarchy
|
* \sa \ref TopicClassHierarchy
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
@@ -283,33 +287,47 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
else resize(other.rows(), other.cols());
|
else resize(other.rows(), other.cols());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resizes \c *this to a \a rows x \a cols matrix while leaving old values of \c *this untouched.
|
/** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
|
||||||
*
|
*
|
||||||
* This method is intended for dynamic-size matrices. If you only want to change the number
|
* The method is intended for matrices of dynamic size. If you only want to change the number
|
||||||
* of rows and/or of columns, you can use conservativeResize(NoChange_t, Index),
|
* of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or
|
||||||
* conservativeResize(Index, NoChange_t).
|
* conservativeResize(Index, NoChange_t).
|
||||||
*
|
*
|
||||||
* The top-left part of the resized matrix will be the same as the overlapping top-left corner
|
* Matrices are resized relative to the top-left element. In case values need to be
|
||||||
* of \c *this. In case values need to be appended to the matrix they will be uninitialized.
|
* appended to the matrix they will be uninitialized.
|
||||||
*/
|
*/
|
||||||
EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols)
|
EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols)
|
||||||
{
|
{
|
||||||
internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols);
|
internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
|
||||||
|
*
|
||||||
|
* As opposed to conservativeResize(Index rows, Index cols), this version leaves
|
||||||
|
* the number of columns unchanged.
|
||||||
|
*
|
||||||
|
* In case the matrix is growing, new rows will be uninitialized.
|
||||||
|
*/
|
||||||
EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t)
|
EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t)
|
||||||
{
|
{
|
||||||
// Note: see the comment in conservativeResize(Index,Index)
|
// Note: see the comment in conservativeResize(Index,Index)
|
||||||
conservativeResize(rows, cols());
|
conservativeResize(rows, cols());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
|
||||||
|
*
|
||||||
|
* As opposed to conservativeResize(Index rows, Index cols), this version leaves
|
||||||
|
* the number of rows unchanged.
|
||||||
|
*
|
||||||
|
* In case the matrix is growing, new columns will be uninitialized.
|
||||||
|
*/
|
||||||
EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols)
|
EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols)
|
||||||
{
|
{
|
||||||
// Note: see the comment in conservativeResize(Index,Index)
|
// Note: see the comment in conservativeResize(Index,Index)
|
||||||
conservativeResize(rows(), cols);
|
conservativeResize(rows(), cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resizes \c *this to a vector of length \a size while retaining old values of *this.
|
/** Resizes the vector to \a size while retaining old values.
|
||||||
*
|
*
|
||||||
* \only_for_vectors. This method does not work for
|
* \only_for_vectors. This method does not work for
|
||||||
* partially dynamic matrices when the static dimension is anything other
|
* partially dynamic matrices when the static dimension is anything other
|
||||||
@@ -322,6 +340,15 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
internal::conservative_resize_like_impl<Derived>::run(*this, size);
|
internal::conservative_resize_like_impl<Derived>::run(*this, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Resizes the matrix to \a rows x \a cols of \c other, while leaving old values untouched.
|
||||||
|
*
|
||||||
|
* The method is intended for matrices of dynamic size. If you only want to change the number
|
||||||
|
* of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or
|
||||||
|
* conservativeResize(Index, NoChange_t).
|
||||||
|
*
|
||||||
|
* Matrices are resized relative to the top-left element. In case values need to be
|
||||||
|
* appended to the matrix they will copied from \c other.
|
||||||
|
*/
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other)
|
EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other)
|
||||||
{
|
{
|
||||||
@@ -620,8 +647,8 @@ struct internal::conservative_resize_like_impl
|
|||||||
{
|
{
|
||||||
// The storage order does not allow us to use reallocation.
|
// The storage order does not allow us to use reallocation.
|
||||||
typename Derived::PlainObject tmp(rows,cols);
|
typename Derived::PlainObject tmp(rows,cols);
|
||||||
const Index common_rows = std::min(rows, _this.rows());
|
const Index common_rows = (std::min)(rows, _this.rows());
|
||||||
const Index common_cols = std::min(cols, _this.cols());
|
const Index common_cols = (std::min)(cols, _this.cols());
|
||||||
tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
|
tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
|
||||||
_this.derived().swap(tmp);
|
_this.derived().swap(tmp);
|
||||||
}
|
}
|
||||||
@@ -654,8 +681,8 @@ struct internal::conservative_resize_like_impl
|
|||||||
{
|
{
|
||||||
// The storage order does not allow us to use reallocation.
|
// The storage order does not allow us to use reallocation.
|
||||||
typename Derived::PlainObject tmp(other);
|
typename Derived::PlainObject tmp(other);
|
||||||
const Index common_rows = std::min(tmp.rows(), _this.rows());
|
const Index common_rows = (std::min)(tmp.rows(), _this.rows());
|
||||||
const Index common_cols = std::min(tmp.cols(), _this.cols());
|
const Index common_cols = (std::min)(tmp.cols(), _this.cols());
|
||||||
tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
|
tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
|
||||||
_this.derived().swap(tmp);
|
_this.derived().swap(tmp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -375,8 +375,23 @@ struct gemv_static_vector_if<Scalar,Size,Dynamic,true>
|
|||||||
template<typename Scalar,int Size,int MaxSize>
|
template<typename Scalar,int Size,int MaxSize>
|
||||||
struct gemv_static_vector_if<Scalar,Size,MaxSize,true>
|
struct gemv_static_vector_if<Scalar,Size,MaxSize,true>
|
||||||
{
|
{
|
||||||
|
#if EIGEN_ALIGN_STATICALLY
|
||||||
internal::plain_array<Scalar,EIGEN_SIZE_MIN_PREFER_FIXED(Size,MaxSize),0> m_data;
|
internal::plain_array<Scalar,EIGEN_SIZE_MIN_PREFER_FIXED(Size,MaxSize),0> m_data;
|
||||||
EIGEN_STRONG_INLINE Scalar* data() { return m_data.array; }
|
EIGEN_STRONG_INLINE Scalar* data() { return m_data.array; }
|
||||||
|
#else
|
||||||
|
// Some architectures cannot align on the stack,
|
||||||
|
// => let's manually enforce alignment by allocating more data and return the address of the first aligned element.
|
||||||
|
enum {
|
||||||
|
ForceAlignment = internal::packet_traits<Scalar>::Vectorizable,
|
||||||
|
PacketSize = internal::packet_traits<Scalar>::size
|
||||||
|
};
|
||||||
|
internal::plain_array<Scalar,EIGEN_SIZE_MIN_PREFER_FIXED(Size,MaxSize)+(ForceAlignment?PacketSize:0),0> m_data;
|
||||||
|
EIGEN_STRONG_INLINE Scalar* data() {
|
||||||
|
return ForceAlignment
|
||||||
|
? reinterpret_cast<Scalar*>((reinterpret_cast<size_t>(m_data.array) & ~(size_t(15))) + 16)
|
||||||
|
: m_data.array;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> struct gemv_selector<OnTheRight,ColMajor,true>
|
template<> struct gemv_selector<OnTheRight,ColMajor,true>
|
||||||
@@ -411,28 +426,21 @@ template<> struct gemv_selector<OnTheRight,ColMajor,true>
|
|||||||
|
|
||||||
gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest;
|
gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest;
|
||||||
|
|
||||||
bool alphaIsCompatible = (!ComplexByReal) || (imag(actualAlpha)==RealScalar(0));
|
// this is written like this (i.e., with a ?:) to workaround an ICE with ICC 12
|
||||||
|
bool alphaIsCompatible = (!ComplexByReal) ? true : (imag(actualAlpha)==RealScalar(0));
|
||||||
bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
|
bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
|
||||||
|
|
||||||
RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
|
RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
|
||||||
|
|
||||||
ResScalar* actualDestPtr;
|
ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(),
|
||||||
bool freeDestPtr = false;
|
evalToDest ? dest.data() : static_dest.data());
|
||||||
if (evalToDest)
|
|
||||||
{
|
if(!evalToDest)
|
||||||
actualDestPtr = &dest.coeffRef(0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||||
int size = dest.size();
|
int size = dest.size();
|
||||||
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||||
#endif
|
#endif
|
||||||
if((actualDestPtr = static_dest.data())==0)
|
|
||||||
{
|
|
||||||
freeDestPtr = true;
|
|
||||||
actualDestPtr = ei_aligned_stack_new(ResScalar,dest.size());
|
|
||||||
}
|
|
||||||
if(!alphaIsCompatible)
|
if(!alphaIsCompatible)
|
||||||
{
|
{
|
||||||
MappedDest(actualDestPtr, dest.size()).setZero();
|
MappedDest(actualDestPtr, dest.size()).setZero();
|
||||||
@@ -456,7 +464,6 @@ template<> struct gemv_selector<OnTheRight,ColMajor,true>
|
|||||||
dest += actualAlpha * MappedDest(actualDestPtr, dest.size());
|
dest += actualAlpha * MappedDest(actualDestPtr, dest.size());
|
||||||
else
|
else
|
||||||
dest = MappedDest(actualDestPtr, dest.size());
|
dest = MappedDest(actualDestPtr, dest.size());
|
||||||
if(freeDestPtr) ei_aligned_stack_delete(ResScalar, actualDestPtr, dest.size());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -490,23 +497,15 @@ template<> struct gemv_selector<OnTheRight,RowMajor,true>
|
|||||||
|
|
||||||
gemv_static_vector_if<RhsScalar,_ActualRhsType::SizeAtCompileTime,_ActualRhsType::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs;
|
gemv_static_vector_if<RhsScalar,_ActualRhsType::SizeAtCompileTime,_ActualRhsType::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs;
|
||||||
|
|
||||||
RhsScalar* actualRhsPtr;
|
ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(),
|
||||||
bool freeRhsPtr = false;
|
DirectlyUseRhs ? const_cast<RhsScalar*>(actualRhs.data()) : static_rhs.data());
|
||||||
if (DirectlyUseRhs)
|
|
||||||
{
|
if(!DirectlyUseRhs)
|
||||||
actualRhsPtr = const_cast<RhsScalar*>(&actualRhs.coeffRef(0));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||||
int size = actualRhs.size();
|
int size = actualRhs.size();
|
||||||
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||||
#endif
|
#endif
|
||||||
if((actualRhsPtr = static_rhs.data())==0)
|
|
||||||
{
|
|
||||||
freeRhsPtr = true;
|
|
||||||
actualRhsPtr = ei_aligned_stack_new(RhsScalar, actualRhs.size());
|
|
||||||
}
|
|
||||||
Map<typename _ActualRhsType::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs;
|
Map<typename _ActualRhsType::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -517,8 +516,6 @@ template<> struct gemv_selector<OnTheRight,RowMajor,true>
|
|||||||
actualRhsPtr, 1,
|
actualRhsPtr, 1,
|
||||||
&dest.coeffRef(0,0), dest.innerStride(),
|
&dest.coeffRef(0,0), dest.innerStride(),
|
||||||
actualAlpha);
|
actualAlpha);
|
||||||
|
|
||||||
if((!DirectlyUseRhs) && freeRhsPtr) ei_aligned_stack_delete(RhsScalar, actualRhsPtr, prod.rhs().size());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ struct redux_impl<Func, Derived, LinearVectorizedTraversal, NoUnrolling>
|
|||||||
const Index packetSize = packet_traits<Scalar>::size;
|
const Index packetSize = packet_traits<Scalar>::size;
|
||||||
const Index alignedStart = first_aligned(mat);
|
const Index alignedStart = first_aligned(mat);
|
||||||
enum {
|
enum {
|
||||||
alignment = (Derived::Flags & DirectAccessBit) || (Derived::Flags & AlignedBit)
|
alignment = bool(Derived::Flags & DirectAccessBit) || bool(Derived::Flags & AlignedBit)
|
||||||
? Aligned : Unaligned
|
? Aligned : Unaligned
|
||||||
};
|
};
|
||||||
const Index alignedSize = ((size-alignedStart)/packetSize)*packetSize;
|
const Index alignedSize = ((size-alignedStart)/packetSize)*packetSize;
|
||||||
|
|||||||
@@ -71,9 +71,9 @@ template<typename Derived> class ReturnByValue
|
|||||||
|
|
||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
inline void evalTo(Dest& dst) const
|
inline void evalTo(Dest& dst) const
|
||||||
{ static_cast<const Derived* const>(this)->evalTo(dst); }
|
{ static_cast<const Derived*>(this)->evalTo(dst); }
|
||||||
inline Index rows() const { return static_cast<const Derived* const>(this)->rows(); }
|
inline Index rows() const { return static_cast<const Derived*>(this)->rows(); }
|
||||||
inline Index cols() const { return static_cast<const Derived* const>(this)->cols(); }
|
inline Index cols() const { return static_cast<const Derived*>(this)->cols(); }
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
#define Unusable YOU_ARE_TRYING_TO_ACCESS_A_SINGLE_COEFFICIENT_IN_A_SPECIAL_EXPRESSION_WHERE_THAT_IS_NOT_ALLOWED_BECAUSE_THAT_WOULD_BE_INEFFICIENT
|
#define Unusable YOU_ARE_TRYING_TO_ACCESS_A_SINGLE_COEFFICIENT_IN_A_SPECIAL_EXPRESSION_WHERE_THAT_IS_NOT_ALLOWED_BECAUSE_THAT_WOULD_BE_INEFFICIENT
|
||||||
|
|||||||
@@ -32,13 +32,13 @@
|
|||||||
* \brief Expression of a selfadjoint matrix from a triangular part of a dense matrix
|
* \brief Expression of a selfadjoint matrix from a triangular part of a dense matrix
|
||||||
*
|
*
|
||||||
* \param MatrixType the type of the dense matrix storing the coefficients
|
* \param MatrixType the type of the dense matrix storing the coefficients
|
||||||
* \param TriangularPart can be either \c Lower or \c Upper
|
* \param TriangularPart can be either \c #Lower or \c #Upper
|
||||||
*
|
*
|
||||||
* This class is an expression of a sefladjoint matrix from a triangular part of a matrix
|
* This class is an expression of a sefladjoint matrix from a triangular part of a matrix
|
||||||
* with given dense storage of the coefficients. It is the return type of MatrixBase::selfadjointView()
|
* with given dense storage of the coefficients. It is the return type of MatrixBase::selfadjointView()
|
||||||
* and most of the time this is the only way that it is used.
|
* and most of the time this is the only way that it is used.
|
||||||
*
|
*
|
||||||
* \sa class TriangularBase, MatrixBase::selfAdjointView()
|
* \sa class TriangularBase, MatrixBase::selfadjointView()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|||||||
@@ -74,26 +74,19 @@ struct triangular_solver_selector<Lhs,Rhs,Side,Mode,NoUnrolling,1>
|
|||||||
// FIXME find a way to allow an inner stride if packet_traits<Scalar>::size==1
|
// FIXME find a way to allow an inner stride if packet_traits<Scalar>::size==1
|
||||||
|
|
||||||
bool useRhsDirectly = Rhs::InnerStrideAtCompileTime==1 || rhs.innerStride()==1;
|
bool useRhsDirectly = Rhs::InnerStrideAtCompileTime==1 || rhs.innerStride()==1;
|
||||||
RhsScalar* actualRhs;
|
|
||||||
if(useRhsDirectly)
|
ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhs,rhs.size(),
|
||||||
{
|
(useRhsDirectly ? rhs.data() : 0));
|
||||||
actualRhs = &rhs.coeffRef(0);
|
|
||||||
}
|
if(!useRhsDirectly)
|
||||||
else
|
|
||||||
{
|
|
||||||
actualRhs = ei_aligned_stack_new(RhsScalar,rhs.size());
|
|
||||||
MappedRhs(actualRhs,rhs.size()) = rhs;
|
MappedRhs(actualRhs,rhs.size()) = rhs;
|
||||||
}
|
|
||||||
|
|
||||||
triangular_solve_vector<LhsScalar, RhsScalar, typename Lhs::Index, Side, Mode, LhsProductTraits::NeedToConjugate,
|
triangular_solve_vector<LhsScalar, RhsScalar, typename Lhs::Index, Side, Mode, LhsProductTraits::NeedToConjugate,
|
||||||
(int(Lhs::Flags) & RowMajorBit) ? RowMajor : ColMajor>
|
(int(Lhs::Flags) & RowMajorBit) ? RowMajor : ColMajor>
|
||||||
::run(actualLhs.cols(), actualLhs.data(), actualLhs.outerStride(), actualRhs);
|
::run(actualLhs.cols(), actualLhs.data(), actualLhs.outerStride(), actualRhs);
|
||||||
|
|
||||||
if(!useRhsDirectly)
|
if(!useRhsDirectly)
|
||||||
{
|
|
||||||
rhs = MappedRhs(actualRhs, rhs.size());
|
rhs = MappedRhs(actualRhs, rhs.size());
|
||||||
ei_aligned_stack_delete(RhsScalar, actualRhs, rhs.size());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ template<typename Derived>
|
|||||||
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
|
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
|
||||||
MatrixBase<Derived>::stableNorm() const
|
MatrixBase<Derived>::stableNorm() const
|
||||||
{
|
{
|
||||||
|
using std::min;
|
||||||
const Index blockSize = 4096;
|
const Index blockSize = 4096;
|
||||||
RealScalar scale = 0;
|
RealScalar scale = 0;
|
||||||
RealScalar invScale = 1;
|
RealScalar invScale = 1;
|
||||||
@@ -68,7 +69,7 @@ MatrixBase<Derived>::stableNorm() const
|
|||||||
if (bi>0)
|
if (bi>0)
|
||||||
internal::stable_norm_kernel(this->head(bi), ssq, scale, invScale);
|
internal::stable_norm_kernel(this->head(bi), ssq, scale, invScale);
|
||||||
for (; bi<n; bi+=blockSize)
|
for (; bi<n; bi+=blockSize)
|
||||||
internal::stable_norm_kernel(this->segment(bi,std::min(blockSize, n - bi)).template forceAlignedAccessIf<Alignment>(), ssq, scale, invScale);
|
internal::stable_norm_kernel(this->segment(bi,(min)(blockSize, n - bi)).template forceAlignedAccessIf<Alignment>(), ssq, scale, invScale);
|
||||||
return scale * internal::sqrt(ssq);
|
return scale * internal::sqrt(ssq);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,6 +86,9 @@ template<typename Derived>
|
|||||||
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
|
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
|
||||||
MatrixBase<Derived>::blueNorm() const
|
MatrixBase<Derived>::blueNorm() const
|
||||||
{
|
{
|
||||||
|
using std::pow;
|
||||||
|
using std::min;
|
||||||
|
using std::max;
|
||||||
static Index nmax = -1;
|
static Index nmax = -1;
|
||||||
static RealScalar b1, b2, s1m, s2m, overfl, rbig, relerr;
|
static RealScalar b1, b2, s1m, s2m, overfl, rbig, relerr;
|
||||||
if(nmax <= 0)
|
if(nmax <= 0)
|
||||||
@@ -99,25 +103,25 @@ MatrixBase<Derived>::blueNorm() const
|
|||||||
// For portability, the PORT subprograms "ilmaeh" and "rlmach"
|
// For portability, the PORT subprograms "ilmaeh" and "rlmach"
|
||||||
// are used. For any specific computer, each of the assignment
|
// are used. For any specific computer, each of the assignment
|
||||||
// statements can be replaced
|
// statements can be replaced
|
||||||
nbig = std::numeric_limits<Index>::max(); // largest integer
|
nbig = (std::numeric_limits<Index>::max)(); // largest integer
|
||||||
ibeta = std::numeric_limits<RealScalar>::radix; // base for floating-point numbers
|
ibeta = std::numeric_limits<RealScalar>::radix; // base for floating-point numbers
|
||||||
it = std::numeric_limits<RealScalar>::digits; // number of base-beta digits in mantissa
|
it = std::numeric_limits<RealScalar>::digits; // number of base-beta digits in mantissa
|
||||||
iemin = std::numeric_limits<RealScalar>::min_exponent; // minimum exponent
|
iemin = std::numeric_limits<RealScalar>::min_exponent; // minimum exponent
|
||||||
iemax = std::numeric_limits<RealScalar>::max_exponent; // maximum exponent
|
iemax = std::numeric_limits<RealScalar>::max_exponent; // maximum exponent
|
||||||
rbig = std::numeric_limits<RealScalar>::max(); // largest floating-point number
|
rbig = (std::numeric_limits<RealScalar>::max)(); // largest floating-point number
|
||||||
|
|
||||||
iexp = -((1-iemin)/2);
|
iexp = -((1-iemin)/2);
|
||||||
b1 = RealScalar(std::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;
|
iexp = (iemax + 1 - it)/2;
|
||||||
b2 = RealScalar(std::pow(RealScalar(ibeta),RealScalar(iexp))); // upper boundary of midrange
|
b2 = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // upper boundary of midrange
|
||||||
|
|
||||||
iexp = (2-iemin)/2;
|
iexp = (2-iemin)/2;
|
||||||
s1m = RealScalar(std::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);
|
iexp = - ((iemax+it)/2);
|
||||||
s2m = RealScalar(std::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(std::pow(double(ibeta), 1-it));
|
eps = RealScalar(pow(double(ibeta), 1-it));
|
||||||
relerr = internal::sqrt(eps); // tolerance for neglecting asml
|
relerr = internal::sqrt(eps); // tolerance for neglecting asml
|
||||||
abig = RealScalar(1.0/eps - 1.0);
|
abig = RealScalar(1.0/eps - 1.0);
|
||||||
if (RealScalar(nbig)>abig) nmax = int(abig); // largest safe n
|
if (RealScalar(nbig)>abig) nmax = int(abig); // largest safe n
|
||||||
@@ -163,8 +167,8 @@ MatrixBase<Derived>::blueNorm() const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
return internal::sqrt(amed);
|
return internal::sqrt(amed);
|
||||||
asml = std::min(abig, amed);
|
asml = (min)(abig, amed);
|
||||||
abig = std::max(abig, amed);
|
abig = (max)(abig, amed);
|
||||||
if(asml <= abig*relerr)
|
if(asml <= abig*relerr)
|
||||||
return abig;
|
return abig;
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -350,15 +350,14 @@ struct blas_traits<SelfCwiseBinaryOp<BinOp,NestedXpr,Rhs> >
|
|||||||
template<bool DestIsTransposed, typename OtherDerived>
|
template<bool DestIsTransposed, typename OtherDerived>
|
||||||
struct check_transpose_aliasing_compile_time_selector
|
struct check_transpose_aliasing_compile_time_selector
|
||||||
{
|
{
|
||||||
enum { ret = blas_traits<OtherDerived>::IsTransposed != DestIsTransposed
|
enum { ret = bool(blas_traits<OtherDerived>::IsTransposed) != DestIsTransposed };
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<bool DestIsTransposed, typename BinOp, typename DerivedA, typename DerivedB>
|
template<bool DestIsTransposed, typename BinOp, typename DerivedA, typename DerivedB>
|
||||||
struct check_transpose_aliasing_compile_time_selector<DestIsTransposed,CwiseBinaryOp<BinOp,DerivedA,DerivedB> >
|
struct check_transpose_aliasing_compile_time_selector<DestIsTransposed,CwiseBinaryOp<BinOp,DerivedA,DerivedB> >
|
||||||
{
|
{
|
||||||
enum { ret = blas_traits<DerivedA>::IsTransposed != DestIsTransposed
|
enum { ret = bool(blas_traits<DerivedA>::IsTransposed) != DestIsTransposed
|
||||||
|| blas_traits<DerivedB>::IsTransposed != DestIsTransposed
|
|| bool(blas_traits<DerivedB>::IsTransposed) != DestIsTransposed
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -367,7 +366,7 @@ struct check_transpose_aliasing_run_time_selector
|
|||||||
{
|
{
|
||||||
static bool run(const Scalar* dest, const OtherDerived& src)
|
static bool run(const Scalar* dest, const OtherDerived& src)
|
||||||
{
|
{
|
||||||
return (blas_traits<OtherDerived>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(Scalar*)extract_data(src));
|
return (bool(blas_traits<OtherDerived>::IsTransposed) != DestIsTransposed) && (dest!=0 && dest==(Scalar*)extract_data(src));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ template<typename Derived> class TriangularBase : public EigenBase<Derived>
|
|||||||
EIGEN_ONLY_USED_FOR_DEBUG(col);
|
EIGEN_ONLY_USED_FOR_DEBUG(col);
|
||||||
eigen_assert(col>=0 && col<cols() && row>=0 && row<rows());
|
eigen_assert(col>=0 && col<cols() && row>=0 && row<rows());
|
||||||
const int mode = int(Mode) & ~SelfAdjoint;
|
const int mode = int(Mode) & ~SelfAdjoint;
|
||||||
|
EIGEN_ONLY_USED_FOR_DEBUG(mode);
|
||||||
eigen_assert((mode==Upper && col>=row)
|
eigen_assert((mode==Upper && col>=row)
|
||||||
|| (mode==Lower && col<=row)
|
|| (mode==Lower && col<=row)
|
||||||
|| ((mode==StrictlyUpper || mode==UnitUpper) && col>row)
|
|| ((mode==StrictlyUpper || mode==UnitUpper) && col>row)
|
||||||
@@ -134,13 +135,13 @@ template<typename Derived> class TriangularBase : public EigenBase<Derived>
|
|||||||
* \brief Base class for triangular part in a matrix
|
* \brief Base class for triangular part in a matrix
|
||||||
*
|
*
|
||||||
* \param MatrixType the type of the object in which we are taking the triangular part
|
* \param MatrixType the type of the object in which we are taking the triangular part
|
||||||
* \param Mode the kind of triangular matrix expression to construct. Can be Upper,
|
* \param Mode the kind of triangular matrix expression to construct. Can be #Upper,
|
||||||
* Lower, UpperSelfadjoint, or LowerSelfadjoint. This is in fact a bit field;
|
* #Lower, #UnitUpper, #UnitLower, #StrictlyUpper, or #StrictlyLower.
|
||||||
* it must have either Upper or Lower, and additionnaly it may have either
|
* This is in fact a bit field; it must have either #Upper or #Lower,
|
||||||
* UnitDiag or Selfadjoint.
|
* and additionnaly it may have #UnitDiag or #ZeroDiag or neither.
|
||||||
*
|
*
|
||||||
* This class represents a triangular part of a matrix, not necessarily square. Strictly speaking, for rectangular
|
* This class represents a triangular part of a matrix, not necessarily square. Strictly speaking, for rectangular
|
||||||
* matrices one should speak ok "trapezoid" parts. This class is the return type
|
* matrices one should speak of "trapezoid" parts. This class is the return type
|
||||||
* of MatrixBase::triangularView() and most of the time this is the only way it is used.
|
* of MatrixBase::triangularView() and most of the time this is the only way it is used.
|
||||||
*
|
*
|
||||||
* \sa MatrixBase::triangularView()
|
* \sa MatrixBase::triangularView()
|
||||||
@@ -448,6 +449,8 @@ struct triangular_assignment_selector
|
|||||||
col = (UnrollCount-1) / Derived1::RowsAtCompileTime,
|
col = (UnrollCount-1) / Derived1::RowsAtCompileTime,
|
||||||
row = (UnrollCount-1) % Derived1::RowsAtCompileTime
|
row = (UnrollCount-1) % Derived1::RowsAtCompileTime
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef typename Derived1::Scalar Scalar;
|
||||||
|
|
||||||
inline static void run(Derived1 &dst, const Derived2 &src)
|
inline static void run(Derived1 &dst, const Derived2 &src)
|
||||||
{
|
{
|
||||||
@@ -466,9 +469,9 @@ struct triangular_assignment_selector
|
|||||||
else if(ClearOpposite)
|
else if(ClearOpposite)
|
||||||
{
|
{
|
||||||
if (Mode&UnitDiag && row==col)
|
if (Mode&UnitDiag && row==col)
|
||||||
dst.coeffRef(row, col) = 1;
|
dst.coeffRef(row, col) = Scalar(1);
|
||||||
else
|
else
|
||||||
dst.coeffRef(row, col) = 0;
|
dst.coeffRef(row, col) = Scalar(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -484,16 +487,17 @@ template<typename Derived1, typename Derived2, bool ClearOpposite>
|
|||||||
struct triangular_assignment_selector<Derived1, Derived2, Upper, Dynamic, ClearOpposite>
|
struct triangular_assignment_selector<Derived1, Derived2, Upper, Dynamic, ClearOpposite>
|
||||||
{
|
{
|
||||||
typedef typename Derived1::Index Index;
|
typedef typename Derived1::Index Index;
|
||||||
|
typedef typename Derived1::Scalar Scalar;
|
||||||
inline static void run(Derived1 &dst, const Derived2 &src)
|
inline static void run(Derived1 &dst, const Derived2 &src)
|
||||||
{
|
{
|
||||||
for(Index j = 0; j < dst.cols(); ++j)
|
for(Index j = 0; j < dst.cols(); ++j)
|
||||||
{
|
{
|
||||||
Index maxi = std::min(j, dst.rows()-1);
|
Index maxi = (std::min)(j, dst.rows()-1);
|
||||||
for(Index i = 0; i <= maxi; ++i)
|
for(Index i = 0; i <= maxi; ++i)
|
||||||
dst.copyCoeff(i, j, src);
|
dst.copyCoeff(i, j, src);
|
||||||
if (ClearOpposite)
|
if (ClearOpposite)
|
||||||
for(Index i = maxi+1; i < dst.rows(); ++i)
|
for(Index i = maxi+1; i < dst.rows(); ++i)
|
||||||
dst.coeffRef(i, j) = 0;
|
dst.coeffRef(i, j) = Scalar(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -508,10 +512,10 @@ struct triangular_assignment_selector<Derived1, Derived2, Lower, Dynamic, ClearO
|
|||||||
{
|
{
|
||||||
for(Index i = j; i < dst.rows(); ++i)
|
for(Index i = j; i < dst.rows(); ++i)
|
||||||
dst.copyCoeff(i, j, src);
|
dst.copyCoeff(i, j, src);
|
||||||
Index maxi = std::min(j, dst.rows());
|
Index maxi = (std::min)(j, dst.rows());
|
||||||
if (ClearOpposite)
|
if (ClearOpposite)
|
||||||
for(Index i = 0; i < maxi; ++i)
|
for(Index i = 0; i < maxi; ++i)
|
||||||
dst.coeffRef(i, j) = 0;
|
dst.coeffRef(i, j) = static_cast<typename Derived1::Scalar>(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -524,7 +528,7 @@ struct triangular_assignment_selector<Derived1, Derived2, StrictlyUpper, Dynamic
|
|||||||
{
|
{
|
||||||
for(Index j = 0; j < dst.cols(); ++j)
|
for(Index j = 0; j < dst.cols(); ++j)
|
||||||
{
|
{
|
||||||
Index maxi = std::min(j, dst.rows());
|
Index maxi = (std::min)(j, dst.rows());
|
||||||
for(Index i = 0; i < maxi; ++i)
|
for(Index i = 0; i < maxi; ++i)
|
||||||
dst.copyCoeff(i, j, src);
|
dst.copyCoeff(i, j, src);
|
||||||
if (ClearOpposite)
|
if (ClearOpposite)
|
||||||
@@ -544,10 +548,10 @@ struct triangular_assignment_selector<Derived1, Derived2, StrictlyLower, Dynamic
|
|||||||
{
|
{
|
||||||
for(Index i = j+1; i < dst.rows(); ++i)
|
for(Index i = j+1; i < dst.rows(); ++i)
|
||||||
dst.copyCoeff(i, j, src);
|
dst.copyCoeff(i, j, src);
|
||||||
Index maxi = std::min(j, dst.rows()-1);
|
Index maxi = (std::min)(j, dst.rows()-1);
|
||||||
if (ClearOpposite)
|
if (ClearOpposite)
|
||||||
for(Index i = 0; i <= maxi; ++i)
|
for(Index i = 0; i <= maxi; ++i)
|
||||||
dst.coeffRef(i, j) = 0;
|
dst.coeffRef(i, j) = static_cast<typename Derived1::Scalar>(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -560,7 +564,7 @@ struct triangular_assignment_selector<Derived1, Derived2, UnitUpper, Dynamic, Cl
|
|||||||
{
|
{
|
||||||
for(Index j = 0; j < dst.cols(); ++j)
|
for(Index j = 0; j < dst.cols(); ++j)
|
||||||
{
|
{
|
||||||
Index maxi = std::min(j, dst.rows());
|
Index maxi = (std::min)(j, dst.rows());
|
||||||
for(Index i = 0; i < maxi; ++i)
|
for(Index i = 0; i < maxi; ++i)
|
||||||
dst.copyCoeff(i, j, src);
|
dst.copyCoeff(i, j, src);
|
||||||
if (ClearOpposite)
|
if (ClearOpposite)
|
||||||
@@ -580,7 +584,7 @@ struct triangular_assignment_selector<Derived1, Derived2, UnitLower, Dynamic, Cl
|
|||||||
{
|
{
|
||||||
for(Index j = 0; j < dst.cols(); ++j)
|
for(Index j = 0; j < dst.cols(); ++j)
|
||||||
{
|
{
|
||||||
Index maxi = std::min(j, dst.rows());
|
Index maxi = (std::min)(j, dst.rows());
|
||||||
for(Index i = maxi+1; i < dst.rows(); ++i)
|
for(Index i = maxi+1; i < dst.rows(); ++i)
|
||||||
dst.copyCoeff(i, j, src);
|
dst.copyCoeff(i, j, src);
|
||||||
if (ClearOpposite)
|
if (ClearOpposite)
|
||||||
@@ -756,8 +760,8 @@ typename internal::eigen2_part_return_type<Derived, Mode>::type MatrixBase<Deriv
|
|||||||
/**
|
/**
|
||||||
* \returns an expression of a triangular view extracted from the current matrix
|
* \returns an expression of a triangular view extracted from the current matrix
|
||||||
*
|
*
|
||||||
* The parameter \a Mode can have the following values: \c Upper, \c StrictlyUpper, \c UnitUpper,
|
* The parameter \a Mode can have the following values: \c #Upper, \c #StrictlyUpper, \c #UnitUpper,
|
||||||
* \c Lower, \c StrictlyLower, \c UnitLower.
|
* \c #Lower, \c #StrictlyLower, \c #UnitLower.
|
||||||
*
|
*
|
||||||
* Example: \include MatrixBase_extract.cpp
|
* Example: \include MatrixBase_extract.cpp
|
||||||
* Output: \verbinclude MatrixBase_extract.out
|
* Output: \verbinclude MatrixBase_extract.out
|
||||||
@@ -792,7 +796,7 @@ bool MatrixBase<Derived>::isUpperTriangular(RealScalar prec) const
|
|||||||
RealScalar maxAbsOnUpperPart = static_cast<RealScalar>(-1);
|
RealScalar maxAbsOnUpperPart = static_cast<RealScalar>(-1);
|
||||||
for(Index j = 0; j < cols(); ++j)
|
for(Index j = 0; j < cols(); ++j)
|
||||||
{
|
{
|
||||||
Index maxi = std::min(j, rows()-1);
|
Index maxi = (std::min)(j, rows()-1);
|
||||||
for(Index i = 0; i <= maxi; ++i)
|
for(Index i = 0; i <= maxi; ++i)
|
||||||
{
|
{
|
||||||
RealScalar absValue = internal::abs(coeff(i,j));
|
RealScalar absValue = internal::abs(coeff(i,j));
|
||||||
@@ -824,7 +828,7 @@ bool MatrixBase<Derived>::isLowerTriangular(RealScalar prec) const
|
|||||||
RealScalar threshold = maxAbsOnLowerPart * prec;
|
RealScalar threshold = maxAbsOnLowerPart * prec;
|
||||||
for(Index j = 1; j < cols(); ++j)
|
for(Index j = 1; j < cols(); ++j)
|
||||||
{
|
{
|
||||||
Index maxi = std::min(j, rows()-1);
|
Index maxi = (std::min)(j, rows()-1);
|
||||||
for(Index i = 0; i < maxi; ++i)
|
for(Index i = 0; i < maxi; ++i)
|
||||||
if(internal::abs(coeff(i, j)) > threshold) return false;
|
if(internal::abs(coeff(i, j)) > threshold) return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,9 +31,9 @@
|
|||||||
*
|
*
|
||||||
* \brief Generic expression of a partially reduxed matrix
|
* \brief Generic expression of a partially reduxed matrix
|
||||||
*
|
*
|
||||||
* \param MatrixType the type of the matrix we are applying the redux operation
|
* \tparam MatrixType the type of the matrix we are applying the redux operation
|
||||||
* \param MemberOp type of the member functor
|
* \tparam MemberOp type of the member functor
|
||||||
* \param Direction indicates the direction of the redux (Vertical or Horizontal)
|
* \tparam Direction indicates the direction of the redux (#Vertical or #Horizontal)
|
||||||
*
|
*
|
||||||
* This class represents an expression of a partial redux operator of a matrix.
|
* This class represents an expression of a partial redux operator of a matrix.
|
||||||
* It is the return type of some VectorwiseOp functions,
|
* It is the return type of some VectorwiseOp functions,
|
||||||
@@ -164,7 +164,7 @@ struct member_redux {
|
|||||||
* \brief Pseudo expression providing partial reduction operations
|
* \brief Pseudo expression providing partial reduction operations
|
||||||
*
|
*
|
||||||
* \param ExpressionType the type of the object on which to do partial reductions
|
* \param ExpressionType the type of the object on which to do partial reductions
|
||||||
* \param Direction indicates the direction of the redux (Vertical or Horizontal)
|
* \param Direction indicates the direction of the redux (#Vertical or #Horizontal)
|
||||||
*
|
*
|
||||||
* This class represents a pseudo expression with partial reduction features.
|
* This class represents a pseudo expression with partial reduction features.
|
||||||
* It is the return type of DenseBase::colwise() and DenseBase::rowwise()
|
* It is the return type of DenseBase::colwise() and DenseBase::rowwise()
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ template<> struct packet_traits<std::complex<float> > : default_packet_traits
|
|||||||
typedef Packet2cf type;
|
typedef Packet2cf type;
|
||||||
enum {
|
enum {
|
||||||
Vectorizable = 1,
|
Vectorizable = 1,
|
||||||
|
AlignedOnScalar = 1,
|
||||||
size = 2,
|
size = 2,
|
||||||
|
|
||||||
HasAdd = 1,
|
HasAdd = 1,
|
||||||
@@ -69,19 +70,17 @@ template<> EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<flo
|
|||||||
{
|
{
|
||||||
Packet2cf res;
|
Packet2cf res;
|
||||||
/* On AltiVec we cannot load 64-bit registers, so wa have to take care of alignment */
|
/* On AltiVec we cannot load 64-bit registers, so wa have to take care of alignment */
|
||||||
if ((ptrdiff_t)&from % 16 == 0) {
|
if((ptrdiff_t(&from) % 16) == 0)
|
||||||
res.v = pload((const float *)&from);
|
res.v = pload<Packet4f>((const float *)&from);
|
||||||
res.v = vec_perm(res.v, res.v, p16uc_PSET_HI);
|
else
|
||||||
} else {
|
res.v = ploadu<Packet4f>((const float *)&from);
|
||||||
res.v = ploadu((const float *)&from);
|
res.v = vec_perm(res.v, res.v, p16uc_PSET_HI);
|
||||||
res.v = vec_perm(res.v, res.v, p16uc_PSET_LO);
|
|
||||||
}
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet2cf padd<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_add(a.v,b.v)); }
|
template<> EIGEN_STRONG_INLINE Packet2cf padd<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_add(a.v,b.v)); }
|
||||||
template<> EIGEN_STRONG_INLINE Packet2cf psub<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_sub(a.v,b.v)); }
|
template<> EIGEN_STRONG_INLINE Packet2cf psub<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_sub(a.v,b.v)); }
|
||||||
template<> EIGEN_STRONG_INLINE Packet2cf pnegate(const Packet2cf& a) { return Packet2cf(psub<Packet4f>(p4f_ZERO, a.v)); }
|
template<> EIGEN_STRONG_INLINE Packet2cf pnegate(const Packet2cf& a) { return Packet2cf(pnegate(a.v)); }
|
||||||
template<> EIGEN_STRONG_INLINE Packet2cf pconj(const Packet2cf& a) { return Packet2cf((Packet4f)vec_xor((Packet4ui)a.v, p4ui_CONJ_XOR)); }
|
template<> EIGEN_STRONG_INLINE Packet2cf pconj(const Packet2cf& a) { return Packet2cf((Packet4f)vec_xor((Packet4ui)a.v, p4ui_CONJ_XOR)); }
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet2cf pmul<Packet2cf>(const Packet2cf& a, const Packet2cf& b)
|
template<> EIGEN_STRONG_INLINE Packet2cf pmul<Packet2cf>(const Packet2cf& a, const Packet2cf& b)
|
||||||
@@ -108,8 +107,13 @@ 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(vec_xor(a.v,b.v)); }
|
template<> EIGEN_STRONG_INLINE Packet2cf pxor <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_xor(a.v,b.v)); }
|
||||||
template<> EIGEN_STRONG_INLINE Packet2cf pandnot<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_and(a.v, vec_nor(b.v,b.v))); }
|
template<> EIGEN_STRONG_INLINE Packet2cf pandnot<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_and(a.v, vec_nor(b.v,b.v))); }
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet2cf pload <std::complex<float> >(const std::complex<float>* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload((const float*)from)); }
|
template<> EIGEN_STRONG_INLINE Packet2cf pload <Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload<Packet4f>((const float*)from)); }
|
||||||
template<> EIGEN_STRONG_INLINE Packet2cf ploadu<std::complex<float> >(const std::complex<float>* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu((const float*)from)); }
|
template<> EIGEN_STRONG_INLINE Packet2cf ploadu<Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu<Packet4f>((const float*)from)); }
|
||||||
|
|
||||||
|
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((float*)to, from.v); }
|
template<> EIGEN_STRONG_INLINE void pstore <std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((float*)to, from.v); }
|
||||||
template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((float*)to, from.v); }
|
template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((float*)to, from.v); }
|
||||||
@@ -136,7 +140,7 @@ template<> EIGEN_STRONG_INLINE std::complex<float> predux<Packet2cf>(const Packe
|
|||||||
Packet4f b;
|
Packet4f b;
|
||||||
b = (Packet4f) vec_sld(a.v, a.v, 8);
|
b = (Packet4f) vec_sld(a.v, a.v, 8);
|
||||||
b = padd(a.v, b);
|
b = padd(a.v, b);
|
||||||
return pfirst(Packet2cf(sum));
|
return pfirst(Packet2cf(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet2cf preduxp<Packet2cf>(const Packet2cf* vecs)
|
template<> EIGEN_STRONG_INLINE Packet2cf preduxp<Packet2cf>(const Packet2cf* vecs)
|
||||||
@@ -180,7 +184,7 @@ template<> struct conj_helper<Packet2cf, Packet2cf, false,true>
|
|||||||
|
|
||||||
EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
|
EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
|
||||||
{
|
{
|
||||||
return pmul(a, pconj(b));
|
return internal::pmul(a, pconj(b));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -191,7 +195,7 @@ template<> struct conj_helper<Packet2cf, Packet2cf, true,false>
|
|||||||
|
|
||||||
EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
|
EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
|
||||||
{
|
{
|
||||||
return pmul(pconj(a), b);
|
return internal::pmul(pconj(a), b);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -202,7 +206,7 @@ template<> struct conj_helper<Packet2cf, Packet2cf, true,true>
|
|||||||
|
|
||||||
EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
|
EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
|
||||||
{
|
{
|
||||||
return pconj(pmul(a, b));
|
return pconj(internal::pmul(a, b));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -214,6 +218,11 @@ template<> EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, con
|
|||||||
return Packet2cf(pdiv(res.v, vec_add(s,vec_perm(s, s, p16uc_COMPLEX_REV))));
|
return Packet2cf(pdiv(res.v, vec_add(s,vec_perm(s, s, p16uc_COMPLEX_REV))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<> EIGEN_STRONG_INLINE Packet2cf pcplxflip<Packet2cf>(const Packet2cf& x)
|
||||||
|
{
|
||||||
|
return Packet2cf(vec_perm(x.v, x.v, p16uc_COMPLEX_REV));
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
#endif // EIGEN_COMPLEX_ALTIVEC_H
|
#endif // EIGEN_COMPLEX_ALTIVEC_H
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ static Packet4f p4f_COUNTDOWN = { 3.0, 2.0, 1.0, 0.0 };
|
|||||||
static Packet4i p4i_COUNTDOWN = { 3, 2, 1, 0 };
|
static Packet4i p4i_COUNTDOWN = { 3, 2, 1, 0 };
|
||||||
static Packet16uc p16uc_REVERSE = {12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3};
|
static Packet16uc p16uc_REVERSE = {12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3};
|
||||||
static Packet16uc p16uc_FORWARD = vec_lvsl(0, (float*)0);
|
static Packet16uc p16uc_FORWARD = vec_lvsl(0, (float*)0);
|
||||||
|
static Packet16uc p16uc_DUPLICATE = {0,1,2,3, 0,1,2,3, 4,5,6,7, 4,5,6,7};
|
||||||
|
|
||||||
static _EIGEN_DECLARE_CONST_FAST_Packet4f(ZERO, 0);
|
static _EIGEN_DECLARE_CONST_FAST_Packet4f(ZERO, 0);
|
||||||
static _EIGEN_DECLARE_CONST_FAST_Packet4i(ZERO, 0);
|
static _EIGEN_DECLARE_CONST_FAST_Packet4i(ZERO, 0);
|
||||||
@@ -292,6 +293,21 @@ template<> EIGEN_STRONG_INLINE Packet4i ploadu<Packet4i>(const int* from)
|
|||||||
return (Packet4i) vec_perm(MSQ, LSQ, mask); // align the data
|
return (Packet4i) vec_perm(MSQ, LSQ, mask); // align the data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<> EIGEN_STRONG_INLINE Packet4f ploaddup<Packet4f>(const float* from)
|
||||||
|
{
|
||||||
|
Packet4f p;
|
||||||
|
if((ptrdiff_t(&from) % 16) == 0) p = pload<Packet4f>(from);
|
||||||
|
else p = ploadu<Packet4f>(from);
|
||||||
|
return vec_perm(p, p, p16uc_DUPLICATE);
|
||||||
|
}
|
||||||
|
template<> EIGEN_STRONG_INLINE Packet4i ploaddup<Packet4i>(const int* from)
|
||||||
|
{
|
||||||
|
Packet4i p;
|
||||||
|
if((ptrdiff_t(&from) % 16) == 0) p = pload<Packet4i>(from);
|
||||||
|
else p = ploadu<Packet4i>(from);
|
||||||
|
return vec_perm(p, p, p16uc_DUPLICATE);
|
||||||
|
}
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE void pstore<float>(float* to, const Packet4f& from) { EIGEN_DEBUG_ALIGNED_STORE vec_st(from, 0, to); }
|
template<> EIGEN_STRONG_INLINE void pstore<float>(float* to, const Packet4f& from) { EIGEN_DEBUG_ALIGNED_STORE vec_st(from, 0, to); }
|
||||||
template<> EIGEN_STRONG_INLINE void pstore<int>(int* to, const Packet4i& from) { EIGEN_DEBUG_ALIGNED_STORE vec_st(from, 0, to); }
|
template<> EIGEN_STRONG_INLINE void pstore<int>(int* to, const Packet4i& from) { EIGEN_DEBUG_ALIGNED_STORE vec_st(from, 0, to); }
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ template<> struct packet_traits<std::complex<float> > : default_packet_traits
|
|||||||
typedef Packet2cf type;
|
typedef Packet2cf type;
|
||||||
enum {
|
enum {
|
||||||
Vectorizable = 1,
|
Vectorizable = 1,
|
||||||
|
AlignedOnScalar = 1,
|
||||||
size = 2,
|
size = 2,
|
||||||
|
|
||||||
HasAdd = 1,
|
HasAdd = 1,
|
||||||
@@ -120,6 +121,8 @@ template<> EIGEN_STRONG_INLINE Packet2cf pandnot<Packet2cf>(const Packet2cf& a,
|
|||||||
template<> EIGEN_STRONG_INLINE Packet2cf pload<Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload<Packet4f>((const float*)from)); }
|
template<> EIGEN_STRONG_INLINE Packet2cf pload<Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload<Packet4f>((const float*)from)); }
|
||||||
template<> EIGEN_STRONG_INLINE Packet2cf ploadu<Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu<Packet4f>((const float*)from)); }
|
template<> EIGEN_STRONG_INLINE Packet2cf ploadu<Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu<Packet4f>((const float*)from)); }
|
||||||
|
|
||||||
|
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((float*)to, from.v); }
|
template<> EIGEN_STRONG_INLINE void pstore <std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((float*)to, from.v); }
|
||||||
template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((float*)to, from.v); }
|
template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((float*)to, from.v); }
|
||||||
|
|
||||||
@@ -144,7 +147,7 @@ template<> EIGEN_STRONG_INLINE Packet2cf preverse(const Packet2cf& a)
|
|||||||
return Packet2cf(a_r128);
|
return Packet2cf(a_r128);
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Packet2cf pcplxflip(const Packet2cf& a)
|
template<> EIGEN_STRONG_INLINE Packet2cf pcplxflip<Packet2cf>(const Packet2cf& a)
|
||||||
{
|
{
|
||||||
return Packet2cf(vrev64q_f32(a.v));
|
return Packet2cf(vrev64q_f32(a.v));
|
||||||
}
|
}
|
||||||
@@ -220,7 +223,7 @@ template<> struct conj_helper<Packet2cf, Packet2cf, false,true>
|
|||||||
|
|
||||||
EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
|
EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
|
||||||
{
|
{
|
||||||
return pmul(a, pconj(b));
|
return internal::pmul(a, pconj(b));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -231,7 +234,7 @@ template<> struct conj_helper<Packet2cf, Packet2cf, true,false>
|
|||||||
|
|
||||||
EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
|
EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
|
||||||
{
|
{
|
||||||
return pmul(pconj(a), b);
|
return internal::pmul(pconj(a), b);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -242,7 +245,7 @@ template<> struct conj_helper<Packet2cf, Packet2cf, true,true>
|
|||||||
|
|
||||||
EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
|
EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
|
||||||
{
|
{
|
||||||
return pconj(pmul(a, b));
|
return pconj(internal::pmul(a, b));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace internal {
|
|||||||
|
|
||||||
typedef float32x4_t Packet4f;
|
typedef float32x4_t Packet4f;
|
||||||
typedef int32x4_t Packet4i;
|
typedef int32x4_t Packet4i;
|
||||||
typedef uint32x4_t Packet4ui;
|
typedef uint32x4_t Packet4ui;
|
||||||
|
|
||||||
#define _EIGEN_DECLARE_CONST_Packet4f(NAME,X) \
|
#define _EIGEN_DECLARE_CONST_Packet4f(NAME,X) \
|
||||||
const Packet4f p4f_##NAME = pset1<Packet4f>(X)
|
const Packet4f p4f_##NAME = pset1<Packet4f>(X)
|
||||||
@@ -84,8 +84,8 @@ template<> struct packet_traits<int> : default_packet_traits
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
#if (defined __GNUC__) && (!(EIGEN_GNUC_AT_LEAST(4,4)))
|
#if EIGEN_GNUC_AT_MOST(4,4)
|
||||||
// workaround gcc 4.2 and 4.3 compilatin issue
|
// workaround gcc 4.2, 4.3 and 4.4 compilatin issue
|
||||||
EIGEN_STRONG_INLINE float32x4_t vld1q_f32(const float* x) { return ::vld1q_f32((const float32_t*)x); }
|
EIGEN_STRONG_INLINE float32x4_t vld1q_f32(const float* x) { return ::vld1q_f32((const float32_t*)x); }
|
||||||
EIGEN_STRONG_INLINE float32x2_t vld1_f32 (const float* x) { return ::vld1_f32 ((const float32_t*)x); }
|
EIGEN_STRONG_INLINE float32x2_t vld1_f32 (const float* x) { return ::vld1_f32 ((const float32_t*)x); }
|
||||||
EIGEN_STRONG_INLINE void vst1q_f32(float* to, float32x4_t from) { ::vst1q_f32((float32_t*)to,from); }
|
EIGEN_STRONG_INLINE void vst1q_f32(float* to, float32x4_t from) { ::vst1q_f32((float32_t*)to,from); }
|
||||||
@@ -100,12 +100,12 @@ template<> EIGEN_STRONG_INLINE Packet4i pset1<Packet4i>(const int& from) {
|
|||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet4f plset<float>(const float& a)
|
template<> EIGEN_STRONG_INLINE Packet4f plset<float>(const float& a)
|
||||||
{
|
{
|
||||||
Packet4f countdown = { 3, 2, 1, 0 };
|
Packet4f countdown = { 0, 1, 2, 3 };
|
||||||
return vaddq_f32(pset1<Packet4f>(a), countdown);
|
return vaddq_f32(pset1<Packet4f>(a), countdown);
|
||||||
}
|
}
|
||||||
template<> EIGEN_STRONG_INLINE Packet4i plset<int>(const int& a)
|
template<> EIGEN_STRONG_INLINE Packet4i plset<int>(const int& a)
|
||||||
{
|
{
|
||||||
Packet4i countdown = { 3, 2, 1, 0 };
|
Packet4i countdown = { 0, 1, 2, 3 };
|
||||||
return vaddq_s32(pset1<Packet4i>(a), countdown);
|
return vaddq_s32(pset1<Packet4i>(a), countdown);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,14 +191,14 @@ template<> EIGEN_STRONG_INLINE Packet4f ploaddup<Packet4f>(const float* from)
|
|||||||
{
|
{
|
||||||
float32x2_t lo, hi;
|
float32x2_t lo, hi;
|
||||||
lo = vdup_n_f32(*from);
|
lo = vdup_n_f32(*from);
|
||||||
hi = vdup_n_f32(*from);
|
hi = vdup_n_f32(*(from+1));
|
||||||
return vcombine_f32(lo, hi);
|
return vcombine_f32(lo, hi);
|
||||||
}
|
}
|
||||||
template<> EIGEN_STRONG_INLINE Packet4i ploaddup<Packet4i>(const int* from)
|
template<> EIGEN_STRONG_INLINE Packet4i ploaddup<Packet4i>(const int* from)
|
||||||
{
|
{
|
||||||
int32x2_t lo, hi;
|
int32x2_t lo, hi;
|
||||||
lo = vdup_n_s32(*from);
|
lo = vdup_n_s32(*from);
|
||||||
hi = vdup_n_s32(*from);
|
hi = vdup_n_s32(*(from+1));
|
||||||
return vcombine_s32(lo, hi);
|
return vcombine_s32(lo, hi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,23 +97,30 @@ template<> EIGEN_STRONG_INLINE Packet2cf pandnot<Packet2cf>(const Packet2cf& a,
|
|||||||
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 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 ploadu<Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu<Packet4f>(&real_ref(*from))); }
|
||||||
|
|
||||||
|
template<> EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<float>& from)
|
||||||
|
{
|
||||||
|
Packet2cf res;
|
||||||
|
#if EIGEN_GNUC_AT_MOST(4,2)
|
||||||
|
// workaround annoying "may be used uninitialized in this function" warning with gcc 4.2
|
||||||
|
res.v = _mm_loadl_pi(_mm_set1_ps(0.0f), (const __m64*)&from);
|
||||||
|
#else
|
||||||
|
res.v = _mm_loadl_pi(res.v, (const __m64*)&from);
|
||||||
|
#endif
|
||||||
|
return Packet2cf(_mm_movelh_ps(res.v,res.v));
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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 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 prefetch<std::complex<float> >(const std::complex<float> * addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
|
template<> EIGEN_STRONG_INLINE void prefetch<std::complex<float> >(const std::complex<float> * addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<float>& from)
|
|
||||||
{
|
|
||||||
Packet2cf res;
|
|
||||||
res.v = _mm_loadl_pi(res.v, (const __m64*)&from);
|
|
||||||
return Packet2cf(_mm_movelh_ps(res.v,res.v));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE std::complex<float> pfirst<Packet2cf>(const Packet2cf& a)
|
template<> EIGEN_STRONG_INLINE std::complex<float> pfirst<Packet2cf>(const Packet2cf& a)
|
||||||
{
|
{
|
||||||
#if (defined __GNUC__) && (__GNUC__==4) && (__GNUC_MINOR__==2) && (__GNUC_PATCHLEVEL__<=3)
|
#if EIGEN_GNUC_AT_MOST(4,3)
|
||||||
// workaround gcc 4.2.1 ICE (mac's gcc version) - I'm not sure how the 4.2.2 and 4.2.3 deal with it, but 4.2.4 works well.
|
// Workaround gcc 4.2 ICE - this is not performance wise ideal, but who cares...
|
||||||
// this is not performance wise ideal, but who cares...
|
// This workaround also fix invalid code generation with gcc 4.3
|
||||||
EIGEN_ALIGN16 std::complex<float> res[2];
|
EIGEN_ALIGN16 std::complex<float> res[2];
|
||||||
_mm_store_ps((float*)res, a.v);
|
_mm_store_ps((float*)res, a.v);
|
||||||
return res[0];
|
return res[0];
|
||||||
@@ -308,6 +315,8 @@ template<> EIGEN_STRONG_INLINE Packet1cd ploadu<Packet1cd>(const std::complex<do
|
|||||||
template<> EIGEN_STRONG_INLINE Packet1cd pset1<Packet1cd>(const std::complex<double>& from)
|
template<> EIGEN_STRONG_INLINE Packet1cd pset1<Packet1cd>(const std::complex<double>& from)
|
||||||
{ /* here we really have to use unaligned loads :( */ return ploadu<Packet1cd>(&from); }
|
{ /* here we really have to use unaligned loads :( */ return ploadu<Packet1cd>(&from); }
|
||||||
|
|
||||||
|
template<> EIGEN_STRONG_INLINE Packet1cd ploaddup<Packet1cd>(const std::complex<double>* from) { return pset1<Packet1cd>(*from); }
|
||||||
|
|
||||||
// FIXME force unaligned store, this is a temporary fix
|
// FIXME force unaligned store, this is a temporary fix
|
||||||
template<> EIGEN_STRONG_INLINE void pstore <std::complex<double> >(std::complex<double> * to, const Packet1cd& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((double*)to, from.v); }
|
template<> EIGEN_STRONG_INLINE void pstore <std::complex<double> >(std::complex<double> * to, const Packet1cd& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((double*)to, from.v); }
|
||||||
template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<double> >(std::complex<double> * to, const Packet1cd& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, from.v); }
|
template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<double> >(std::complex<double> * to, const Packet1cd& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, from.v); }
|
||||||
|
|||||||
@@ -110,22 +110,8 @@ template<> struct unpacket_traits<Packet4f> { typedef float type; enum {size=4}
|
|||||||
template<> struct unpacket_traits<Packet2d> { typedef double type; enum {size=2}; };
|
template<> struct unpacket_traits<Packet2d> { typedef double type; enum {size=2}; };
|
||||||
template<> struct unpacket_traits<Packet4i> { typedef int type; enum {size=4}; };
|
template<> struct unpacket_traits<Packet4i> { typedef int type; enum {size=4}; };
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
// Sometimes GCC implements _mm_set1_p* using multiple moves,
|
|
||||||
// that is inefficient :( (e.g., see gemm_pack_rhs)
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet4f pset1<Packet4f>(const float& from) {
|
|
||||||
Packet4f res = _mm_set_ss(from);
|
|
||||||
return vec4f_swizzle1(res,0,0,0,0);
|
|
||||||
}
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet2d pset1<Packet2d>(const double& from) {
|
|
||||||
// NOTE the SSE3 intrinsic _mm_loaddup_pd is never faster but sometimes much slower
|
|
||||||
Packet2d res = _mm_set_sd(from);
|
|
||||||
return vec2d_swizzle1(res, 0, 0);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet4f pset1<Packet4f>(const float& from) { return _mm_set1_ps(from); }
|
template<> EIGEN_STRONG_INLINE Packet4f pset1<Packet4f>(const float& from) { return _mm_set1_ps(from); }
|
||||||
template<> EIGEN_STRONG_INLINE Packet2d pset1<Packet2d>(const double& from) { return _mm_set1_pd(from); }
|
template<> EIGEN_STRONG_INLINE Packet2d pset1<Packet2d>(const double& from) { return _mm_set1_pd(from); }
|
||||||
#endif
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet4i pset1<Packet4i>(const int& from) { return _mm_set1_epi32(from); }
|
template<> EIGEN_STRONG_INLINE Packet4i pset1<Packet4i>(const int& from) { return _mm_set1_epi32(from); }
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet4f plset<float>(const float& a) { return _mm_add_ps(pset1<Packet4f>(a), _mm_set_ps(3,2,1,0)); }
|
template<> EIGEN_STRONG_INLINE Packet4f plset<float>(const float& a) { return _mm_add_ps(pset1<Packet4f>(a), _mm_set_ps(3,2,1,0)); }
|
||||||
@@ -245,29 +231,52 @@ template<> EIGEN_STRONG_INLINE Packet4i pload<Packet4i>(const int* from) { E
|
|||||||
// a correct instruction dependency.
|
// a correct instruction dependency.
|
||||||
// TODO: do the same for MSVC (ICC is compatible)
|
// TODO: do the same for MSVC (ICC is compatible)
|
||||||
// NOTE: with the code below, MSVC's compiler crashes!
|
// NOTE: with the code below, MSVC's compiler crashes!
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && defined(__i386__)
|
||||||
|
// bug 195: gcc/i386 emits weird x87 fldl/fstpl instructions for _mm_load_sd
|
||||||
|
#define EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS 1
|
||||||
|
#elif defined(__clang__)
|
||||||
|
// bug 201: Segfaults in __mm_loadh_pd with clang 2.8
|
||||||
|
#define EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS 1
|
||||||
|
#else
|
||||||
|
#define EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet4f ploadu<Packet4f>(const float* from)
|
template<> EIGEN_STRONG_INLINE Packet4f ploadu<Packet4f>(const float* from)
|
||||||
{
|
{
|
||||||
EIGEN_DEBUG_UNALIGNED_LOAD
|
EIGEN_DEBUG_UNALIGNED_LOAD
|
||||||
|
#if EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS
|
||||||
|
return _mm_loadu_ps(from);
|
||||||
|
#else
|
||||||
__m128d res;
|
__m128d res;
|
||||||
res = _mm_load_sd((const double*)(from)) ;
|
res = _mm_load_sd((const double*)(from)) ;
|
||||||
res = _mm_loadh_pd(res, (const double*)(from+2)) ;
|
res = _mm_loadh_pd(res, (const double*)(from+2)) ;
|
||||||
return _mm_castpd_ps(res);
|
return _mm_castpd_ps(res);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
template<> EIGEN_STRONG_INLINE Packet2d ploadu<Packet2d>(const double* from)
|
template<> EIGEN_STRONG_INLINE Packet2d ploadu<Packet2d>(const double* from)
|
||||||
{
|
{
|
||||||
EIGEN_DEBUG_UNALIGNED_LOAD
|
EIGEN_DEBUG_UNALIGNED_LOAD
|
||||||
|
#if EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS
|
||||||
|
return _mm_loadu_pd(from);
|
||||||
|
#else
|
||||||
__m128d res;
|
__m128d res;
|
||||||
res = _mm_load_sd(from) ;
|
res = _mm_load_sd(from) ;
|
||||||
res = _mm_loadh_pd(res,from+1);
|
res = _mm_loadh_pd(res,from+1);
|
||||||
return res;
|
return res;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
template<> EIGEN_STRONG_INLINE Packet4i ploadu<Packet4i>(const int* from)
|
template<> EIGEN_STRONG_INLINE Packet4i ploadu<Packet4i>(const int* from)
|
||||||
{
|
{
|
||||||
EIGEN_DEBUG_UNALIGNED_LOAD
|
EIGEN_DEBUG_UNALIGNED_LOAD
|
||||||
|
#if EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS
|
||||||
|
return _mm_loadu_si128(reinterpret_cast<const Packet4i*>(from));
|
||||||
|
#else
|
||||||
__m128d res;
|
__m128d res;
|
||||||
res = _mm_load_sd((const double*)(from)) ;
|
res = _mm_load_sd((const double*)(from)) ;
|
||||||
res = _mm_loadh_pd(res, (const double*)(from+2)) ;
|
res = _mm_loadh_pd(res, (const double*)(from+2)) ;
|
||||||
return _mm_castpd_si128(res);
|
return _mm_castpd_si128(res);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -296,6 +305,19 @@ template<> EIGEN_STRONG_INLINE void pstoreu<double>(double* to, const Packet2d&
|
|||||||
template<> EIGEN_STRONG_INLINE void pstoreu<float>(float* to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, _mm_castps_pd(from)); }
|
template<> EIGEN_STRONG_INLINE void pstoreu<float>(float* to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, _mm_castps_pd(from)); }
|
||||||
template<> EIGEN_STRONG_INLINE void pstoreu<int>(int* to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, _mm_castsi128_pd(from)); }
|
template<> EIGEN_STRONG_INLINE void pstoreu<int>(int* to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, _mm_castsi128_pd(from)); }
|
||||||
|
|
||||||
|
// some compilers might be tempted to perform multiple moves instead of using a vector path.
|
||||||
|
template<> EIGEN_STRONG_INLINE void pstore1<Packet4f>(float* to, const float& a)
|
||||||
|
{
|
||||||
|
Packet4f pa = _mm_set_ss(a);
|
||||||
|
pstore(to, vec4f_swizzle1(pa,0,0,0,0));
|
||||||
|
}
|
||||||
|
// some compilers might be tempted to perform multiple moves instead of using a vector path.
|
||||||
|
template<> EIGEN_STRONG_INLINE void pstore1<Packet2d>(double* to, const double& a)
|
||||||
|
{
|
||||||
|
Packet2d pa = _mm_set_sd(a);
|
||||||
|
pstore(to, vec2d_swizzle1(pa,0,0));
|
||||||
|
}
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE void prefetch<float>(const float* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
|
template<> EIGEN_STRONG_INLINE void prefetch<float>(const float* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
|
||||||
template<> EIGEN_STRONG_INLINE void prefetch<double>(const double* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
|
template<> EIGEN_STRONG_INLINE void prefetch<double>(const double* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
|
||||||
template<> EIGEN_STRONG_INLINE void prefetch<int>(const int* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
|
template<> EIGEN_STRONG_INLINE void prefetch<int>(const int* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ inline void manage_caching_sizes(Action action, std::ptrdiff_t* l1=0, std::ptrdi
|
|||||||
template<typename LhsScalar, typename RhsScalar, int KcFactor>
|
template<typename LhsScalar, typename RhsScalar, int KcFactor>
|
||||||
void computeProductBlockingSizes(std::ptrdiff_t& k, std::ptrdiff_t& m, std::ptrdiff_t& n)
|
void computeProductBlockingSizes(std::ptrdiff_t& k, std::ptrdiff_t& m, std::ptrdiff_t& n)
|
||||||
{
|
{
|
||||||
|
EIGEN_UNUSED_VARIABLE(n);
|
||||||
// Explanations:
|
// Explanations:
|
||||||
// Let's recall the product algorithms form kc x nc horizontal panels B' on the rhs and
|
// Let's recall the product algorithms form kc x nc horizontal panels B' on the rhs and
|
||||||
// mc x kc blocks A' on the lhs. A' has to fit into L2 cache. Moreover, B' is processed
|
// mc x kc blocks A' on the lhs. A' has to fit into L2 cache. Moreover, B' is processed
|
||||||
@@ -102,7 +103,6 @@ void computeProductBlockingSizes(std::ptrdiff_t& k, std::ptrdiff_t& m, std::ptrd
|
|||||||
k = std::min<std::ptrdiff_t>(k, l1/kdiv);
|
k = std::min<std::ptrdiff_t>(k, l1/kdiv);
|
||||||
std::ptrdiff_t _m = k>0 ? l2/(4 * sizeof(LhsScalar) * k) : 0;
|
std::ptrdiff_t _m = k>0 ? l2/(4 * sizeof(LhsScalar) * k) : 0;
|
||||||
if(_m<m) m = _m & mr_mask;
|
if(_m<m) m = _m & mr_mask;
|
||||||
n = n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename LhsScalar, typename RhsScalar>
|
template<typename LhsScalar, typename RhsScalar>
|
||||||
@@ -199,7 +199,7 @@ public:
|
|||||||
EIGEN_STRONG_INLINE void unpackRhs(DenseIndex n, const RhsScalar* rhs, RhsScalar* b)
|
EIGEN_STRONG_INLINE void unpackRhs(DenseIndex n, const RhsScalar* rhs, RhsScalar* b)
|
||||||
{
|
{
|
||||||
for(DenseIndex k=0; k<n; k++)
|
for(DenseIndex k=0; k<n; k++)
|
||||||
pstore(&b[k*RhsPacketSize], pset1<RhsPacket>(rhs[k]));
|
pstore1<RhsPacket>(&b[k*RhsPacketSize], rhs[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE void loadRhs(const RhsScalar* b, RhsPacket& dest) const
|
EIGEN_STRONG_INLINE void loadRhs(const RhsScalar* b, RhsPacket& dest) const
|
||||||
@@ -270,7 +270,7 @@ public:
|
|||||||
EIGEN_STRONG_INLINE void unpackRhs(DenseIndex n, const RhsScalar* rhs, RhsScalar* b)
|
EIGEN_STRONG_INLINE void unpackRhs(DenseIndex n, const RhsScalar* rhs, RhsScalar* b)
|
||||||
{
|
{
|
||||||
for(DenseIndex k=0; k<n; k++)
|
for(DenseIndex k=0; k<n; k++)
|
||||||
pstore(&b[k*RhsPacketSize], pset1<RhsPacket>(rhs[k]));
|
pstore1<RhsPacket>(&b[k*RhsPacketSize], rhs[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE void loadRhs(const RhsScalar* b, RhsPacket& dest) const
|
EIGEN_STRONG_INLINE void loadRhs(const RhsScalar* b, RhsPacket& dest) const
|
||||||
@@ -363,8 +363,8 @@ public:
|
|||||||
{
|
{
|
||||||
if(Vectorizable)
|
if(Vectorizable)
|
||||||
{
|
{
|
||||||
pstore((RealScalar*)&b[k*ResPacketSize*2+0], pset1<RealPacket>(real(rhs[k])));
|
pstore1<RealPacket>((RealScalar*)&b[k*ResPacketSize*2+0], real(rhs[k]));
|
||||||
pstore((RealScalar*)&b[k*ResPacketSize*2+ResPacketSize], pset1<RealPacket>(imag(rhs[k])));
|
pstore1<RealPacket>((RealScalar*)&b[k*ResPacketSize*2+ResPacketSize], imag(rhs[k]));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
b[k] = rhs[k];
|
b[k] = rhs[k];
|
||||||
@@ -475,7 +475,7 @@ public:
|
|||||||
EIGEN_STRONG_INLINE void unpackRhs(DenseIndex n, const RhsScalar* rhs, RhsScalar* b)
|
EIGEN_STRONG_INLINE void unpackRhs(DenseIndex n, const RhsScalar* rhs, RhsScalar* b)
|
||||||
{
|
{
|
||||||
for(DenseIndex k=0; k<n; k++)
|
for(DenseIndex k=0; k<n; k++)
|
||||||
pstore(&b[k*RhsPacketSize], pset1<RhsPacket>(rhs[k]));
|
pstore1<RhsPacket>(&b[k*RhsPacketSize], rhs[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE void loadRhs(const RhsScalar* b, RhsPacket& dest) const
|
EIGEN_STRONG_INLINE void loadRhs(const RhsScalar* b, RhsPacket& dest) const
|
||||||
@@ -1009,12 +1009,7 @@ EIGEN_ASM_COMMENT("mybegin4");
|
|||||||
for(Index j2=packet_cols; j2<cols; j2++)
|
for(Index j2=packet_cols; j2<cols; j2++)
|
||||||
{
|
{
|
||||||
// unpack B
|
// unpack B
|
||||||
{
|
traits.unpackRhs(depth, &blockB[j2*strideB+offsetB], unpackedB);
|
||||||
traits.unpackRhs(depth, &blockB[j2*strideB+offsetB], unpackedB);
|
|
||||||
// const RhsScalar* blB = &blockB[j2*strideB+offsetB];
|
|
||||||
// for(Index k=0; k<depth; k++)
|
|
||||||
// pstore(&unpackedB[k*RhsPacketSize], pset1<RhsPacket>(blB[k]));
|
|
||||||
}
|
|
||||||
|
|
||||||
for(Index i=0; i<peeled_mc; i+=mr)
|
for(Index i=0; i<peeled_mc; i+=mr)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ static void run(Index rows, Index cols, Index depth,
|
|||||||
typedef gebp_traits<LhsScalar,RhsScalar> Traits;
|
typedef gebp_traits<LhsScalar,RhsScalar> Traits;
|
||||||
|
|
||||||
Index kc = blocking.kc(); // cache block size along the K direction
|
Index kc = blocking.kc(); // cache block size along the K direction
|
||||||
Index mc = std::min(rows,blocking.mc()); // cache block size along the M direction
|
Index mc = (std::min)(rows,blocking.mc()); // cache block size along the M direction
|
||||||
//Index nc = blocking.nc(); // cache block size along the N direction
|
//Index nc = blocking.nc(); // cache block size along the N direction
|
||||||
|
|
||||||
gemm_pack_lhs<LhsScalar, Index, Traits::mr, Traits::LhsProgress, LhsStorageOrder> pack_lhs;
|
gemm_pack_lhs<LhsScalar, Index, Traits::mr, Traits::LhsProgress, LhsStorageOrder> pack_lhs;
|
||||||
@@ -94,15 +94,16 @@ static void run(Index rows, Index cols, Index depth,
|
|||||||
|
|
||||||
std::size_t sizeA = kc*mc;
|
std::size_t sizeA = kc*mc;
|
||||||
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
|
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
|
||||||
LhsScalar* blockA = ei_aligned_stack_new(LhsScalar, sizeA);
|
ei_declare_aligned_stack_constructed_variable(LhsScalar, blockA, sizeA, 0);
|
||||||
RhsScalar* w = ei_aligned_stack_new(RhsScalar, sizeW);
|
ei_declare_aligned_stack_constructed_variable(RhsScalar, w, sizeW, 0);
|
||||||
|
|
||||||
RhsScalar* blockB = blocking.blockB();
|
RhsScalar* blockB = blocking.blockB();
|
||||||
eigen_internal_assert(blockB!=0);
|
eigen_internal_assert(blockB!=0);
|
||||||
|
|
||||||
// For each horizontal panel of the rhs, and corresponding vertical panel of the lhs...
|
// For each horizontal panel of the rhs, and corresponding vertical panel of the lhs...
|
||||||
for(Index k=0; k<depth; k+=kc)
|
for(Index k=0; k<depth; k+=kc)
|
||||||
{
|
{
|
||||||
const Index actual_kc = std::min(k+kc,depth)-k; // => rows of B', and cols of the A'
|
const Index actual_kc = (std::min)(k+kc,depth)-k; // => rows of B', and cols of the A'
|
||||||
|
|
||||||
// In order to reduce the chance that a thread has to wait for the other,
|
// In order to reduce the chance that a thread has to wait for the other,
|
||||||
// let's start by packing A'.
|
// let's start by packing A'.
|
||||||
@@ -139,7 +140,7 @@ static void run(Index rows, Index cols, Index depth,
|
|||||||
// Then keep going as usual with the remaining A'
|
// Then keep going as usual with the remaining A'
|
||||||
for(Index i=mc; i<rows; i+=mc)
|
for(Index i=mc; i<rows; i+=mc)
|
||||||
{
|
{
|
||||||
const Index actual_mc = std::min(i+mc,rows)-i;
|
const Index actual_mc = (std::min)(i+mc,rows)-i;
|
||||||
|
|
||||||
// pack A_i,k to A'
|
// pack A_i,k to A'
|
||||||
pack_lhs(blockA, &lhs(i,k), lhsStride, actual_kc, actual_mc);
|
pack_lhs(blockA, &lhs(i,k), lhsStride, actual_kc, actual_mc);
|
||||||
@@ -154,9 +155,6 @@ static void run(Index rows, Index cols, Index depth,
|
|||||||
#pragma omp atomic
|
#pragma omp atomic
|
||||||
--(info[j].users);
|
--(info[j].users);
|
||||||
}
|
}
|
||||||
|
|
||||||
ei_aligned_stack_delete(LhsScalar, blockA, kc*mc);
|
|
||||||
ei_aligned_stack_delete(RhsScalar, w, sizeW);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif // EIGEN_HAS_OPENMP
|
#endif // EIGEN_HAS_OPENMP
|
||||||
@@ -167,15 +165,16 @@ static void run(Index rows, Index cols, Index depth,
|
|||||||
std::size_t sizeA = kc*mc;
|
std::size_t sizeA = kc*mc;
|
||||||
std::size_t sizeB = kc*cols;
|
std::size_t sizeB = kc*cols;
|
||||||
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
|
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
|
||||||
LhsScalar *blockA = blocking.blockA()==0 ? ei_aligned_stack_new(LhsScalar, sizeA) : blocking.blockA();
|
|
||||||
RhsScalar *blockB = blocking.blockB()==0 ? ei_aligned_stack_new(RhsScalar, sizeB) : blocking.blockB();
|
ei_declare_aligned_stack_constructed_variable(LhsScalar, blockA, sizeA, blocking.blockA());
|
||||||
RhsScalar *blockW = blocking.blockW()==0 ? ei_aligned_stack_new(RhsScalar, sizeW) : blocking.blockW();
|
ei_declare_aligned_stack_constructed_variable(RhsScalar, blockB, sizeB, blocking.blockB());
|
||||||
|
ei_declare_aligned_stack_constructed_variable(RhsScalar, blockW, sizeW, blocking.blockW());
|
||||||
|
|
||||||
// For each horizontal panel of the rhs, and corresponding panel of the lhs...
|
// For each horizontal panel of the rhs, and corresponding panel of the lhs...
|
||||||
// (==GEMM_VAR1)
|
// (==GEMM_VAR1)
|
||||||
for(Index k2=0; k2<depth; k2+=kc)
|
for(Index k2=0; k2<depth; k2+=kc)
|
||||||
{
|
{
|
||||||
const Index actual_kc = std::min(k2+kc,depth)-k2;
|
const Index actual_kc = (std::min)(k2+kc,depth)-k2;
|
||||||
|
|
||||||
// OK, here we have selected one horizontal panel of rhs and one vertical panel of lhs.
|
// OK, here we have selected one horizontal panel of rhs and one vertical panel of lhs.
|
||||||
// => Pack rhs's panel into a sequential chunk of memory (L2 caching)
|
// => Pack rhs's panel into a sequential chunk of memory (L2 caching)
|
||||||
@@ -188,7 +187,7 @@ static void run(Index rows, Index cols, Index depth,
|
|||||||
// (==GEPP_VAR1)
|
// (==GEPP_VAR1)
|
||||||
for(Index i2=0; i2<rows; i2+=mc)
|
for(Index i2=0; i2<rows; i2+=mc)
|
||||||
{
|
{
|
||||||
const Index actual_mc = std::min(i2+mc,rows)-i2;
|
const Index actual_mc = (std::min)(i2+mc,rows)-i2;
|
||||||
|
|
||||||
// We pack the lhs's block into a sequential chunk of memory (L1 caching)
|
// We pack the lhs's block into a sequential chunk of memory (L1 caching)
|
||||||
// Note that this block will be read a very high number of times, which is equal to the number of
|
// Note that this block will be read a very high number of times, which is equal to the number of
|
||||||
@@ -200,10 +199,6 @@ static void run(Index rows, Index cols, Index depth,
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(blocking.blockA()==0) ei_aligned_stack_delete(LhsScalar, blockA, sizeA);
|
|
||||||
if(blocking.blockB()==0) ei_aligned_stack_delete(RhsScalar, blockB, sizeB);
|
|
||||||
if(blocking.blockW()==0) ei_aligned_stack_delete(RhsScalar, blockW, sizeW);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,10 +83,10 @@ struct general_matrix_matrix_triangular_product<Index,LhsScalar,LhsStorageOrder,
|
|||||||
if(mc > Traits::nr)
|
if(mc > Traits::nr)
|
||||||
mc = (mc/Traits::nr)*Traits::nr;
|
mc = (mc/Traits::nr)*Traits::nr;
|
||||||
|
|
||||||
LhsScalar* blockA = ei_aligned_stack_new(LhsScalar, kc*mc);
|
|
||||||
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
|
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
|
||||||
std::size_t sizeB = sizeW + kc*size;
|
std::size_t sizeB = sizeW + kc*size;
|
||||||
RhsScalar* allocatedBlockB = ei_aligned_stack_new(RhsScalar, sizeB);
|
ei_declare_aligned_stack_constructed_variable(LhsScalar, blockA, kc*mc, 0);
|
||||||
|
ei_declare_aligned_stack_constructed_variable(RhsScalar, allocatedBlockB, sizeB, 0);
|
||||||
RhsScalar* blockB = allocatedBlockB + sizeW;
|
RhsScalar* blockB = allocatedBlockB + sizeW;
|
||||||
|
|
||||||
gemm_pack_lhs<LhsScalar, Index, Traits::mr, Traits::LhsProgress, LhsStorageOrder> pack_lhs;
|
gemm_pack_lhs<LhsScalar, Index, Traits::mr, Traits::LhsProgress, LhsStorageOrder> pack_lhs;
|
||||||
@@ -96,14 +96,14 @@ struct general_matrix_matrix_triangular_product<Index,LhsScalar,LhsStorageOrder,
|
|||||||
|
|
||||||
for(Index k2=0; k2<depth; k2+=kc)
|
for(Index k2=0; k2<depth; k2+=kc)
|
||||||
{
|
{
|
||||||
const Index actual_kc = std::min(k2+kc,depth)-k2;
|
const Index actual_kc = (std::min)(k2+kc,depth)-k2;
|
||||||
|
|
||||||
// note that the actual rhs is the transpose/adjoint of mat
|
// note that the actual rhs is the transpose/adjoint of mat
|
||||||
pack_rhs(blockB, &rhs(k2,0), rhsStride, actual_kc, size);
|
pack_rhs(blockB, &rhs(k2,0), rhsStride, actual_kc, size);
|
||||||
|
|
||||||
for(Index i2=0; i2<size; i2+=mc)
|
for(Index i2=0; i2<size; i2+=mc)
|
||||||
{
|
{
|
||||||
const Index actual_mc = std::min(i2+mc,size)-i2;
|
const Index actual_mc = (std::min)(i2+mc,size)-i2;
|
||||||
|
|
||||||
pack_lhs(blockA, &lhs(i2, k2), lhsStride, actual_kc, actual_mc);
|
pack_lhs(blockA, &lhs(i2, k2), lhsStride, actual_kc, actual_mc);
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ struct general_matrix_matrix_triangular_product<Index,LhsScalar,LhsStorageOrder,
|
|||||||
// 2 - the actual_mc x actual_mc symmetric block => processed with a special kernel
|
// 2 - the actual_mc x actual_mc symmetric block => processed with a special kernel
|
||||||
// 3 - after the diagonal => processed with gebp or skipped
|
// 3 - after the diagonal => processed with gebp or skipped
|
||||||
if (UpLo==Lower)
|
if (UpLo==Lower)
|
||||||
gebp(res+i2, resStride, blockA, blockB, actual_mc, actual_kc, std::min(size,i2), alpha,
|
gebp(res+i2, resStride, blockA, blockB, actual_mc, actual_kc, (std::min)(size,i2), alpha,
|
||||||
-1, -1, 0, 0, allocatedBlockB);
|
-1, -1, 0, 0, allocatedBlockB);
|
||||||
|
|
||||||
sybb(res+resStride*i2 + i2, resStride, blockA, blockB + actual_kc*i2, actual_mc, actual_kc, alpha, allocatedBlockB);
|
sybb(res+resStride*i2 + i2, resStride, blockA, blockB + actual_kc*i2, actual_mc, actual_kc, alpha, allocatedBlockB);
|
||||||
@@ -120,13 +120,11 @@ struct general_matrix_matrix_triangular_product<Index,LhsScalar,LhsStorageOrder,
|
|||||||
if (UpLo==Upper)
|
if (UpLo==Upper)
|
||||||
{
|
{
|
||||||
Index j2 = i2+actual_mc;
|
Index j2 = i2+actual_mc;
|
||||||
gebp(res+resStride*j2+i2, resStride, blockA, blockB+actual_kc*j2, actual_mc, actual_kc, std::max(Index(0), size-j2), alpha,
|
gebp(res+resStride*j2+i2, resStride, blockA, blockB+actual_kc*j2, actual_mc, actual_kc, (std::max)(Index(0), size-j2), alpha,
|
||||||
-1, -1, 0, 0, allocatedBlockB);
|
-1, -1, 0, 0, allocatedBlockB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ei_aligned_stack_delete(LhsScalar, blockA, kc*mc);
|
|
||||||
ei_aligned_stack_delete(RhsScalar, allocatedBlockB, sizeB);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ EIGEN_DONT_INLINE static void run(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
skipColumns = std::min(skipColumns,cols);
|
skipColumns = (std::min)(skipColumns,cols);
|
||||||
// note that the skiped columns are processed later.
|
// note that the skiped columns are processed later.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,7 +386,7 @@ EIGEN_DONT_INLINE static void run(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
skipRows = std::min(skipRows,Index(rows));
|
skipRows = (std::min)(skipRows,Index(rows));
|
||||||
// note that the skiped columns are processed later.
|
// note that the skiped columns are processed later.
|
||||||
}
|
}
|
||||||
eigen_internal_assert( alignmentPattern==NoneAligned
|
eigen_internal_assert( alignmentPattern==NoneAligned
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace internal {
|
|||||||
/** \internal */
|
/** \internal */
|
||||||
inline void manage_multi_threading(Action action, int* v)
|
inline void manage_multi_threading(Action action, int* v)
|
||||||
{
|
{
|
||||||
static int m_maxThreads = -1;
|
static EIGEN_UNUSED int m_maxThreads = -1;
|
||||||
|
|
||||||
if(action==SetAction)
|
if(action==SetAction)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ struct symm_pack_rhs
|
|||||||
}
|
}
|
||||||
|
|
||||||
// second part: diagonal block
|
// second part: diagonal block
|
||||||
for(Index j2=k2; j2<std::min(k2+rows,packet_cols); j2+=nr)
|
for(Index j2=k2; j2<(std::min)(k2+rows,packet_cols); j2+=nr)
|
||||||
{
|
{
|
||||||
// again we can split vertically in three different parts (transpose, symmetric, normal)
|
// again we can split vertically in three different parts (transpose, symmetric, normal)
|
||||||
// transpose
|
// transpose
|
||||||
@@ -179,7 +179,7 @@ struct symm_pack_rhs
|
|||||||
for(Index j2=packet_cols; j2<cols; ++j2)
|
for(Index j2=packet_cols; j2<cols; ++j2)
|
||||||
{
|
{
|
||||||
// transpose
|
// transpose
|
||||||
Index half = std::min(end_k,j2);
|
Index half = (std::min)(end_k,j2);
|
||||||
for(Index k=k2; k<half; k++)
|
for(Index k=k2; k<half; k++)
|
||||||
{
|
{
|
||||||
blockB[count] = conj(rhs(j2,k));
|
blockB[count] = conj(rhs(j2,k));
|
||||||
@@ -261,12 +261,12 @@ struct product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,true,ConjugateLhs
|
|||||||
Index nc = cols; // cache block size along the N direction
|
Index nc = cols; // cache block size along the N direction
|
||||||
computeProductBlockingSizes<Scalar,Scalar>(kc, mc, nc);
|
computeProductBlockingSizes<Scalar,Scalar>(kc, mc, nc);
|
||||||
// kc must smaller than mc
|
// kc must smaller than mc
|
||||||
kc = std::min(kc,mc);
|
kc = (std::min)(kc,mc);
|
||||||
|
|
||||||
Scalar* blockA = ei_aligned_stack_new(Scalar, kc*mc);
|
|
||||||
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
|
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
|
||||||
std::size_t sizeB = sizeW + kc*cols;
|
std::size_t sizeB = sizeW + kc*cols;
|
||||||
Scalar* allocatedBlockB = ei_aligned_stack_new(Scalar, sizeB);
|
ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0);
|
||||||
|
ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0);
|
||||||
Scalar* blockB = allocatedBlockB + sizeW;
|
Scalar* blockB = allocatedBlockB + sizeW;
|
||||||
|
|
||||||
gebp_kernel<Scalar, Scalar, Index, Traits::mr, Traits::nr, ConjugateLhs, ConjugateRhs> gebp_kernel;
|
gebp_kernel<Scalar, Scalar, Index, Traits::mr, Traits::nr, ConjugateLhs, ConjugateRhs> gebp_kernel;
|
||||||
@@ -276,7 +276,7 @@ struct product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,true,ConjugateLhs
|
|||||||
|
|
||||||
for(Index k2=0; k2<size; k2+=kc)
|
for(Index k2=0; k2<size; k2+=kc)
|
||||||
{
|
{
|
||||||
const Index actual_kc = std::min(k2+kc,size)-k2;
|
const Index actual_kc = (std::min)(k2+kc,size)-k2;
|
||||||
|
|
||||||
// we have selected one row panel of rhs and one column panel of lhs
|
// we have selected one row panel of rhs and one column panel of lhs
|
||||||
// pack rhs's panel into a sequential chunk of memory
|
// pack rhs's panel into a sequential chunk of memory
|
||||||
@@ -289,7 +289,7 @@ struct product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,true,ConjugateLhs
|
|||||||
// 3 - the panel below the diagonal block => generic packed copy
|
// 3 - the panel below the diagonal block => generic packed copy
|
||||||
for(Index i2=0; i2<k2; i2+=mc)
|
for(Index i2=0; i2<k2; i2+=mc)
|
||||||
{
|
{
|
||||||
const Index actual_mc = std::min(i2+mc,k2)-i2;
|
const Index actual_mc = (std::min)(i2+mc,k2)-i2;
|
||||||
// transposed packed copy
|
// transposed packed copy
|
||||||
pack_lhs_transposed(blockA, &lhs(k2, i2), lhsStride, actual_kc, actual_mc);
|
pack_lhs_transposed(blockA, &lhs(k2, i2), lhsStride, actual_kc, actual_mc);
|
||||||
|
|
||||||
@@ -297,7 +297,7 @@ struct product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,true,ConjugateLhs
|
|||||||
}
|
}
|
||||||
// the block diagonal
|
// the block diagonal
|
||||||
{
|
{
|
||||||
const Index actual_mc = std::min(k2+kc,size)-k2;
|
const Index actual_mc = (std::min)(k2+kc,size)-k2;
|
||||||
// symmetric packed copy
|
// symmetric packed copy
|
||||||
pack_lhs(blockA, &lhs(k2,k2), lhsStride, actual_kc, actual_mc);
|
pack_lhs(blockA, &lhs(k2,k2), lhsStride, actual_kc, actual_mc);
|
||||||
|
|
||||||
@@ -306,16 +306,13 @@ struct product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,true,ConjugateLhs
|
|||||||
|
|
||||||
for(Index i2=k2+kc; i2<size; i2+=mc)
|
for(Index i2=k2+kc; i2<size; i2+=mc)
|
||||||
{
|
{
|
||||||
const Index actual_mc = std::min(i2+mc,size)-i2;
|
const Index actual_mc = (std::min)(i2+mc,size)-i2;
|
||||||
gemm_pack_lhs<Scalar, Index, Traits::mr, Traits::LhsProgress, LhsStorageOrder,false>()
|
gemm_pack_lhs<Scalar, Index, Traits::mr, Traits::LhsProgress, LhsStorageOrder,false>()
|
||||||
(blockA, &lhs(i2, k2), lhsStride, actual_kc, actual_mc);
|
(blockA, &lhs(i2, k2), lhsStride, actual_kc, actual_mc);
|
||||||
|
|
||||||
gebp_kernel(res+i2, resStride, blockA, blockB, actual_mc, actual_kc, cols, alpha);
|
gebp_kernel(res+i2, resStride, blockA, blockB, actual_mc, actual_kc, cols, alpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ei_aligned_stack_delete(Scalar, blockA, kc*mc);
|
|
||||||
ei_aligned_stack_delete(Scalar, allocatedBlockB, sizeB);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -343,11 +340,10 @@ struct product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,false,ConjugateLh
|
|||||||
Index mc = rows; // cache block size along the M direction
|
Index mc = rows; // cache block size along the M direction
|
||||||
Index nc = cols; // cache block size along the N direction
|
Index nc = cols; // cache block size along the N direction
|
||||||
computeProductBlockingSizes<Scalar,Scalar>(kc, mc, nc);
|
computeProductBlockingSizes<Scalar,Scalar>(kc, mc, nc);
|
||||||
|
|
||||||
Scalar* blockA = ei_aligned_stack_new(Scalar, kc*mc);
|
|
||||||
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
|
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
|
||||||
std::size_t sizeB = sizeW + kc*cols;
|
std::size_t sizeB = sizeW + kc*cols;
|
||||||
Scalar* allocatedBlockB = ei_aligned_stack_new(Scalar, sizeB);
|
ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0);
|
||||||
|
ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0);
|
||||||
Scalar* blockB = allocatedBlockB + sizeW;
|
Scalar* blockB = allocatedBlockB + sizeW;
|
||||||
|
|
||||||
gebp_kernel<Scalar, Scalar, Index, Traits::mr, Traits::nr, ConjugateLhs, ConjugateRhs> gebp_kernel;
|
gebp_kernel<Scalar, Scalar, Index, Traits::mr, Traits::nr, ConjugateLhs, ConjugateRhs> gebp_kernel;
|
||||||
@@ -356,22 +352,19 @@ struct product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,false,ConjugateLh
|
|||||||
|
|
||||||
for(Index k2=0; k2<size; k2+=kc)
|
for(Index k2=0; k2<size; k2+=kc)
|
||||||
{
|
{
|
||||||
const Index actual_kc = std::min(k2+kc,size)-k2;
|
const Index actual_kc = (std::min)(k2+kc,size)-k2;
|
||||||
|
|
||||||
pack_rhs(blockB, _rhs, rhsStride, actual_kc, cols, k2);
|
pack_rhs(blockB, _rhs, rhsStride, actual_kc, cols, k2);
|
||||||
|
|
||||||
// => GEPP
|
// => GEPP
|
||||||
for(Index i2=0; i2<rows; i2+=mc)
|
for(Index i2=0; i2<rows; i2+=mc)
|
||||||
{
|
{
|
||||||
const Index actual_mc = std::min(i2+mc,rows)-i2;
|
const Index actual_mc = (std::min)(i2+mc,rows)-i2;
|
||||||
pack_lhs(blockA, &lhs(i2, k2), lhsStride, actual_kc, actual_mc);
|
pack_lhs(blockA, &lhs(i2, k2), lhsStride, actual_kc, actual_mc);
|
||||||
|
|
||||||
gebp_kernel(res+i2, resStride, blockA, blockB, actual_mc, actual_kc, cols, alpha);
|
gebp_kernel(res+i2, resStride, blockA, blockB, actual_mc, actual_kc, cols, alpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ei_aligned_stack_delete(Scalar, blockA, kc*mc);
|
|
||||||
ei_aligned_stack_delete(Scalar, allocatedBlockB, sizeB);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -62,17 +62,15 @@ static EIGEN_DONT_INLINE void product_selfadjoint_vector(
|
|||||||
// FIXME this copy is now handled outside product_selfadjoint_vector, so it could probably be removed.
|
// 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,
|
// if the rhs is not sequentially stored in memory we copy it to a temporary buffer,
|
||||||
// this is because we need to extract packets
|
// this is because we need to extract packets
|
||||||
const Scalar* EIGEN_RESTRICT rhs = _rhs;
|
ei_declare_aligned_stack_constructed_variable(Scalar,rhs,size,rhsIncr==1 ? const_cast<Scalar*>(_rhs) : 0);
|
||||||
if (rhsIncr!=1)
|
if (rhsIncr!=1)
|
||||||
{
|
{
|
||||||
Scalar* r = ei_aligned_stack_new(Scalar, size);
|
|
||||||
const Scalar* it = _rhs;
|
const Scalar* it = _rhs;
|
||||||
for (Index i=0; i<size; ++i, it+=rhsIncr)
|
for (Index i=0; i<size; ++i, it+=rhsIncr)
|
||||||
r[i] = *it;
|
rhs[i] = *it;
|
||||||
rhs = r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Index bound = std::max(Index(0),size-8) & 0xfffffffe;
|
Index bound = (std::max)(Index(0),size-8) & 0xfffffffe;
|
||||||
if (FirstTriangular)
|
if (FirstTriangular)
|
||||||
bound = size - bound;
|
bound = size - bound;
|
||||||
|
|
||||||
@@ -160,9 +158,6 @@ static EIGEN_DONT_INLINE void product_selfadjoint_vector(
|
|||||||
}
|
}
|
||||||
res[j] += alpha * t2;
|
res[j] += alpha * t2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rhsIncr!=1)
|
|
||||||
ei_aligned_stack_delete(Scalar, const_cast<Scalar*>(rhs), size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
@@ -211,40 +206,28 @@ struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,0,true>
|
|||||||
|
|
||||||
internal::gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,!EvalToDest> static_dest;
|
internal::gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,!EvalToDest> static_dest;
|
||||||
internal::gemv_static_vector_if<RhsScalar,_ActualRhsType::SizeAtCompileTime,_ActualRhsType::MaxSizeAtCompileTime,!UseRhs> static_rhs;
|
internal::gemv_static_vector_if<RhsScalar,_ActualRhsType::SizeAtCompileTime,_ActualRhsType::MaxSizeAtCompileTime,!UseRhs> static_rhs;
|
||||||
|
|
||||||
|
ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(),
|
||||||
|
EvalToDest ? dest.data() : static_dest.data());
|
||||||
|
|
||||||
|
ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,rhs.size(),
|
||||||
|
UseRhs ? const_cast<RhsScalar*>(rhs.data()) : static_rhs.data());
|
||||||
|
|
||||||
bool freeDestPtr = false;
|
if(!EvalToDest)
|
||||||
ResScalar* actualDestPtr;
|
|
||||||
if(EvalToDest)
|
|
||||||
actualDestPtr = dest.data();
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||||
int size = dest.size();
|
int size = dest.size();
|
||||||
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||||
#endif
|
#endif
|
||||||
if((actualDestPtr=static_dest.data())==0)
|
|
||||||
{
|
|
||||||
freeDestPtr = true;
|
|
||||||
actualDestPtr = ei_aligned_stack_new(ResScalar,dest.size());
|
|
||||||
}
|
|
||||||
MappedDest(actualDestPtr, dest.size()) = dest;
|
MappedDest(actualDestPtr, dest.size()) = dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool freeRhsPtr = false;
|
if(!UseRhs)
|
||||||
RhsScalar* actualRhsPtr;
|
|
||||||
if(UseRhs)
|
|
||||||
actualRhsPtr = const_cast<RhsScalar*>(rhs.data());
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||||
int size = rhs.size();
|
int size = rhs.size();
|
||||||
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||||
#endif
|
#endif
|
||||||
if((actualRhsPtr=static_rhs.data())==0)
|
|
||||||
{
|
|
||||||
freeRhsPtr = true;
|
|
||||||
actualRhsPtr = ei_aligned_stack_new(RhsScalar,rhs.size());
|
|
||||||
}
|
|
||||||
Map<typename _ActualRhsType::PlainObject>(actualRhsPtr, rhs.size()) = rhs;
|
Map<typename _ActualRhsType::PlainObject>(actualRhsPtr, rhs.size()) = rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,11 +242,7 @@ struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,0,true>
|
|||||||
);
|
);
|
||||||
|
|
||||||
if(!EvalToDest)
|
if(!EvalToDest)
|
||||||
{
|
|
||||||
dest = MappedDest(actualDestPtr, dest.size());
|
dest = MappedDest(actualDestPtr, dest.size());
|
||||||
if(freeDestPtr) ei_aligned_stack_delete(ResScalar, actualDestPtr, dest.size());
|
|
||||||
}
|
|
||||||
if(freeRhsPtr) ei_aligned_stack_delete(RhsScalar, actualRhsPtr, rhs.size());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -81,27 +81,17 @@ struct selfadjoint_product_selector<MatrixType,OtherType,UpLo,true>
|
|||||||
UseOtherDirectly = _ActualOtherType::InnerStrideAtCompileTime==1
|
UseOtherDirectly = _ActualOtherType::InnerStrideAtCompileTime==1
|
||||||
};
|
};
|
||||||
internal::gemv_static_vector_if<Scalar,OtherType::SizeAtCompileTime,OtherType::MaxSizeAtCompileTime,!UseOtherDirectly> static_other;
|
internal::gemv_static_vector_if<Scalar,OtherType::SizeAtCompileTime,OtherType::MaxSizeAtCompileTime,!UseOtherDirectly> static_other;
|
||||||
|
|
||||||
bool freeOtherPtr = false;
|
ei_declare_aligned_stack_constructed_variable(Scalar, actualOtherPtr, other.size(),
|
||||||
Scalar* actualOtherPtr;
|
(UseOtherDirectly ? const_cast<Scalar*>(actualOther.data()) : static_other.data()));
|
||||||
if(UseOtherDirectly)
|
|
||||||
actualOtherPtr = const_cast<Scalar*>(actualOther.data());
|
if(!UseOtherDirectly)
|
||||||
else
|
|
||||||
{
|
|
||||||
if((actualOtherPtr=static_other.data())==0)
|
|
||||||
{
|
|
||||||
freeOtherPtr = true;
|
|
||||||
actualOtherPtr = ei_aligned_stack_new(Scalar,other.size());
|
|
||||||
}
|
|
||||||
Map<typename _ActualOtherType::PlainObject>(actualOtherPtr, actualOther.size()) = actualOther;
|
Map<typename _ActualOtherType::PlainObject>(actualOtherPtr, actualOther.size()) = actualOther;
|
||||||
}
|
|
||||||
|
|
||||||
selfadjoint_rank1_update<Scalar,Index,StorageOrder,UpLo,
|
selfadjoint_rank1_update<Scalar,Index,StorageOrder,UpLo,
|
||||||
OtherBlasTraits::NeedToConjugate && NumTraits<Scalar>::IsComplex,
|
OtherBlasTraits::NeedToConjugate && NumTraits<Scalar>::IsComplex,
|
||||||
(!OtherBlasTraits::NeedToConjugate) && NumTraits<Scalar>::IsComplex>
|
(!OtherBlasTraits::NeedToConjugate) && NumTraits<Scalar>::IsComplex>
|
||||||
::run(other.size(), mat.data(), mat.outerStride(), actualOtherPtr, actualAlpha);
|
::run(other.size(), mat.data(), mat.outerStride(), actualOtherPtr, actualAlpha);
|
||||||
|
|
||||||
if((!UseOtherDirectly) && freeOtherPtr) ei_aligned_stack_delete(Scalar, actualOtherPtr, other.size());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -96,33 +96,38 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,true,
|
|||||||
LhsStorageOrder,ConjugateLhs,
|
LhsStorageOrder,ConjugateLhs,
|
||||||
RhsStorageOrder,ConjugateRhs,ColMajor>
|
RhsStorageOrder,ConjugateRhs,ColMajor>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
typedef gebp_traits<Scalar,Scalar> Traits;
|
||||||
|
enum {
|
||||||
|
SmallPanelWidth = EIGEN_PLAIN_ENUM_MAX(Traits::mr,Traits::nr),
|
||||||
|
IsLower = (Mode&Lower) == Lower,
|
||||||
|
SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1
|
||||||
|
};
|
||||||
|
|
||||||
static EIGEN_DONT_INLINE void run(
|
static EIGEN_DONT_INLINE void run(
|
||||||
Index rows, Index cols, Index depth,
|
Index _rows, Index _cols, Index _depth,
|
||||||
const Scalar* _lhs, Index lhsStride,
|
const Scalar* _lhs, Index lhsStride,
|
||||||
const Scalar* _rhs, Index rhsStride,
|
const Scalar* _rhs, Index rhsStride,
|
||||||
Scalar* res, Index resStride,
|
Scalar* res, Index resStride,
|
||||||
Scalar alpha)
|
Scalar alpha)
|
||||||
{
|
{
|
||||||
|
// strip zeros
|
||||||
|
Index diagSize = (std::min)(_rows,_depth);
|
||||||
|
Index rows = IsLower ? _rows : diagSize;
|
||||||
|
Index depth = IsLower ? diagSize : _depth;
|
||||||
|
Index cols = _cols;
|
||||||
|
|
||||||
const_blas_data_mapper<Scalar, Index, LhsStorageOrder> lhs(_lhs,lhsStride);
|
const_blas_data_mapper<Scalar, Index, LhsStorageOrder> lhs(_lhs,lhsStride);
|
||||||
const_blas_data_mapper<Scalar, Index, RhsStorageOrder> rhs(_rhs,rhsStride);
|
const_blas_data_mapper<Scalar, Index, RhsStorageOrder> rhs(_rhs,rhsStride);
|
||||||
|
|
||||||
typedef gebp_traits<Scalar,Scalar> Traits;
|
|
||||||
enum {
|
|
||||||
SmallPanelWidth = EIGEN_PLAIN_ENUM_MAX(Traits::mr,Traits::nr),
|
|
||||||
IsLower = (Mode&Lower) == Lower,
|
|
||||||
SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1
|
|
||||||
};
|
|
||||||
|
|
||||||
Index kc = depth; // cache block size along the K direction
|
Index kc = depth; // cache block size along the K direction
|
||||||
Index mc = rows; // cache block size along the M direction
|
Index mc = rows; // cache block size along the M direction
|
||||||
Index nc = cols; // cache block size along the N direction
|
Index nc = cols; // cache block size along the N direction
|
||||||
computeProductBlockingSizes<Scalar,Scalar,4>(kc, mc, nc);
|
computeProductBlockingSizes<Scalar,Scalar,4>(kc, mc, nc);
|
||||||
|
|
||||||
Scalar* blockA = ei_aligned_stack_new(Scalar, kc*mc);
|
|
||||||
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
|
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
|
||||||
std::size_t sizeB = sizeW + kc*cols;
|
std::size_t sizeB = sizeW + kc*cols;
|
||||||
Scalar* allocatedBlockB = ei_aligned_stack_new(Scalar, sizeB);
|
ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0);
|
||||||
|
ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0);
|
||||||
Scalar* blockB = allocatedBlockB + sizeW;
|
Scalar* blockB = allocatedBlockB + sizeW;
|
||||||
|
|
||||||
Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,LhsStorageOrder> triangularBuffer;
|
Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,LhsStorageOrder> triangularBuffer;
|
||||||
@@ -140,7 +145,7 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,true,
|
|||||||
IsLower ? k2>0 : k2<depth;
|
IsLower ? k2>0 : k2<depth;
|
||||||
IsLower ? k2-=kc : k2+=kc)
|
IsLower ? k2-=kc : k2+=kc)
|
||||||
{
|
{
|
||||||
Index actual_kc = std::min(IsLower ? k2 : depth-k2, kc);
|
Index actual_kc = (std::min)(IsLower ? k2 : depth-k2, kc);
|
||||||
Index actual_k2 = IsLower ? k2-actual_kc : k2;
|
Index actual_k2 = IsLower ? k2-actual_kc : k2;
|
||||||
|
|
||||||
// align blocks with the end of the triangular part for trapezoidal lhs
|
// align blocks with the end of the triangular part for trapezoidal lhs
|
||||||
@@ -153,10 +158,11 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,true,
|
|||||||
pack_rhs(blockB, &rhs(actual_k2,0), rhsStride, actual_kc, cols);
|
pack_rhs(blockB, &rhs(actual_k2,0), rhsStride, actual_kc, cols);
|
||||||
|
|
||||||
// the selected lhs's panel has to be split in three different parts:
|
// the selected lhs's panel has to be split in three different parts:
|
||||||
// 1 - the part which is above the diagonal block => skip it
|
// 1 - the part which is zero => skip it
|
||||||
// 2 - the diagonal block => special kernel
|
// 2 - the diagonal block => special kernel
|
||||||
// 3 - the panel below the diagonal block => GEPP
|
// 3 - the dense panel below (lower case) or above (upper case) the diagonal block => GEPP
|
||||||
// the block diagonal, if any
|
|
||||||
|
// the block diagonal, if any:
|
||||||
if(IsLower || actual_k2<rows)
|
if(IsLower || actual_k2<rows)
|
||||||
{
|
{
|
||||||
// for each small vertical panels of lhs
|
// for each small vertical panels of lhs
|
||||||
@@ -194,13 +200,13 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,true,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// the part below the diagonal => GEPP
|
// the part below (lower case) or above (upper case) the diagonal => GEPP
|
||||||
{
|
{
|
||||||
Index start = IsLower ? k2 : 0;
|
Index start = IsLower ? k2 : 0;
|
||||||
Index end = IsLower ? rows : std::min(actual_k2,rows);
|
Index end = IsLower ? rows : (std::min)(actual_k2,rows);
|
||||||
for(Index i2=start; i2<end; i2+=mc)
|
for(Index i2=start; i2<end; i2+=mc)
|
||||||
{
|
{
|
||||||
const Index actual_mc = std::min(i2+mc,end)-i2;
|
const Index actual_mc = (std::min)(i2+mc,end)-i2;
|
||||||
gemm_pack_lhs<Scalar, Index, Traits::mr,Traits::LhsProgress, LhsStorageOrder,false>()
|
gemm_pack_lhs<Scalar, Index, Traits::mr,Traits::LhsProgress, LhsStorageOrder,false>()
|
||||||
(blockA, &lhs(i2, actual_k2), lhsStride, actual_kc, actual_mc);
|
(blockA, &lhs(i2, actual_k2), lhsStride, actual_kc, actual_mc);
|
||||||
|
|
||||||
@@ -208,10 +214,6 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,true,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ei_aligned_stack_delete(Scalar, blockA, kc*mc);
|
|
||||||
ei_aligned_stack_delete(Scalar, allocatedBlockB, sizeB);
|
|
||||||
// delete[] allocatedBlockB;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -223,33 +225,38 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,false,
|
|||||||
LhsStorageOrder,ConjugateLhs,
|
LhsStorageOrder,ConjugateLhs,
|
||||||
RhsStorageOrder,ConjugateRhs,ColMajor>
|
RhsStorageOrder,ConjugateRhs,ColMajor>
|
||||||
{
|
{
|
||||||
|
typedef gebp_traits<Scalar,Scalar> Traits;
|
||||||
|
enum {
|
||||||
|
SmallPanelWidth = EIGEN_PLAIN_ENUM_MAX(Traits::mr,Traits::nr),
|
||||||
|
IsLower = (Mode&Lower) == Lower,
|
||||||
|
SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1
|
||||||
|
};
|
||||||
|
|
||||||
static EIGEN_DONT_INLINE void run(
|
static EIGEN_DONT_INLINE void run(
|
||||||
Index rows, Index cols, Index depth,
|
Index _rows, Index _cols, Index _depth,
|
||||||
const Scalar* _lhs, Index lhsStride,
|
const Scalar* _lhs, Index lhsStride,
|
||||||
const Scalar* _rhs, Index rhsStride,
|
const Scalar* _rhs, Index rhsStride,
|
||||||
Scalar* res, Index resStride,
|
Scalar* res, Index resStride,
|
||||||
Scalar alpha)
|
Scalar alpha)
|
||||||
{
|
{
|
||||||
|
// strip zeros
|
||||||
|
Index diagSize = (std::min)(_cols,_depth);
|
||||||
|
Index rows = _rows;
|
||||||
|
Index depth = IsLower ? _depth : diagSize;
|
||||||
|
Index cols = IsLower ? diagSize : _cols;
|
||||||
|
|
||||||
const_blas_data_mapper<Scalar, Index, LhsStorageOrder> lhs(_lhs,lhsStride);
|
const_blas_data_mapper<Scalar, Index, LhsStorageOrder> lhs(_lhs,lhsStride);
|
||||||
const_blas_data_mapper<Scalar, Index, RhsStorageOrder> rhs(_rhs,rhsStride);
|
const_blas_data_mapper<Scalar, Index, RhsStorageOrder> rhs(_rhs,rhsStride);
|
||||||
|
|
||||||
typedef gebp_traits<Scalar,Scalar> Traits;
|
|
||||||
enum {
|
|
||||||
SmallPanelWidth = EIGEN_PLAIN_ENUM_MAX(Traits::mr,Traits::nr),
|
|
||||||
IsLower = (Mode&Lower) == Lower,
|
|
||||||
SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1
|
|
||||||
};
|
|
||||||
|
|
||||||
Index kc = depth; // cache block size along the K direction
|
Index kc = depth; // cache block size along the K direction
|
||||||
Index mc = rows; // cache block size along the M direction
|
Index mc = rows; // cache block size along the M direction
|
||||||
Index nc = cols; // cache block size along the N direction
|
Index nc = cols; // cache block size along the N direction
|
||||||
computeProductBlockingSizes<Scalar,Scalar,4>(kc, mc, nc);
|
computeProductBlockingSizes<Scalar,Scalar,4>(kc, mc, nc);
|
||||||
|
|
||||||
Scalar* blockA = ei_aligned_stack_new(Scalar, kc*mc);
|
|
||||||
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
|
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
|
||||||
std::size_t sizeB = sizeW + kc*cols;
|
std::size_t sizeB = sizeW + kc*cols;
|
||||||
Scalar* allocatedBlockB = ei_aligned_stack_new(Scalar,sizeB);
|
ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0);
|
||||||
|
ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0);
|
||||||
Scalar* blockB = allocatedBlockB + sizeW;
|
Scalar* blockB = allocatedBlockB + sizeW;
|
||||||
|
|
||||||
Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,RhsStorageOrder> triangularBuffer;
|
Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,RhsStorageOrder> triangularBuffer;
|
||||||
@@ -268,7 +275,7 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,false,
|
|||||||
IsLower ? k2<depth : k2>0;
|
IsLower ? k2<depth : k2>0;
|
||||||
IsLower ? k2+=kc : k2-=kc)
|
IsLower ? k2+=kc : k2-=kc)
|
||||||
{
|
{
|
||||||
Index actual_kc = std::min(IsLower ? depth-k2 : k2, kc);
|
Index actual_kc = (std::min)(IsLower ? depth-k2 : k2, kc);
|
||||||
Index actual_k2 = IsLower ? k2 : k2-actual_kc;
|
Index actual_k2 = IsLower ? k2 : k2-actual_kc;
|
||||||
|
|
||||||
// align blocks with the end of the triangular part for trapezoidal rhs
|
// align blocks with the end of the triangular part for trapezoidal rhs
|
||||||
@@ -279,7 +286,7 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,false,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// remaining size
|
// remaining size
|
||||||
Index rs = IsLower ? std::min(cols,actual_k2) : cols - k2;
|
Index rs = IsLower ? (std::min)(cols,actual_k2) : cols - k2;
|
||||||
// size of the triangular part
|
// size of the triangular part
|
||||||
Index ts = (IsLower && actual_k2>=cols) ? 0 : actual_kc;
|
Index ts = (IsLower && actual_k2>=cols) ? 0 : actual_kc;
|
||||||
|
|
||||||
@@ -320,7 +327,7 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,false,
|
|||||||
|
|
||||||
for (Index i2=0; i2<rows; i2+=mc)
|
for (Index i2=0; i2<rows; i2+=mc)
|
||||||
{
|
{
|
||||||
const Index actual_mc = std::min(mc,rows-i2);
|
const Index actual_mc = (std::min)(mc,rows-i2);
|
||||||
pack_lhs(blockA, &lhs(i2, actual_k2), lhsStride, actual_kc, actual_mc);
|
pack_lhs(blockA, &lhs(i2, actual_k2), lhsStride, actual_kc, actual_mc);
|
||||||
|
|
||||||
// triangular kernel
|
// triangular kernel
|
||||||
@@ -347,9 +354,6 @@ struct product_triangular_matrix_matrix<Scalar,Index,Mode,false,
|
|||||||
-1, -1, 0, 0, allocatedBlockB);
|
-1, -1, 0, 0, allocatedBlockB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ei_aligned_stack_delete(Scalar, blockA, kc*mc);
|
|
||||||
ei_aligned_stack_delete(Scalar, allocatedBlockB, sizeB);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -41,9 +41,6 @@ struct product_triangular_matrix_vector<Index,Mode,LhsScalar,ConjLhs,RhsScalar,C
|
|||||||
static EIGEN_DONT_INLINE void run(Index rows, Index cols, const LhsScalar* _lhs, Index lhsStride,
|
static EIGEN_DONT_INLINE void run(Index rows, Index cols, const LhsScalar* _lhs, Index lhsStride,
|
||||||
const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, ResScalar alpha)
|
const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, ResScalar alpha)
|
||||||
{
|
{
|
||||||
EIGEN_UNUSED_VARIABLE(resIncr);
|
|
||||||
eigen_assert(resIncr==1);
|
|
||||||
|
|
||||||
static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH;
|
static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH;
|
||||||
|
|
||||||
typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,ColMajor>, 0, OuterStride<> > LhsMap;
|
typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,ColMajor>, 0, OuterStride<> > LhsMap;
|
||||||
@@ -59,7 +56,7 @@ struct product_triangular_matrix_vector<Index,Mode,LhsScalar,ConjLhs,RhsScalar,C
|
|||||||
|
|
||||||
for (Index pi=0; pi<cols; pi+=PanelWidth)
|
for (Index pi=0; pi<cols; pi+=PanelWidth)
|
||||||
{
|
{
|
||||||
Index actualPanelWidth = std::min(PanelWidth, cols-pi);
|
Index actualPanelWidth = (std::min)(PanelWidth, cols-pi);
|
||||||
for (Index k=0; k<actualPanelWidth; ++k)
|
for (Index k=0; k<actualPanelWidth; ++k)
|
||||||
{
|
{
|
||||||
Index i = pi + k;
|
Index i = pi + k;
|
||||||
@@ -95,9 +92,6 @@ struct product_triangular_matrix_vector<Index,Mode,LhsScalar,ConjLhs,RhsScalar,C
|
|||||||
static void run(Index rows, Index cols, const LhsScalar* _lhs, Index lhsStride,
|
static void run(Index rows, Index cols, const LhsScalar* _lhs, Index lhsStride,
|
||||||
const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, ResScalar alpha)
|
const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, ResScalar alpha)
|
||||||
{
|
{
|
||||||
eigen_assert(rhsIncr==1);
|
|
||||||
EIGEN_UNUSED_VARIABLE(rhsIncr);
|
|
||||||
|
|
||||||
static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH;
|
static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH;
|
||||||
|
|
||||||
typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,RowMajor>, 0, OuterStride<> > LhsMap;
|
typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,RowMajor>, 0, OuterStride<> > LhsMap;
|
||||||
@@ -113,7 +107,7 @@ struct product_triangular_matrix_vector<Index,Mode,LhsScalar,ConjLhs,RhsScalar,C
|
|||||||
|
|
||||||
for (Index pi=0; pi<cols; pi+=PanelWidth)
|
for (Index pi=0; pi<cols; pi+=PanelWidth)
|
||||||
{
|
{
|
||||||
Index actualPanelWidth = std::min(PanelWidth, cols-pi);
|
Index actualPanelWidth = (std::min)(PanelWidth, cols-pi);
|
||||||
for (Index k=0; k<actualPanelWidth; ++k)
|
for (Index k=0; k<actualPanelWidth; ++k)
|
||||||
{
|
{
|
||||||
Index i = pi + k;
|
Index i = pi + k;
|
||||||
@@ -185,7 +179,7 @@ struct TriangularProduct<Mode,false,Lhs,true,Rhs,false>
|
|||||||
template<typename Dest> void scaleAndAddTo(Dest& dst, Scalar alpha) const
|
template<typename Dest> void scaleAndAddTo(Dest& dst, Scalar alpha) const
|
||||||
{
|
{
|
||||||
eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols());
|
eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols());
|
||||||
|
|
||||||
typedef TriangularProduct<(Mode & UnitDiag) | ((Mode & Lower) ? Upper : Lower),true,Transpose<const Rhs>,false,Transpose<const Lhs>,true> TriangularProductTranspose;
|
typedef TriangularProduct<(Mode & UnitDiag) | ((Mode & Lower) ? Upper : Lower),true,Transpose<const Rhs>,false,Transpose<const Lhs>,true> TriangularProductTranspose;
|
||||||
Transpose<Dest> dstT(dst);
|
Transpose<Dest> dstT(dst);
|
||||||
internal::trmv_selector<(int(internal::traits<Rhs>::Flags)&RowMajorBit) ? ColMajor : RowMajor>::run(
|
internal::trmv_selector<(int(internal::traits<Rhs>::Flags)&RowMajorBit) ? ColMajor : RowMajor>::run(
|
||||||
@@ -235,23 +229,15 @@ template<> struct trmv_selector<ColMajor>
|
|||||||
|
|
||||||
RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
|
RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
|
||||||
|
|
||||||
ResScalar* actualDestPtr;
|
ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(),
|
||||||
bool freeDestPtr = false;
|
evalToDest ? dest.data() : static_dest.data());
|
||||||
if (evalToDest)
|
|
||||||
{
|
if(!evalToDest)
|
||||||
actualDestPtr = dest.data();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||||
int size = dest.size();
|
int size = dest.size();
|
||||||
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||||
#endif
|
#endif
|
||||||
if((actualDestPtr = static_dest.data())==0)
|
|
||||||
{
|
|
||||||
freeDestPtr = true;
|
|
||||||
actualDestPtr = ei_aligned_stack_new(ResScalar,dest.size());
|
|
||||||
}
|
|
||||||
if(!alphaIsCompatible)
|
if(!alphaIsCompatible)
|
||||||
{
|
{
|
||||||
MappedDest(actualDestPtr, dest.size()).setZero();
|
MappedDest(actualDestPtr, dest.size()).setZero();
|
||||||
@@ -277,7 +263,6 @@ template<> struct trmv_selector<ColMajor>
|
|||||||
dest += actualAlpha * MappedDest(actualDestPtr, dest.size());
|
dest += actualAlpha * MappedDest(actualDestPtr, dest.size());
|
||||||
else
|
else
|
||||||
dest = MappedDest(actualDestPtr, dest.size());
|
dest = MappedDest(actualDestPtr, dest.size());
|
||||||
if(freeDestPtr) ei_aligned_stack_delete(ResScalar, actualDestPtr, dest.size());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -310,23 +295,15 @@ template<> struct trmv_selector<RowMajor>
|
|||||||
|
|
||||||
gemv_static_vector_if<RhsScalar,_ActualRhsType::SizeAtCompileTime,_ActualRhsType::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs;
|
gemv_static_vector_if<RhsScalar,_ActualRhsType::SizeAtCompileTime,_ActualRhsType::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs;
|
||||||
|
|
||||||
RhsScalar* actualRhsPtr;
|
ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(),
|
||||||
bool freeRhsPtr = false;
|
DirectlyUseRhs ? const_cast<RhsScalar*>(actualRhs.data()) : static_rhs.data());
|
||||||
if (DirectlyUseRhs)
|
|
||||||
{
|
if(!DirectlyUseRhs)
|
||||||
actualRhsPtr = const_cast<RhsScalar*>(actualRhs.data());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||||
int size = actualRhs.size();
|
int size = actualRhs.size();
|
||||||
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||||
#endif
|
#endif
|
||||||
if((actualRhsPtr = static_rhs.data())==0)
|
|
||||||
{
|
|
||||||
freeRhsPtr = true;
|
|
||||||
actualRhsPtr = ei_aligned_stack_new(RhsScalar, actualRhs.size());
|
|
||||||
}
|
|
||||||
Map<typename _ActualRhsType::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs;
|
Map<typename _ActualRhsType::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,8 +317,6 @@ template<> struct trmv_selector<RowMajor>
|
|||||||
actualRhsPtr,1,
|
actualRhsPtr,1,
|
||||||
dest.data(),dest.innerStride(),
|
dest.data(),dest.innerStride(),
|
||||||
actualAlpha);
|
actualAlpha);
|
||||||
|
|
||||||
if((!DirectlyUseRhs) && freeRhsPtr) ei_aligned_stack_delete(RhsScalar, actualRhsPtr, prod.rhs().size());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -70,10 +70,10 @@ struct triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conjugate,TriStorageO
|
|||||||
Index nc = cols; // cache block size along the N direction
|
Index nc = cols; // cache block size along the N direction
|
||||||
computeProductBlockingSizes<Scalar,Scalar,4>(kc, mc, nc);
|
computeProductBlockingSizes<Scalar,Scalar,4>(kc, mc, nc);
|
||||||
|
|
||||||
Scalar* blockA = ei_aligned_stack_new(Scalar, kc*mc);
|
|
||||||
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
|
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
|
||||||
std::size_t sizeB = sizeW + kc*cols;
|
std::size_t sizeB = sizeW + kc*cols;
|
||||||
Scalar* allocatedBlockB = ei_aligned_stack_new(Scalar, sizeB);
|
ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0);
|
||||||
|
ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0);
|
||||||
Scalar* blockB = allocatedBlockB + sizeW;
|
Scalar* blockB = allocatedBlockB + sizeW;
|
||||||
|
|
||||||
conj_if<Conjugate> conj;
|
conj_if<Conjugate> conj;
|
||||||
@@ -85,7 +85,7 @@ struct triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conjugate,TriStorageO
|
|||||||
IsLower ? k2<size : k2>0;
|
IsLower ? k2<size : k2>0;
|
||||||
IsLower ? k2+=kc : k2-=kc)
|
IsLower ? k2+=kc : k2-=kc)
|
||||||
{
|
{
|
||||||
const Index actual_kc = std::min(IsLower ? size-k2 : k2, kc);
|
const Index actual_kc = (std::min)(IsLower ? size-k2 : k2, kc);
|
||||||
|
|
||||||
// We have selected and packed a big horizontal panel R1 of rhs. Let B be the packed copy of this panel,
|
// We have selected and packed a big horizontal panel R1 of rhs. Let B be the packed copy of this panel,
|
||||||
// and R2 the remaining part of rhs. The corresponding vertical panel of lhs is split into
|
// and R2 the remaining part of rhs. The corresponding vertical panel of lhs is split into
|
||||||
@@ -164,7 +164,7 @@ struct triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conjugate,TriStorageO
|
|||||||
Index end = IsLower ? size : k2-kc;
|
Index end = IsLower ? size : k2-kc;
|
||||||
for(Index i2=start; i2<end; i2+=mc)
|
for(Index i2=start; i2<end; i2+=mc)
|
||||||
{
|
{
|
||||||
const Index actual_mc = std::min(mc,end-i2);
|
const Index actual_mc = (std::min)(mc,end-i2);
|
||||||
if (actual_mc>0)
|
if (actual_mc>0)
|
||||||
{
|
{
|
||||||
pack_lhs(blockA, &tri(i2, IsLower ? k2 : k2-kc), triStride, actual_kc, actual_mc);
|
pack_lhs(blockA, &tri(i2, IsLower ? k2 : k2-kc), triStride, actual_kc, actual_mc);
|
||||||
@@ -174,9 +174,6 @@ struct triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conjugate,TriStorageO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ei_aligned_stack_delete(Scalar, blockA, kc*mc);
|
|
||||||
ei_aligned_stack_delete(Scalar, allocatedBlockB, sizeB);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -209,10 +206,10 @@ struct triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conjugate,TriStorage
|
|||||||
Index nc = rows; // cache block size along the N direction
|
Index nc = rows; // cache block size along the N direction
|
||||||
computeProductBlockingSizes<Scalar,Scalar,4>(kc, mc, nc);
|
computeProductBlockingSizes<Scalar,Scalar,4>(kc, mc, nc);
|
||||||
|
|
||||||
Scalar* blockA = ei_aligned_stack_new(Scalar, kc*mc);
|
|
||||||
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
|
std::size_t sizeW = kc*Traits::WorkSpaceFactor;
|
||||||
std::size_t sizeB = sizeW + kc*size;
|
std::size_t sizeB = sizeW + kc*size;
|
||||||
Scalar* allocatedBlockB = ei_aligned_stack_new(Scalar, sizeB);
|
ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0);
|
||||||
|
ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0);
|
||||||
Scalar* blockB = allocatedBlockB + sizeW;
|
Scalar* blockB = allocatedBlockB + sizeW;
|
||||||
|
|
||||||
conj_if<Conjugate> conj;
|
conj_if<Conjugate> conj;
|
||||||
@@ -225,7 +222,7 @@ struct triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conjugate,TriStorage
|
|||||||
IsLower ? k2>0 : k2<size;
|
IsLower ? k2>0 : k2<size;
|
||||||
IsLower ? k2-=kc : k2+=kc)
|
IsLower ? k2-=kc : k2+=kc)
|
||||||
{
|
{
|
||||||
const Index actual_kc = std::min(IsLower ? k2 : size-k2, kc);
|
const Index actual_kc = (std::min)(IsLower ? k2 : size-k2, kc);
|
||||||
Index actual_k2 = IsLower ? k2-actual_kc : k2 ;
|
Index actual_k2 = IsLower ? k2-actual_kc : k2 ;
|
||||||
|
|
||||||
Index startPanel = IsLower ? 0 : k2+actual_kc;
|
Index startPanel = IsLower ? 0 : k2+actual_kc;
|
||||||
@@ -254,7 +251,7 @@ struct triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conjugate,TriStorage
|
|||||||
|
|
||||||
for(Index i2=0; i2<rows; i2+=mc)
|
for(Index i2=0; i2<rows; i2+=mc)
|
||||||
{
|
{
|
||||||
const Index actual_mc = std::min(mc,rows-i2);
|
const Index actual_mc = (std::min)(mc,rows-i2);
|
||||||
|
|
||||||
// triangular solver kernel
|
// triangular solver kernel
|
||||||
{
|
{
|
||||||
@@ -314,9 +311,6 @@ struct triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conjugate,TriStorage
|
|||||||
-1, -1, 0, 0, allocatedBlockB);
|
-1, -1, 0, 0, allocatedBlockB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ei_aligned_stack_delete(Scalar, blockA, kc*mc);
|
|
||||||
ei_aligned_stack_delete(Scalar, allocatedBlockB, sizeB);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ struct triangular_solve_vector<LhsScalar, RhsScalar, Index, OnTheLeft, Mode, Con
|
|||||||
IsLower ? pi<size : pi>0;
|
IsLower ? pi<size : pi>0;
|
||||||
IsLower ? pi+=PanelWidth : pi-=PanelWidth)
|
IsLower ? pi+=PanelWidth : pi-=PanelWidth)
|
||||||
{
|
{
|
||||||
Index actualPanelWidth = std::min(IsLower ? size - pi : pi, PanelWidth);
|
Index actualPanelWidth = (std::min)(IsLower ? size - pi : pi, PanelWidth);
|
||||||
|
|
||||||
Index r = IsLower ? pi : size - pi; // remaining size
|
Index r = IsLower ? pi : size - pi; // remaining size
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
@@ -114,7 +114,7 @@ struct triangular_solve_vector<LhsScalar, RhsScalar, Index, OnTheLeft, Mode, Con
|
|||||||
IsLower ? pi<size : pi>0;
|
IsLower ? pi<size : pi>0;
|
||||||
IsLower ? pi+=PanelWidth : pi-=PanelWidth)
|
IsLower ? pi+=PanelWidth : pi-=PanelWidth)
|
||||||
{
|
{
|
||||||
Index actualPanelWidth = std::min(IsLower ? size - pi : pi, PanelWidth);
|
Index actualPanelWidth = (std::min)(IsLower ? size - pi : pi, PanelWidth);
|
||||||
Index startBlock = IsLower ? pi : pi-actualPanelWidth;
|
Index startBlock = IsLower ? pi : pi-actualPanelWidth;
|
||||||
Index endBlock = IsLower ? pi + actualPanelWidth : 0;
|
Index endBlock = IsLower ? pi + actualPanelWidth : 0;
|
||||||
|
|
||||||
|
|||||||
@@ -161,23 +161,72 @@ const unsigned int HereditaryBits = RowMajorBit
|
|||||||
| EvalBeforeNestingBit
|
| EvalBeforeNestingBit
|
||||||
| EvalBeforeAssigningBit;
|
| EvalBeforeAssigningBit;
|
||||||
|
|
||||||
// Possible values for the Mode parameter of triangularView()
|
/** \defgroup enums Enumerations
|
||||||
enum {
|
* \ingroup Core_Module
|
||||||
Lower=0x1, Upper=0x2, UnitDiag=0x4, ZeroDiag=0x8,
|
*
|
||||||
UnitLower=UnitDiag|Lower, UnitUpper=UnitDiag|Upper,
|
* Various enumerations used in %Eigen. Many of these are used as template parameters.
|
||||||
StrictlyLower=ZeroDiag|Lower, StrictlyUpper=ZeroDiag|Upper,
|
*/
|
||||||
SelfAdjoint=0x10};
|
|
||||||
|
/** \ingroup enums
|
||||||
|
* Enum containing possible values for the \p Mode parameter of
|
||||||
|
* MatrixBase::selfadjointView() and MatrixBase::triangularView(). */
|
||||||
|
enum {
|
||||||
|
/** View matrix as a lower triangular matrix. */
|
||||||
|
Lower=0x1,
|
||||||
|
/** View matrix as an upper triangular matrix. */
|
||||||
|
Upper=0x2,
|
||||||
|
/** %Matrix has ones on the diagonal; to be used in combination with #Lower or #Upper. */
|
||||||
|
UnitDiag=0x4,
|
||||||
|
/** %Matrix has zeros on the diagonal; to be used in combination with #Lower or #Upper. */
|
||||||
|
ZeroDiag=0x8,
|
||||||
|
/** View matrix as a lower triangular matrix with ones on the diagonal. */
|
||||||
|
UnitLower=UnitDiag|Lower,
|
||||||
|
/** View matrix as an upper triangular matrix with ones on the diagonal. */
|
||||||
|
UnitUpper=UnitDiag|Upper,
|
||||||
|
/** View matrix as a lower triangular matrix with zeros on the diagonal. */
|
||||||
|
StrictlyLower=ZeroDiag|Lower,
|
||||||
|
/** View matrix as an upper triangular matrix with zeros on the diagonal. */
|
||||||
|
StrictlyUpper=ZeroDiag|Upper,
|
||||||
|
/** Used in BandMatrix and SelfAdjointView to indicate that the matrix is self-adjoint. */
|
||||||
|
SelfAdjoint=0x10
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \ingroup enums
|
||||||
|
* Enum for indicating whether an object is aligned or not. */
|
||||||
|
enum {
|
||||||
|
/** Object is not correctly aligned for vectorization. */
|
||||||
|
Unaligned=0,
|
||||||
|
/** Object is aligned for vectorization. */
|
||||||
|
Aligned=1
|
||||||
|
};
|
||||||
|
|
||||||
enum { Unaligned=0, Aligned=1 };
|
|
||||||
enum { ConditionalJumpCost = 5 };
|
enum { ConditionalJumpCost = 5 };
|
||||||
|
|
||||||
|
/** \ingroup enums
|
||||||
|
* Enum used by DenseBase::corner() in Eigen2 compatibility mode. */
|
||||||
// FIXME after the corner() API change, this was not needed anymore, except by AlignedBox
|
// FIXME after the corner() API change, this was not needed anymore, except by AlignedBox
|
||||||
// TODO: find out what to do with that. Adapt the AlignedBox API ?
|
// TODO: find out what to do with that. Adapt the AlignedBox API ?
|
||||||
enum CornerType { TopLeft, TopRight, BottomLeft, BottomRight };
|
enum CornerType { TopLeft, TopRight, BottomLeft, BottomRight };
|
||||||
|
|
||||||
enum DirectionType { Vertical, Horizontal, BothDirections };
|
/** \ingroup enums
|
||||||
|
* Enum containing possible values for the \p Direction parameter of
|
||||||
|
* Reverse, PartialReduxExpr and VectorwiseOp. */
|
||||||
|
enum DirectionType {
|
||||||
|
/** For Reverse, all columns are reversed;
|
||||||
|
* for PartialReduxExpr and VectorwiseOp, act on columns. */
|
||||||
|
Vertical,
|
||||||
|
/** For Reverse, all rows are reversed;
|
||||||
|
* for PartialReduxExpr and VectorwiseOp, act on rows. */
|
||||||
|
Horizontal,
|
||||||
|
/** For Reverse, both rows and columns are reversed;
|
||||||
|
* not used for PartialReduxExpr and VectorwiseOp. */
|
||||||
|
BothDirections
|
||||||
|
};
|
||||||
|
|
||||||
enum ProductEvaluationMode { NormalProduct, CacheFriendlyProduct };
|
enum ProductEvaluationMode { NormalProduct, CacheFriendlyProduct };
|
||||||
|
|
||||||
|
/** \internal \ingroup enums
|
||||||
|
* Enum to specify how to traverse the entries of a matrix. */
|
||||||
enum {
|
enum {
|
||||||
/** \internal Default traversal, no vectorization, no index-based access */
|
/** \internal Default traversal, no vectorization, no index-based access */
|
||||||
DefaultTraversal,
|
DefaultTraversal,
|
||||||
@@ -196,14 +245,25 @@ enum {
|
|||||||
InvalidTraversal
|
InvalidTraversal
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** \internal \ingroup enums
|
||||||
|
* Enum to specify whether to unroll loops when traversing over the entries of a matrix. */
|
||||||
enum {
|
enum {
|
||||||
|
/** \internal Do not unroll loops. */
|
||||||
NoUnrolling,
|
NoUnrolling,
|
||||||
|
/** \internal Unroll only the inner loop, but not the outer loop. */
|
||||||
InnerUnrolling,
|
InnerUnrolling,
|
||||||
|
/** \internal Unroll both the inner and the outer loop. If there is only one loop,
|
||||||
|
* because linear traversal is used, then unroll that loop. */
|
||||||
CompleteUnrolling
|
CompleteUnrolling
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** \ingroup enums
|
||||||
|
* Enum containing possible values for the \p _Options template parameter of
|
||||||
|
* Matrix, Array and BandMatrix. */
|
||||||
enum {
|
enum {
|
||||||
|
/** Storage order is column major (see \ref TopicStorageOrders). */
|
||||||
ColMajor = 0,
|
ColMajor = 0,
|
||||||
|
/** Storage order is row major (see \ref TopicStorageOrders). */
|
||||||
RowMajor = 0x1, // it is only a coincidence that this is equal to RowMajorBit -- don't rely on that
|
RowMajor = 0x1, // it is only a coincidence that this is equal to RowMajorBit -- don't rely on that
|
||||||
/** \internal Align the matrix itself if it is vectorizable fixed-size */
|
/** \internal Align the matrix itself if it is vectorizable fixed-size */
|
||||||
AutoAlign = 0,
|
AutoAlign = 0,
|
||||||
@@ -211,11 +271,13 @@ enum {
|
|||||||
DontAlign = 0x2
|
DontAlign = 0x2
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \brief Enum for specifying whether to apply or solve on the left or right.
|
/** \ingroup enums
|
||||||
*/
|
* Enum for specifying whether to apply or solve on the left or right. */
|
||||||
enum {
|
enum {
|
||||||
OnTheLeft = 1, /**< \brief Apply transformation on the left. */
|
/** Apply transformation on the left. */
|
||||||
OnTheRight = 2 /**< \brief Apply transformation on the right. */
|
OnTheLeft = 1,
|
||||||
|
/** Apply transformation on the right. */
|
||||||
|
OnTheRight = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
/* the following could as well be written:
|
/* the following could as well be written:
|
||||||
@@ -239,53 +301,108 @@ namespace {
|
|||||||
EIGEN_UNUSED Default_t Default;
|
EIGEN_UNUSED Default_t Default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \internal \ingroup enums
|
||||||
|
* Used in AmbiVector. */
|
||||||
enum {
|
enum {
|
||||||
IsDense = 0,
|
IsDense = 0,
|
||||||
IsSparse
|
IsSparse
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** \ingroup enums
|
||||||
|
* Used as template parameter in DenseCoeffBase and MapBase to indicate
|
||||||
|
* which accessors should be provided. */
|
||||||
enum AccessorLevels {
|
enum AccessorLevels {
|
||||||
ReadOnlyAccessors, WriteAccessors, DirectAccessors, DirectWriteAccessors
|
/** Read-only access via a member function. */
|
||||||
|
ReadOnlyAccessors,
|
||||||
|
/** Read/write access via member functions. */
|
||||||
|
WriteAccessors,
|
||||||
|
/** Direct read-only access to the coefficients. */
|
||||||
|
DirectAccessors,
|
||||||
|
/** Direct read/write access to the coefficients. */
|
||||||
|
DirectWriteAccessors
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** \ingroup enums
|
||||||
|
* Enum with options to give to various decompositions. */
|
||||||
enum DecompositionOptions {
|
enum DecompositionOptions {
|
||||||
Pivoting = 0x01, // LDLT,
|
/** \internal Not used (meant for LDLT?). */
|
||||||
NoPivoting = 0x02, // LDLT,
|
Pivoting = 0x01,
|
||||||
ComputeFullU = 0x04, // SVD,
|
/** \internal Not used (meant for LDLT?). */
|
||||||
ComputeThinU = 0x08, // SVD,
|
NoPivoting = 0x02,
|
||||||
ComputeFullV = 0x10, // SVD,
|
/** Used in JacobiSVD to indicate that the square matrix U is to be computed. */
|
||||||
ComputeThinV = 0x20, // SVD,
|
ComputeFullU = 0x04,
|
||||||
EigenvaluesOnly = 0x40, // all eigen solvers
|
/** Used in JacobiSVD to indicate that the thin matrix U is to be computed. */
|
||||||
ComputeEigenvectors = 0x80, // all eigen solvers
|
ComputeThinU = 0x08,
|
||||||
|
/** Used in JacobiSVD to indicate that the square matrix V is to be computed. */
|
||||||
|
ComputeFullV = 0x10,
|
||||||
|
/** Used in JacobiSVD to indicate that the thin matrix V is to be computed. */
|
||||||
|
ComputeThinV = 0x20,
|
||||||
|
/** Used in SelfAdjointEigenSolver and GeneralizedSelfAdjointEigenSolver to specify
|
||||||
|
* that only the eigenvalues are to be computed and not the eigenvectors. */
|
||||||
|
EigenvaluesOnly = 0x40,
|
||||||
|
/** Used in SelfAdjointEigenSolver and GeneralizedSelfAdjointEigenSolver to specify
|
||||||
|
* that both the eigenvalues and the eigenvectors are to be computed. */
|
||||||
|
ComputeEigenvectors = 0x80,
|
||||||
|
/** \internal */
|
||||||
EigVecMask = EigenvaluesOnly | ComputeEigenvectors,
|
EigVecMask = EigenvaluesOnly | ComputeEigenvectors,
|
||||||
|
/** Used in GeneralizedSelfAdjointEigenSolver to indicate that it should
|
||||||
|
* solve the generalized eigenproblem \f$ Ax = \lambda B x \f$. */
|
||||||
Ax_lBx = 0x100,
|
Ax_lBx = 0x100,
|
||||||
|
/** Used in GeneralizedSelfAdjointEigenSolver to indicate that it should
|
||||||
|
* solve the generalized eigenproblem \f$ ABx = \lambda x \f$. */
|
||||||
ABx_lx = 0x200,
|
ABx_lx = 0x200,
|
||||||
|
/** Used in GeneralizedSelfAdjointEigenSolver to indicate that it should
|
||||||
|
* solve the generalized eigenproblem \f$ BAx = \lambda x \f$. */
|
||||||
BAx_lx = 0x400,
|
BAx_lx = 0x400,
|
||||||
|
/** \internal */
|
||||||
GenEigMask = Ax_lBx | ABx_lx | BAx_lx
|
GenEigMask = Ax_lBx | ABx_lx | BAx_lx
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** \ingroup enums
|
||||||
|
* Possible values for the \p QRPreconditioner template parameter of JacobiSVD. */
|
||||||
enum QRPreconditioners {
|
enum QRPreconditioners {
|
||||||
|
/** Do not specify what is to be done if the SVD of a non-square matrix is asked for. */
|
||||||
NoQRPreconditioner,
|
NoQRPreconditioner,
|
||||||
|
/** Use a QR decomposition without pivoting as the first step. */
|
||||||
HouseholderQRPreconditioner,
|
HouseholderQRPreconditioner,
|
||||||
|
/** Use a QR decomposition with column pivoting as the first step. */
|
||||||
ColPivHouseholderQRPreconditioner,
|
ColPivHouseholderQRPreconditioner,
|
||||||
|
/** Use a QR decomposition with full pivoting as the first step. */
|
||||||
FullPivHouseholderQRPreconditioner
|
FullPivHouseholderQRPreconditioner
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \brief Enum for reporting the status of a computation.
|
#ifdef Success
|
||||||
*/
|
#error The preprocessor symbol 'Success' is defined, possibly by the X11 header file X.h
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \ingroups enums
|
||||||
|
* Enum for reporting the status of a computation. */
|
||||||
enum ComputationInfo {
|
enum ComputationInfo {
|
||||||
Success = 0, /**< \brief Computation was successful. */
|
/** Computation was successful. */
|
||||||
NumericalIssue = 1, /**< \brief The provided data did not satisfy the prerequisites. */
|
Success = 0,
|
||||||
NoConvergence = 2 /**< \brief Iterative procedure did not converge. */
|
/** The provided data did not satisfy the prerequisites. */
|
||||||
|
NumericalIssue = 1,
|
||||||
|
/** Iterative procedure did not converge. */
|
||||||
|
NoConvergence = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** \ingroup enums
|
||||||
|
* Enum used to specify how a particular transformation is stored in a matrix.
|
||||||
|
* \sa Transform, Hyperplane::transform(). */
|
||||||
enum TransformTraits {
|
enum TransformTraits {
|
||||||
|
/** Transformation is an isometry. */
|
||||||
Isometry = 0x1,
|
Isometry = 0x1,
|
||||||
|
/** Transformation is an affine transformation stored as a (Dim+1)^2 matrix whose last row is
|
||||||
|
* assumed to be [0 ... 0 1]. */
|
||||||
Affine = 0x2,
|
Affine = 0x2,
|
||||||
|
/** Transformation is an affine transformation stored as a (Dim) x (Dim+1) matrix. */
|
||||||
AffineCompact = 0x10 | Affine,
|
AffineCompact = 0x10 | Affine,
|
||||||
|
/** Transformation is a general projective transformation stored as a (Dim+1)^2 matrix. */
|
||||||
Projective = 0x20
|
Projective = 0x20
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** \internal \ingroup enums
|
||||||
|
* Enum used to choose between implementation depending on the computer architecture. */
|
||||||
namespace Architecture
|
namespace Architecture
|
||||||
{
|
{
|
||||||
enum Type {
|
enum Type {
|
||||||
@@ -302,8 +419,12 @@ namespace Architecture
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \internal \ingroup enums
|
||||||
|
* Enum used as template parameter in GeneralProduct. */
|
||||||
enum { CoeffBasedProductMode, LazyCoeffBasedProductMode, OuterProduct, InnerProduct, GemvProduct, GemmProduct };
|
enum { CoeffBasedProductMode, LazyCoeffBasedProductMode, OuterProduct, InnerProduct, GemvProduct, GemmProduct };
|
||||||
|
|
||||||
|
/** \internal \ingroup enums
|
||||||
|
* Enum used in experimental parallel implementation. */
|
||||||
enum Action {GetAction, SetAction};
|
enum Action {GetAction, SetAction};
|
||||||
|
|
||||||
/** The type used to identify a dense storage. */
|
/** The type used to identify a dense storage. */
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
// 4100 - unreferenced formal parameter (occurred e.g. in aligned_allocator::destroy(pointer p))
|
|
||||||
// 4101 - unreferenced local variable
|
|
||||||
// 4127 - conditional expression is constant
|
|
||||||
// 4181 - qualifier applied to reference type ignored
|
|
||||||
// 4211 - nonstandard extension used : redefined extern to static
|
|
||||||
// 4244 - 'argument' : conversion from 'type1' to 'type2', possible loss of data
|
|
||||||
// 4273 - QtAlignedMalloc, inconsistent DLL linkage
|
|
||||||
// 4324 - structure was padded due to declspec(align())
|
|
||||||
// 4512 - assignment operator could not be generated
|
|
||||||
// 4522 - 'class' : multiple assignment operators specified
|
|
||||||
// 4700 - uninitialized local variable 'xyz' used
|
|
||||||
// 4717 - 'function' : recursive on all control paths, function will cause runtime stack overflow
|
|
||||||
#pragma warning( push )
|
|
||||||
#pragma warning( disable : 4100 4101 4127 4181 4211 4244 4273 4324 4512 4522 4700 4717 )
|
|
||||||
#endif
|
|
||||||
42
Eigen/src/Core/util/DisableStupidWarnings.h
Normal file
42
Eigen/src/Core/util/DisableStupidWarnings.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#ifndef EIGEN_WARNINGS_DISABLED
|
||||||
|
#define EIGEN_WARNINGS_DISABLED
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// 4100 - unreferenced formal parameter (occurred e.g. in aligned_allocator::destroy(pointer p))
|
||||||
|
// 4101 - unreferenced local variable
|
||||||
|
// 4127 - conditional expression is constant
|
||||||
|
// 4181 - qualifier applied to reference type ignored
|
||||||
|
// 4211 - nonstandard extension used : redefined extern to static
|
||||||
|
// 4244 - 'argument' : conversion from 'type1' to 'type2', possible loss of data
|
||||||
|
// 4273 - QtAlignedMalloc, inconsistent DLL linkage
|
||||||
|
// 4324 - structure was padded due to declspec(align())
|
||||||
|
// 4512 - assignment operator could not be generated
|
||||||
|
// 4522 - 'class' : multiple assignment operators specified
|
||||||
|
// 4700 - uninitialized local variable 'xyz' used
|
||||||
|
// 4717 - 'function' : recursive on all control paths, function will cause runtime stack overflow
|
||||||
|
#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
|
||||||
|
#pragma warning( push )
|
||||||
|
#endif
|
||||||
|
#pragma warning( disable : 4100 4101 4127 4181 4211 4244 4273 4324 4512 4522 4700 4717 )
|
||||||
|
#elif defined __INTEL_COMPILER
|
||||||
|
// 2196 - routine is both "inline" and "noinline" ("noinline" assumed)
|
||||||
|
// ICC 12 generates this warning even without any inline keyword, when defining class methods 'inline' i.e. inside of class body
|
||||||
|
// 2536 - type qualifiers are meaningless here
|
||||||
|
// ICC 12 generates this warning when a function return type is const qualified, even if that type is a template-parameter-dependent
|
||||||
|
// typedef that may be a reference type.
|
||||||
|
// 279 - controlling expression is constant
|
||||||
|
// ICC 12 generates this warning on assert(constant_expression_depending_on_template_params) and frankly this is a legitimate use case.
|
||||||
|
#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
|
||||||
|
#pragma warning push
|
||||||
|
#endif
|
||||||
|
#pragma warning disable 2196 2536 279
|
||||||
|
#elif defined __clang__
|
||||||
|
// -Wconstant-logical-operand - warning: use of logical && with constant operand; switch to bitwise & or remove constant
|
||||||
|
// this is really a stupid warning as it warns on compile-time expressions involving enums
|
||||||
|
#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#endif
|
||||||
|
#pragma clang diagnostic ignored "-Wconstant-logical-operand"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // not EIGEN_WARNINGS_DISABLED
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning( pop )
|
|
||||||
#endif
|
|
||||||
@@ -179,6 +179,9 @@ template<typename Scalar> struct scalar_exp_op;
|
|||||||
template<typename Scalar> struct scalar_log_op;
|
template<typename Scalar> struct scalar_log_op;
|
||||||
template<typename Scalar> struct scalar_cos_op;
|
template<typename Scalar> struct scalar_cos_op;
|
||||||
template<typename Scalar> struct scalar_sin_op;
|
template<typename Scalar> struct scalar_sin_op;
|
||||||
|
template<typename Scalar> struct scalar_acos_op;
|
||||||
|
template<typename Scalar> struct scalar_asin_op;
|
||||||
|
template<typename Scalar> struct scalar_tan_op;
|
||||||
template<typename Scalar> struct scalar_pow_op;
|
template<typename Scalar> struct scalar_pow_op;
|
||||||
template<typename Scalar> struct scalar_inverse_op;
|
template<typename Scalar> struct scalar_inverse_op;
|
||||||
template<typename Scalar> struct scalar_square_op;
|
template<typename Scalar> struct scalar_square_op;
|
||||||
|
|||||||
@@ -26,18 +26,31 @@
|
|||||||
#ifndef EIGEN_MACROS_H
|
#ifndef EIGEN_MACROS_H
|
||||||
#define EIGEN_MACROS_H
|
#define EIGEN_MACROS_H
|
||||||
|
|
||||||
#define EIGEN_WORLD_VERSION 2
|
#define EIGEN_WORLD_VERSION 3
|
||||||
#define EIGEN_MAJOR_VERSION 93
|
#define EIGEN_MAJOR_VERSION 0
|
||||||
#define EIGEN_MINOR_VERSION 0
|
#define EIGEN_MINOR_VERSION 2
|
||||||
|
|
||||||
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
|
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
|
||||||
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
|
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
|
||||||
EIGEN_MINOR_VERSION>=z))))
|
EIGEN_MINOR_VERSION>=z))))
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__>=x && __GNUC_MINOR__>=y) || __GNUC__>x)
|
#define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__==x && __GNUC_MINOR__>=y) || __GNUC__>x)
|
||||||
#else
|
#else
|
||||||
#define EIGEN_GNUC_AT_LEAST(x,y) 0
|
#define EIGEN_GNUC_AT_LEAST(x,y) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define EIGEN_GNUC_AT_MOST(x,y) ((__GNUC__==x && __GNUC_MINOR__<=y) || __GNUC__<x)
|
||||||
|
#else
|
||||||
|
#define EIGEN_GNUC_AT_MOST(x,y) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if EIGEN_GNUC_AT_MOST(4,3)
|
||||||
|
// see bug 89
|
||||||
|
#define EIGEN_SAFE_TO_USE_STANDARD_ASSERT_MACRO 0
|
||||||
|
#else
|
||||||
|
#define EIGEN_SAFE_TO_USE_STANDARD_ASSERT_MACRO 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__GNUC__) && (__GNUC__ <= 3)
|
#if defined(__GNUC__) && (__GNUC__ <= 3)
|
||||||
#define EIGEN_GCC3_OR_OLDER 1
|
#define EIGEN_GCC3_OR_OLDER 1
|
||||||
@@ -109,31 +122,13 @@
|
|||||||
|
|
||||||
#define EIGEN_DEBUG_VAR(x) std::cerr << #x << " = " << x << std::endl;
|
#define EIGEN_DEBUG_VAR(x) std::cerr << #x << " = " << x << std::endl;
|
||||||
|
|
||||||
#ifdef NDEBUG
|
// concatenate two tokens
|
||||||
# ifndef EIGEN_NO_DEBUG
|
#define EIGEN_CAT2(a,b) a ## b
|
||||||
# define EIGEN_NO_DEBUG
|
#define EIGEN_CAT(a,b) EIGEN_CAT2(a,b)
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef eigen_assert
|
// convert a token to a string
|
||||||
#ifdef EIGEN_NO_DEBUG
|
#define EIGEN_MAKESTRING2(a) #a
|
||||||
#define eigen_assert(x)
|
#define EIGEN_MAKESTRING(a) EIGEN_MAKESTRING2(a)
|
||||||
#else
|
|
||||||
#define eigen_assert(x) assert(x)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EIGEN_INTERNAL_DEBUGGING
|
|
||||||
#define eigen_internal_assert(x) eigen_assert(x)
|
|
||||||
#else
|
|
||||||
#define eigen_internal_assert(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EIGEN_NO_DEBUG
|
|
||||||
#define EIGEN_ONLY_USED_FOR_DEBUG(x) (void)x
|
|
||||||
#else
|
|
||||||
#define EIGEN_ONLY_USED_FOR_DEBUG(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// EIGEN_ALWAYS_INLINE_ATTRIB should be use in the declaration of function
|
// EIGEN_ALWAYS_INLINE_ATTRIB should be use in the declaration of function
|
||||||
// which should be inlined even in debug mode.
|
// which should be inlined even in debug mode.
|
||||||
@@ -147,14 +142,14 @@
|
|||||||
#define EIGEN_ALWAYS_INLINE_ATTRIB
|
#define EIGEN_ALWAYS_INLINE_ATTRIB
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if EIGEN_GNUC_AT_LEAST(4,1)
|
#if EIGEN_GNUC_AT_LEAST(4,1) && !defined(__clang__) && !defined(__INTEL_COMPILER)
|
||||||
#define EIGEN_FLATTEN_ATTRIB __attribute__((flatten))
|
#define EIGEN_FLATTEN_ATTRIB __attribute__((flatten))
|
||||||
#else
|
#else
|
||||||
#define EIGEN_FLATTEN_ATTRIB
|
#define EIGEN_FLATTEN_ATTRIB
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// EIGEN_FORCE_INLINE means "inline as much as possible"
|
// EIGEN_FORCE_INLINE means "inline as much as possible"
|
||||||
#if (defined _MSC_VER) || (defined __intel_compiler)
|
#if (defined _MSC_VER) || (defined __INTEL_COMPILER)
|
||||||
#define EIGEN_STRONG_INLINE __forceinline
|
#define EIGEN_STRONG_INLINE __forceinline
|
||||||
#else
|
#else
|
||||||
#define EIGEN_STRONG_INLINE inline
|
#define EIGEN_STRONG_INLINE inline
|
||||||
@@ -175,6 +170,67 @@
|
|||||||
#define EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
#define EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
#define EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS inline
|
#define EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS inline
|
||||||
|
|
||||||
|
#ifdef NDEBUG
|
||||||
|
# ifndef EIGEN_NO_DEBUG
|
||||||
|
# define EIGEN_NO_DEBUG
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// eigen_plain_assert is where we implement the workaround for the assert() bug in GCC <= 4.3, see bug 89
|
||||||
|
#ifdef EIGEN_NO_DEBUG
|
||||||
|
#define eigen_plain_assert(x)
|
||||||
|
#else
|
||||||
|
#if EIGEN_SAFE_TO_USE_STANDARD_ASSERT_MACRO
|
||||||
|
namespace Eigen {
|
||||||
|
namespace internal {
|
||||||
|
inline bool copy_bool(bool b) { return b; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#define eigen_plain_assert(x) assert(x)
|
||||||
|
#else
|
||||||
|
// work around bug 89
|
||||||
|
#include <cstdlib> // for abort
|
||||||
|
#include <iostream> // for std::cerr
|
||||||
|
|
||||||
|
namespace Eigen {
|
||||||
|
namespace internal {
|
||||||
|
// trivial function copying a bool. Must be EIGEN_DONT_INLINE, so we implement it after including Eigen headers.
|
||||||
|
// see bug 89.
|
||||||
|
namespace {
|
||||||
|
EIGEN_DONT_INLINE bool copy_bool(bool b) { return b; }
|
||||||
|
}
|
||||||
|
inline void assert_fail(const char *condition, const char *function, const char *file, int line)
|
||||||
|
{
|
||||||
|
std::cerr << "assertion failed: " << condition << " in function " << function << " at " << file << ":" << line << std::endl;
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#define eigen_plain_assert(x) \
|
||||||
|
do { \
|
||||||
|
if(!Eigen::internal::copy_bool(x)) \
|
||||||
|
Eigen::internal::assert_fail(EIGEN_MAKESTRING(x), __PRETTY_FUNCTION__, __FILE__, __LINE__); \
|
||||||
|
} while(false)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// eigen_assert can be overridden
|
||||||
|
#ifndef eigen_assert
|
||||||
|
#define eigen_assert(x) eigen_plain_assert(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EIGEN_INTERNAL_DEBUGGING
|
||||||
|
#define eigen_internal_assert(x) eigen_assert(x)
|
||||||
|
#else
|
||||||
|
#define eigen_internal_assert(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EIGEN_NO_DEBUG
|
||||||
|
#define EIGEN_ONLY_USED_FOR_DEBUG(x) (void)x
|
||||||
|
#else
|
||||||
|
#define EIGEN_ONLY_USED_FOR_DEBUG(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (defined __GNUC__)
|
#if (defined __GNUC__)
|
||||||
#define EIGEN_DEPRECATED __attribute__((deprecated))
|
#define EIGEN_DEPRECATED __attribute__((deprecated))
|
||||||
#elif (defined _MSC_VER)
|
#elif (defined _MSC_VER)
|
||||||
@@ -205,9 +261,7 @@
|
|||||||
* If we made alignment depend on whether or not EIGEN_VECTORIZE is defined, it would be impossible to link
|
* If we made alignment depend on whether or not EIGEN_VECTORIZE is defined, it would be impossible to link
|
||||||
* vectorized and non-vectorized code.
|
* vectorized and non-vectorized code.
|
||||||
*/
|
*/
|
||||||
#if !EIGEN_ALIGN_STATICALLY
|
#if (defined __GNUC__) || (defined __PGI) || (defined __IBMCPP__)
|
||||||
#define EIGEN_ALIGN_TO_BOUNDARY(n)
|
|
||||||
#elif (defined __GNUC__) || (defined __PGI) || (defined __IBMCPP__)
|
|
||||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n)))
|
#define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n)))
|
||||||
#elif (defined _MSC_VER)
|
#elif (defined _MSC_VER)
|
||||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __declspec(align(n))
|
#define EIGEN_ALIGN_TO_BOUNDARY(n) __declspec(align(n))
|
||||||
@@ -220,6 +274,14 @@
|
|||||||
|
|
||||||
#define EIGEN_ALIGN16 EIGEN_ALIGN_TO_BOUNDARY(16)
|
#define EIGEN_ALIGN16 EIGEN_ALIGN_TO_BOUNDARY(16)
|
||||||
|
|
||||||
|
#if EIGEN_ALIGN_STATICALLY
|
||||||
|
#define EIGEN_USER_ALIGN_TO_BOUNDARY(n) EIGEN_ALIGN_TO_BOUNDARY(n)
|
||||||
|
#define EIGEN_USER_ALIGN16 EIGEN_ALIGN16
|
||||||
|
#else
|
||||||
|
#define EIGEN_USER_ALIGN_TO_BOUNDARY(n)
|
||||||
|
#define EIGEN_USER_ALIGN16
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef EIGEN_DONT_USE_RESTRICT_KEYWORD
|
#ifdef EIGEN_DONT_USE_RESTRICT_KEYWORD
|
||||||
#define EIGEN_RESTRICT
|
#define EIGEN_RESTRICT
|
||||||
#endif
|
#endif
|
||||||
@@ -244,14 +306,6 @@
|
|||||||
// just an empty macro !
|
// just an empty macro !
|
||||||
#define EIGEN_EMPTY
|
#define EIGEN_EMPTY
|
||||||
|
|
||||||
// concatenate two tokens
|
|
||||||
#define EIGEN_CAT2(a,b) a ## b
|
|
||||||
#define EIGEN_CAT(a,b) EIGEN_CAT2(a,b)
|
|
||||||
|
|
||||||
// convert a token to a string
|
|
||||||
#define EIGEN_MAKESTRING2(a) #a
|
|
||||||
#define EIGEN_MAKESTRING(a) EIGEN_MAKESTRING2(a)
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && (!defined(__INTEL_COMPILER))
|
#if defined(_MSC_VER) && (!defined(__INTEL_COMPILER))
|
||||||
#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
|
#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
|
||||||
using Base::operator =;
|
using Base::operator =;
|
||||||
@@ -345,7 +399,7 @@
|
|||||||
#define EIGEN_MAKE_CWISE_BINARY_OP(METHOD,FUNCTOR) \
|
#define EIGEN_MAKE_CWISE_BINARY_OP(METHOD,FUNCTOR) \
|
||||||
template<typename OtherDerived> \
|
template<typename OtherDerived> \
|
||||||
EIGEN_STRONG_INLINE const CwiseBinaryOp<FUNCTOR<Scalar>, const Derived, const OtherDerived> \
|
EIGEN_STRONG_INLINE const CwiseBinaryOp<FUNCTOR<Scalar>, const Derived, const OtherDerived> \
|
||||||
METHOD(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const \
|
(METHOD)(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const \
|
||||||
{ \
|
{ \
|
||||||
return CwiseBinaryOp<FUNCTOR<Scalar>, const Derived, const OtherDerived>(derived(), other.derived()); \
|
return CwiseBinaryOp<FUNCTOR<Scalar>, const Derived, const OtherDerived>(derived(), other.derived()); \
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ inline void* generic_aligned_realloc(void* ptr, size_t size, size_t old_size)
|
|||||||
|
|
||||||
if (ptr != 0)
|
if (ptr != 0)
|
||||||
{
|
{
|
||||||
std::memcpy(newptr, ptr, std::min(size,old_size));
|
std::memcpy(newptr, ptr, (std::min)(size,old_size));
|
||||||
aligned_free(ptr);
|
aligned_free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,14 +167,36 @@ inline void* generic_aligned_realloc(void* ptr, size_t size, size_t old_size)
|
|||||||
*** Implementation of portable aligned versions of malloc/free/realloc ***
|
*** Implementation of portable aligned versions of malloc/free/realloc ***
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef EIGEN_NO_MALLOC
|
||||||
|
inline void check_that_malloc_is_allowed()
|
||||||
|
{
|
||||||
|
eigen_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)");
|
||||||
|
}
|
||||||
|
#elif defined EIGEN_RUNTIME_NO_MALLOC
|
||||||
|
inline bool is_malloc_allowed_impl(bool update, bool new_value = false)
|
||||||
|
{
|
||||||
|
static bool value = true;
|
||||||
|
if (update == 1)
|
||||||
|
value = new_value;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
inline bool is_malloc_allowed() { return is_malloc_allowed_impl(false); }
|
||||||
|
inline bool set_is_malloc_allowed(bool new_value) { return is_malloc_allowed_impl(true, new_value); }
|
||||||
|
inline void check_that_malloc_is_allowed()
|
||||||
|
{
|
||||||
|
eigen_assert(is_malloc_allowed() && "heap allocation is forbidden (EIGEN_RUNTIME_NO_MALLOC is defined and g_is_malloc_allowed is false)");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
inline void check_that_malloc_is_allowed()
|
||||||
|
{}
|
||||||
|
#endif
|
||||||
|
|
||||||
/** \internal Allocates \a size bytes. The returned pointer is guaranteed to have 16 bytes alignment.
|
/** \internal Allocates \a size bytes. The returned pointer is guaranteed to have 16 bytes alignment.
|
||||||
* On allocation error, the returned pointer is null, and if exceptions are enabled then a std::bad_alloc is thrown.
|
* On allocation error, the returned pointer is null, and if exceptions are enabled then a std::bad_alloc is thrown.
|
||||||
*/
|
*/
|
||||||
inline void* aligned_malloc(size_t size)
|
inline void* aligned_malloc(size_t size)
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_NO_MALLOC
|
check_that_malloc_is_allowed();
|
||||||
eigen_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *result;
|
void *result;
|
||||||
#if !EIGEN_ALIGN
|
#if !EIGEN_ALIGN
|
||||||
@@ -268,9 +290,7 @@ template<bool Align> inline void* conditional_aligned_malloc(size_t size)
|
|||||||
|
|
||||||
template<> inline void* conditional_aligned_malloc<false>(size_t size)
|
template<> inline void* conditional_aligned_malloc<false>(size_t size)
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_NO_MALLOC
|
check_that_malloc_is_allowed();
|
||||||
eigen_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *result = std::malloc(size);
|
void *result = std::malloc(size);
|
||||||
#ifdef EIGEN_EXCEPTIONS
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
@@ -448,36 +468,87 @@ inline static Index first_aligned(const Scalar* array, Index size)
|
|||||||
*** Implementation of runtime stack allocation (falling back to malloc) ***
|
*** Implementation of runtime stack allocation (falling back to malloc) ***
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/** \internal
|
// you can overwrite Eigen's default behavior regarding alloca by defining EIGEN_ALLOCA
|
||||||
* Allocates an aligned buffer of SIZE bytes on the stack if SIZE is smaller than
|
// to the appropriate stack allocation function
|
||||||
* EIGEN_STACK_ALLOCATION_LIMIT, and if stack allocation is supported by the platform
|
#ifndef EIGEN_ALLOCA
|
||||||
* (currently, this is Linux only). Otherwise the memory is allocated on the heap.
|
#if (defined __linux__)
|
||||||
* Data allocated with ei_aligned_stack_alloc \b must be freed by calling
|
#define EIGEN_ALLOCA alloca
|
||||||
* ei_aligned_stack_free(PTR,SIZE).
|
#elif defined(_MSC_VER)
|
||||||
* \code
|
#define EIGEN_ALLOCA _alloca
|
||||||
* float * data = ei_aligned_stack_alloc(float,array.size());
|
#endif
|
||||||
* // ...
|
|
||||||
* ei_aligned_stack_free(data,float,array.size());
|
|
||||||
* \endcode
|
|
||||||
*/
|
|
||||||
#if (defined __linux__)
|
|
||||||
#define ei_aligned_stack_alloc(SIZE) (SIZE<=EIGEN_STACK_ALLOCATION_LIMIT) \
|
|
||||||
? alloca(SIZE) \
|
|
||||||
: Eigen::internal::aligned_malloc(SIZE)
|
|
||||||
#define ei_aligned_stack_free(PTR,SIZE) if(SIZE>EIGEN_STACK_ALLOCATION_LIMIT) Eigen::internal::aligned_free(PTR)
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#define ei_aligned_stack_alloc(SIZE) (SIZE<=EIGEN_STACK_ALLOCATION_LIMIT) \
|
|
||||||
? _alloca(SIZE) \
|
|
||||||
: Eigen::internal::aligned_malloc(SIZE)
|
|
||||||
#define ei_aligned_stack_free(PTR,SIZE) if(SIZE>EIGEN_STACK_ALLOCATION_LIMIT) Eigen::internal::aligned_free(PTR)
|
|
||||||
#else
|
|
||||||
#define ei_aligned_stack_alloc(SIZE) Eigen::internal::aligned_malloc(SIZE)
|
|
||||||
#define ei_aligned_stack_free(PTR,SIZE) Eigen::internal::aligned_free(PTR)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ei_aligned_stack_new(TYPE,SIZE) Eigen::internal::construct_elements_of_array(reinterpret_cast<TYPE*>(ei_aligned_stack_alloc(sizeof(TYPE)*SIZE)), SIZE)
|
namespace internal {
|
||||||
#define ei_aligned_stack_delete(TYPE,PTR,SIZE) do {Eigen::internal::destruct_elements_of_array<TYPE>(PTR, SIZE); \
|
|
||||||
ei_aligned_stack_free(PTR,sizeof(TYPE)*SIZE);} while(0)
|
// This helper class construct the allocated memory, and takes care of destructing and freeing the handled data
|
||||||
|
// at destruction time. In practice this helper class is mainly useful to avoid memory leak in case of exceptions.
|
||||||
|
template<typename T> class aligned_stack_memory_handler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/* Creates a stack_memory_handler responsible for the buffer \a ptr of size \a size.
|
||||||
|
* Note that \a ptr can be 0 regardless of the other parameters.
|
||||||
|
* This constructor takes care of constructing/initializing the elements of the buffer if required by the scalar type T (see NumTraits<T>::RequireInitialization).
|
||||||
|
* In this case, the buffer elements will also be destructed when this handler will be destructed.
|
||||||
|
* Finally, if \a dealloc is true, then the pointer \a ptr is freed.
|
||||||
|
**/
|
||||||
|
aligned_stack_memory_handler(T* ptr, size_t size, bool dealloc)
|
||||||
|
: m_ptr(ptr), m_size(size), m_deallocate(dealloc)
|
||||||
|
{
|
||||||
|
if(NumTraits<T>::RequireInitialization && m_ptr)
|
||||||
|
Eigen::internal::construct_elements_of_array(m_ptr, size);
|
||||||
|
}
|
||||||
|
~aligned_stack_memory_handler()
|
||||||
|
{
|
||||||
|
if(NumTraits<T>::RequireInitialization && m_ptr)
|
||||||
|
Eigen::internal::destruct_elements_of_array<T>(m_ptr, m_size);
|
||||||
|
if(m_deallocate)
|
||||||
|
Eigen::internal::aligned_free(m_ptr);
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
T* m_ptr;
|
||||||
|
size_t m_size;
|
||||||
|
bool m_deallocate;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \internal
|
||||||
|
* Declares, allocates and construct an aligned buffer named NAME of SIZE elements of type TYPE on the stack
|
||||||
|
* if SIZE is smaller than EIGEN_STACK_ALLOCATION_LIMIT, and if stack allocation is supported by the platform
|
||||||
|
* (currently, this is Linux and Visual Studio only). Otherwise the memory is allocated on the heap.
|
||||||
|
* The allocated buffer is automatically deleted when exiting the scope of this declaration.
|
||||||
|
* If BUFFER is non nul, then the declared variable is simply an alias for BUFFER, and no allocation/deletion occurs.
|
||||||
|
* Here is an example:
|
||||||
|
* \code
|
||||||
|
* {
|
||||||
|
* ei_declare_aligned_stack_constructed_variable(float,data,size,0);
|
||||||
|
* // use data[0] to data[size-1]
|
||||||
|
* }
|
||||||
|
* \endcode
|
||||||
|
* The underlying stack allocation function can controlled with the EIGEN_ALLOCA preprocessor token.
|
||||||
|
*/
|
||||||
|
#ifdef EIGEN_ALLOCA
|
||||||
|
|
||||||
|
#ifdef __arm__
|
||||||
|
#define EIGEN_ALIGNED_ALLOCA(SIZE) reinterpret_cast<void*>((reinterpret_cast<size_t>(EIGEN_ALLOCA(SIZE+16)) & ~(size_t(15))) + 16)
|
||||||
|
#else
|
||||||
|
#define EIGEN_ALIGNED_ALLOCA EIGEN_ALLOCA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ei_declare_aligned_stack_constructed_variable(TYPE,NAME,SIZE,BUFFER) \
|
||||||
|
TYPE* NAME = (BUFFER)!=0 ? (BUFFER) \
|
||||||
|
: reinterpret_cast<TYPE*>( \
|
||||||
|
(sizeof(TYPE)*SIZE<=EIGEN_STACK_ALLOCATION_LIMIT) ? EIGEN_ALIGNED_ALLOCA(sizeof(TYPE)*SIZE) \
|
||||||
|
: Eigen::internal::aligned_malloc(sizeof(TYPE)*SIZE) ); \
|
||||||
|
Eigen::internal::aligned_stack_memory_handler<TYPE> EIGEN_CAT(NAME,_stack_memory_destructor)((BUFFER)==0 ? NAME : 0,SIZE,sizeof(TYPE)*SIZE>EIGEN_STACK_ALLOCATION_LIMIT)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define ei_declare_aligned_stack_constructed_variable(TYPE,NAME,SIZE,BUFFER) \
|
||||||
|
TYPE* NAME = (BUFFER)!=0 ? BUFFER : reinterpret_cast<TYPE*>(Eigen::internal::aligned_malloc(sizeof(TYPE)*SIZE)); \
|
||||||
|
Eigen::internal::aligned_stack_memory_handler<TYPE> EIGEN_CAT(NAME,_stack_memory_destructor)((BUFFER)==0 ? NAME : 0,SIZE,true)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@@ -592,12 +663,12 @@ public:
|
|||||||
|
|
||||||
size_type max_size() const throw()
|
size_type max_size() const throw()
|
||||||
{
|
{
|
||||||
return std::numeric_limits<size_type>::max();
|
return (std::numeric_limits<size_type>::max)();
|
||||||
}
|
}
|
||||||
|
|
||||||
pointer allocate( size_type num, const_pointer* hint = 0 )
|
pointer allocate( size_type num, const void* hint = 0 )
|
||||||
{
|
{
|
||||||
static_cast<void>( hint ); // suppress unused variable warning
|
EIGEN_UNUSED_VARIABLE(hint);
|
||||||
return static_cast<pointer>( internal::aligned_malloc( num * sizeof(T) ) );
|
return static_cast<pointer>( internal::aligned_malloc( num * sizeof(T) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -832,7 +903,7 @@ inline int queryTopLevelCacheSize()
|
|||||||
{
|
{
|
||||||
int l1, l2(-1), l3(-1);
|
int l1, l2(-1), l3(-1);
|
||||||
queryCacheSizes(l1,l2,l3);
|
queryCacheSizes(l1,l2,l3);
|
||||||
return std::max(l2,l3);
|
return (std::max)(l2,l3);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|||||||
14
Eigen/src/Core/util/ReenableStupidWarnings.h
Normal file
14
Eigen/src/Core/util/ReenableStupidWarnings.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#ifdef EIGEN_WARNINGS_DISABLED
|
||||||
|
#undef EIGEN_WARNINGS_DISABLED
|
||||||
|
|
||||||
|
#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning( pop )
|
||||||
|
#elif defined __INTEL_COMPILER
|
||||||
|
#pragma warning pop
|
||||||
|
#elif defined __clang__
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // EIGEN_WARNINGS_DISABLED
|
||||||
@@ -4,3 +4,5 @@ INSTALL(FILES
|
|||||||
${Eigen_Eigen2Support_SRCS}
|
${Eigen_Eigen2Support_SRCS}
|
||||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Eigen2Support COMPONENT Devel
|
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Eigen2Support COMPONENT Devel
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ADD_SUBDIRECTORY(Geometry)
|
||||||
@@ -55,6 +55,9 @@
|
|||||||
* Example: \include MatrixBase_cwise_const.cpp
|
* Example: \include MatrixBase_cwise_const.cpp
|
||||||
* Output: \verbinclude MatrixBase_cwise_const.out
|
* Output: \verbinclude MatrixBase_cwise_const.out
|
||||||
*
|
*
|
||||||
|
* This class can be extended with the help of the plugin mechanism described on the page
|
||||||
|
* \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_CWISE_PLUGIN.
|
||||||
|
*
|
||||||
* \sa MatrixBase::cwise() const, MatrixBase::cwise()
|
* \sa MatrixBase::cwise() const, MatrixBase::cwise()
|
||||||
*/
|
*/
|
||||||
template<typename ExpressionType> class Cwise
|
template<typename ExpressionType> class Cwise
|
||||||
@@ -79,13 +82,17 @@ template<typename ExpressionType> class Cwise
|
|||||||
const EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_quotient_op)
|
const EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_quotient_op)
|
||||||
operator/(const MatrixBase<OtherDerived> &other) const;
|
operator/(const MatrixBase<OtherDerived> &other) const;
|
||||||
|
|
||||||
|
/** \deprecated ArrayBase::min() */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
const EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_min_op)
|
const EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_min_op)
|
||||||
min(const MatrixBase<OtherDerived> &other) const;
|
(min)(const MatrixBase<OtherDerived> &other) const
|
||||||
|
{ return EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_min_op)(_expression(), other.derived()); }
|
||||||
|
|
||||||
|
/** \deprecated ArrayBase::max() */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
const EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_max_op)
|
const EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_max_op)
|
||||||
max(const MatrixBase<OtherDerived> &other) const;
|
(max)(const MatrixBase<OtherDerived> &other) const
|
||||||
|
{ return EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_max_op)(_expression(), other.derived()); }
|
||||||
|
|
||||||
const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_abs_op) abs() const;
|
const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_abs_op) abs() const;
|
||||||
const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_abs2_op) abs2() const;
|
const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_abs2_op) abs2() const;
|
||||||
|
|||||||
@@ -96,24 +96,6 @@ inline ExpressionType& Cwise<ExpressionType>::operator/=(const MatrixBase<OtherD
|
|||||||
return m_matrix.const_cast_derived() = *this / other;
|
return m_matrix.const_cast_derived() = *this / other;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \deprecated ArrayBase::min() */
|
|
||||||
template<typename ExpressionType>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_min_op)
|
|
||||||
Cwise<ExpressionType>::min(const MatrixBase<OtherDerived> &other) const
|
|
||||||
{
|
|
||||||
return EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_min_op)(_expression(), other.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \deprecated ArrayBase::max() */
|
|
||||||
template<typename ExpressionType>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_max_op)
|
|
||||||
Cwise<ExpressionType>::max(const MatrixBase<OtherDerived> &other) const
|
|
||||||
{
|
|
||||||
return EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_max_op)(_expression(), other.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* The following functions were defined in Array
|
* The following functions were defined in Array
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|||||||
@@ -51,14 +51,14 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim==
|
|||||||
{ if (AmbientDimAtCompileTime!=Dynamic) setNull(); }
|
{ if (AmbientDimAtCompileTime!=Dynamic) setNull(); }
|
||||||
|
|
||||||
/** Constructs a null box with \a _dim the dimension of the ambient space. */
|
/** Constructs a null box with \a _dim the dimension of the ambient space. */
|
||||||
inline explicit AlignedBox(int _dim) : m_min(_dim), m_max(_dim)
|
inline explicit AlignedBox(int _dim) : m_(min)(_dim), m_(max)(_dim)
|
||||||
{ setNull(); }
|
{ setNull(); }
|
||||||
|
|
||||||
/** Constructs a box with extremities \a _min and \a _max. */
|
/** Constructs a box with extremities \a _min and \a _max. */
|
||||||
inline AlignedBox(const VectorType& _min, const VectorType& _max) : m_min(_min), m_max(_max) {}
|
inline AlignedBox(const VectorType& _min, const VectorType& _max) : m_(min)(_min), m_(max)(_max) {}
|
||||||
|
|
||||||
/** Constructs a box containing a single point \a p. */
|
/** Constructs a box containing a single point \a p. */
|
||||||
inline explicit AlignedBox(const VectorType& p) : m_min(p), m_max(p) {}
|
inline explicit AlignedBox(const VectorType& p) : m_(min)(p), m_(max)(p) {}
|
||||||
|
|
||||||
~AlignedBox() {}
|
~AlignedBox() {}
|
||||||
|
|
||||||
@@ -71,18 +71,18 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim==
|
|||||||
/** Makes \c *this a null/empty box. */
|
/** Makes \c *this a null/empty box. */
|
||||||
inline void setNull()
|
inline void setNull()
|
||||||
{
|
{
|
||||||
m_min.setConstant( std::numeric_limits<Scalar>::max());
|
m_min.setConstant( std::numeric_limits<Scalar>::(max)());
|
||||||
m_max.setConstant(-std::numeric_limits<Scalar>::max());
|
m_max.setConstant(-std::numeric_limits<Scalar>::(max)());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the minimal corner */
|
/** \returns the minimal corner */
|
||||||
inline const VectorType& min() const { return m_min; }
|
inline const VectorType& (min)() const { return m_min; }
|
||||||
/** \returns a non const reference to the minimal corner */
|
/** \returns a non const reference to the minimal corner */
|
||||||
inline VectorType& min() { return m_min; }
|
inline VectorType& (min)() { return m_min; }
|
||||||
/** \returns the maximal corner */
|
/** \returns the maximal corner */
|
||||||
inline const VectorType& max() const { return m_max; }
|
inline const VectorType& (max)() const { return m_max; }
|
||||||
/** \returns a non const reference to the maximal corner */
|
/** \returns a non const reference to the maximal corner */
|
||||||
inline VectorType& max() { return m_max; }
|
inline VectorType& (max)() { return m_max; }
|
||||||
|
|
||||||
/** \returns true if the point \a p is inside the box \c *this. */
|
/** \returns true if the point \a p is inside the box \c *this. */
|
||||||
inline bool contains(const VectorType& p) const
|
inline bool contains(const VectorType& p) const
|
||||||
@@ -90,19 +90,19 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim==
|
|||||||
|
|
||||||
/** \returns true if the box \a b is entirely inside the box \c *this. */
|
/** \returns true if the box \a b is entirely inside the box \c *this. */
|
||||||
inline bool contains(const AlignedBox& b) const
|
inline bool contains(const AlignedBox& b) const
|
||||||
{ return (m_min.cwise()<=b.min()).all() && (b.max().cwise()<=m_max).all(); }
|
{ return (m_min.cwise()<=b.(min)()).all() && (b.(max)().cwise()<=m_max).all(); }
|
||||||
|
|
||||||
/** Extends \c *this such that it contains the point \a p and returns a reference to \c *this. */
|
/** Extends \c *this such that it contains the point \a p and returns a reference to \c *this. */
|
||||||
inline AlignedBox& extend(const VectorType& p)
|
inline AlignedBox& extend(const VectorType& p)
|
||||||
{ m_min = m_min.cwise().min(p); m_max = m_max.cwise().max(p); return *this; }
|
{ m_min = m_min.cwise().(min)(p); m_max = m_max.cwise().(max)(p); return *this; }
|
||||||
|
|
||||||
/** Extends \c *this such that it contains the box \a b and returns a reference to \c *this. */
|
/** Extends \c *this such that it contains the box \a b and returns a reference to \c *this. */
|
||||||
inline AlignedBox& extend(const AlignedBox& b)
|
inline AlignedBox& extend(const AlignedBox& b)
|
||||||
{ m_min = m_min.cwise().min(b.m_min); m_max = m_max.cwise().max(b.m_max); return *this; }
|
{ m_min = m_min.cwise().(min)(b.m_min); m_max = m_max.cwise().(max)(b.m_max); return *this; }
|
||||||
|
|
||||||
/** Clamps \c *this by the box \a b and returns a reference to \c *this. */
|
/** Clamps \c *this by the box \a b and returns a reference to \c *this. */
|
||||||
inline AlignedBox& clamp(const AlignedBox& b)
|
inline AlignedBox& clamp(const AlignedBox& b)
|
||||||
{ m_min = m_min.cwise().max(b.m_min); m_max = m_max.cwise().min(b.m_max); return *this; }
|
{ m_min = m_min.cwise().(max)(b.m_min); m_max = m_max.cwise().(min)(b.m_max); return *this; }
|
||||||
|
|
||||||
/** Translate \c *this by the vector \a t and returns a reference to \c *this. */
|
/** Translate \c *this by the vector \a t and returns a reference to \c *this. */
|
||||||
inline AlignedBox& translate(const VectorType& t)
|
inline AlignedBox& translate(const VectorType& t)
|
||||||
@@ -138,8 +138,8 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim==
|
|||||||
template<typename OtherScalarType>
|
template<typename OtherScalarType>
|
||||||
inline explicit AlignedBox(const AlignedBox<OtherScalarType,AmbientDimAtCompileTime>& other)
|
inline explicit AlignedBox(const AlignedBox<OtherScalarType,AmbientDimAtCompileTime>& other)
|
||||||
{
|
{
|
||||||
m_min = other.min().template cast<Scalar>();
|
m_min = other.(min)().template cast<Scalar>();
|
||||||
m_max = other.max().template cast<Scalar>();
|
m_max = other.(max)().template cast<Scalar>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns \c true if \c *this is approximately equal to \a other, within the precision
|
/** \returns \c true if \c *this is approximately equal to \a other, within the precision
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
FILE(GLOB Eigen_Geometry_SRCS "*.h")
|
FILE(GLOB Eigen_Eigen2Support_Geometry_SRCS "*.h")
|
||||||
|
|
||||||
INSTALL(FILES
|
INSTALL(FILES
|
||||||
${Eigen_Geometry_SRCS}
|
${Eigen_Eigen2Support_Geometry_SRCS}
|
||||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Eigen2Support/Geometry
|
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Eigen2Support/Geometry
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -64,9 +64,9 @@ template<typename MatrixType> class SVD
|
|||||||
SVD() {} // a user who relied on compiler-generated default compiler reported problems with MSVC in 2.0.7
|
SVD() {} // a user who relied on compiler-generated default compiler reported problems with MSVC in 2.0.7
|
||||||
|
|
||||||
SVD(const MatrixType& matrix)
|
SVD(const MatrixType& matrix)
|
||||||
: m_matU(matrix.rows(), std::min(matrix.rows(), matrix.cols())),
|
: m_matU(matrix.rows(), (std::min)(matrix.rows(), matrix.cols())),
|
||||||
m_matV(matrix.cols(),matrix.cols()),
|
m_matV(matrix.cols(),matrix.cols()),
|
||||||
m_sigma(std::min(matrix.rows(),matrix.cols()))
|
m_sigma((std::min)(matrix.rows(),matrix.cols()))
|
||||||
{
|
{
|
||||||
compute(matrix);
|
compute(matrix);
|
||||||
}
|
}
|
||||||
@@ -108,13 +108,13 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
|
|||||||
{
|
{
|
||||||
const int m = matrix.rows();
|
const int m = matrix.rows();
|
||||||
const int n = matrix.cols();
|
const int n = matrix.cols();
|
||||||
const int nu = std::min(m,n);
|
const int nu = (std::min)(m,n);
|
||||||
ei_assert(m>=n && "In Eigen 2.0, SVD only works for MxN matrices with M>=N. Sorry!");
|
ei_assert(m>=n && "In Eigen 2.0, SVD only works for MxN matrices with M>=N. Sorry!");
|
||||||
ei_assert(m>1 && "In Eigen 2.0, SVD doesn't work on 1x1 matrices");
|
ei_assert(m>1 && "In Eigen 2.0, SVD doesn't work on 1x1 matrices");
|
||||||
|
|
||||||
m_matU.resize(m, nu);
|
m_matU.resize(m, nu);
|
||||||
m_matU.setZero();
|
m_matU.setZero();
|
||||||
m_sigma.resize(std::min(m,n));
|
m_sigma.resize((std::min)(m,n));
|
||||||
m_matV.resize(n,n);
|
m_matV.resize(n,n);
|
||||||
|
|
||||||
RowVector e(n);
|
RowVector e(n);
|
||||||
@@ -126,9 +126,9 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
|
|||||||
|
|
||||||
// Reduce A to bidiagonal form, storing the diagonal elements
|
// Reduce A to bidiagonal form, storing the diagonal elements
|
||||||
// in s and the super-diagonal elements in e.
|
// in s and the super-diagonal elements in e.
|
||||||
int nct = std::min(m-1,n);
|
int nct = (std::min)(m-1,n);
|
||||||
int nrt = std::max(0,std::min(n-2,m));
|
int nrt = (std::max)(0,(std::min)(n-2,m));
|
||||||
for (k = 0; k < std::max(nct,nrt); ++k)
|
for (k = 0; k < (std::max)(nct,nrt); ++k)
|
||||||
{
|
{
|
||||||
if (k < nct)
|
if (k < nct)
|
||||||
{
|
{
|
||||||
@@ -193,7 +193,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
|
|||||||
|
|
||||||
|
|
||||||
// Set up the final bidiagonal matrix or order p.
|
// Set up the final bidiagonal matrix or order p.
|
||||||
int p = std::min(n,m+1);
|
int p = (std::min)(n,m+1);
|
||||||
if (nct < n)
|
if (nct < n)
|
||||||
m_sigma[nct] = matA(nct,nct);
|
m_sigma[nct] = matA(nct,nct);
|
||||||
if (m < p)
|
if (m < p)
|
||||||
@@ -380,7 +380,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
|
|||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
// Calculate the shift.
|
// Calculate the shift.
|
||||||
Scalar scale = std::max(std::max(std::max(std::max(
|
Scalar scale = (std::max)((std::max)((std::max)((std::max)(
|
||||||
ei_abs(m_sigma[p-1]),ei_abs(m_sigma[p-2])),ei_abs(e[p-2])),
|
ei_abs(m_sigma[p-1]),ei_abs(m_sigma[p-2])),ei_abs(e[p-2])),
|
||||||
ei_abs(m_sigma[k])),ei_abs(e[k]));
|
ei_abs(m_sigma[k])),ei_abs(e[k]));
|
||||||
Scalar sp = m_sigma[p-1]/scale;
|
Scalar sp = m_sigma[p-1]/scale;
|
||||||
|
|||||||
@@ -186,7 +186,8 @@ template<typename _MatrixType> class ComplexEigenSolver
|
|||||||
* This function returns a column vector containing the
|
* This function returns a column vector containing the
|
||||||
* eigenvalues. Eigenvalues are repeated according to their
|
* eigenvalues. Eigenvalues are repeated according to their
|
||||||
* algebraic multiplicity, so there are as many eigenvalues as
|
* algebraic multiplicity, so there are as many eigenvalues as
|
||||||
* rows in the matrix.
|
* rows in the matrix. The eigenvalues are not sorted in any particular
|
||||||
|
* order.
|
||||||
*
|
*
|
||||||
* Example: \include ComplexEigenSolver_eigenvalues.cpp
|
* Example: \include ComplexEigenSolver_eigenvalues.cpp
|
||||||
* Output: \verbinclude ComplexEigenSolver_eigenvalues.out
|
* Output: \verbinclude ComplexEigenSolver_eigenvalues.out
|
||||||
|
|||||||
@@ -423,7 +423,7 @@ void ComplexSchur<MatrixType>::reduceToTriangularForm(bool computeU)
|
|||||||
JacobiRotation<ComplexScalar> rot;
|
JacobiRotation<ComplexScalar> rot;
|
||||||
rot.makeGivens(m_matT.coeff(il,il) - shift, m_matT.coeff(il+1,il));
|
rot.makeGivens(m_matT.coeff(il,il) - shift, m_matT.coeff(il+1,il));
|
||||||
m_matT.rightCols(m_matT.cols()-il).applyOnTheLeft(il, il+1, rot.adjoint());
|
m_matT.rightCols(m_matT.cols()-il).applyOnTheLeft(il, il+1, rot.adjoint());
|
||||||
m_matT.topRows(std::min(il+2,iu)+1).applyOnTheRight(il, il+1, rot);
|
m_matT.topRows((std::min)(il+2,iu)+1).applyOnTheRight(il, il+1, rot);
|
||||||
if(computeU) m_matU.applyOnTheRight(il, il+1, rot);
|
if(computeU) m_matU.applyOnTheRight(il, il+1, rot);
|
||||||
|
|
||||||
for(Index i=il+1 ; i<iu ; i++)
|
for(Index i=il+1 ; i<iu ; i++)
|
||||||
@@ -431,7 +431,7 @@ void ComplexSchur<MatrixType>::reduceToTriangularForm(bool computeU)
|
|||||||
rot.makeGivens(m_matT.coeffRef(i,i-1), m_matT.coeffRef(i+1,i-1), &m_matT.coeffRef(i,i-1));
|
rot.makeGivens(m_matT.coeffRef(i,i-1), m_matT.coeffRef(i+1,i-1), &m_matT.coeffRef(i,i-1));
|
||||||
m_matT.coeffRef(i+1,i-1) = ComplexScalar(0);
|
m_matT.coeffRef(i+1,i-1) = ComplexScalar(0);
|
||||||
m_matT.rightCols(m_matT.cols()-i).applyOnTheLeft(i, i+1, rot.adjoint());
|
m_matT.rightCols(m_matT.cols()-i).applyOnTheLeft(i, i+1, rot.adjoint());
|
||||||
m_matT.topRows(std::min(i+2,iu)+1).applyOnTheRight(i, i+1, rot);
|
m_matT.topRows((std::min)(i+2,iu)+1).applyOnTheRight(i, i+1, rot);
|
||||||
if(computeU) m_matU.applyOnTheRight(i, i+1, rot);
|
if(computeU) m_matU.applyOnTheRight(i, i+1, rot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -228,6 +228,7 @@ template<typename _MatrixType> class EigenSolver
|
|||||||
* block-diagonal. The blocks on the diagonal are either 1-by-1 or 2-by-2
|
* block-diagonal. The blocks on the diagonal are either 1-by-1 or 2-by-2
|
||||||
* blocks of the form
|
* blocks of the form
|
||||||
* \f$ \begin{bmatrix} u & v \\ -v & u \end{bmatrix} \f$.
|
* \f$ \begin{bmatrix} u & v \\ -v & u \end{bmatrix} \f$.
|
||||||
|
* These blocks are not sorted in any particular order.
|
||||||
* The matrix \f$ D \f$ and the matrix \f$ V \f$ returned by
|
* The matrix \f$ D \f$ and the matrix \f$ V \f$ returned by
|
||||||
* pseudoEigenvectors() satisfy \f$ AV = VD \f$.
|
* pseudoEigenvectors() satisfy \f$ AV = VD \f$.
|
||||||
*
|
*
|
||||||
@@ -244,7 +245,8 @@ template<typename _MatrixType> class EigenSolver
|
|||||||
* compute(const MatrixType&, bool) has been called before.
|
* compute(const MatrixType&, bool) has been called before.
|
||||||
*
|
*
|
||||||
* The eigenvalues are repeated according to their algebraic multiplicity,
|
* The eigenvalues are repeated according to their algebraic multiplicity,
|
||||||
* so there are as many eigenvalues as rows in the matrix.
|
* so there are as many eigenvalues as rows in the matrix. The eigenvalues
|
||||||
|
* are not sorted in any particular order.
|
||||||
*
|
*
|
||||||
* Example: \include EigenSolver_eigenvalues.cpp
|
* Example: \include EigenSolver_eigenvalues.cpp
|
||||||
* Output: \verbinclude EigenSolver_eigenvalues.out
|
* Output: \verbinclude EigenSolver_eigenvalues.out
|
||||||
@@ -341,6 +343,7 @@ typename EigenSolver<MatrixType>::EigenvectorsType EigenSolver<MatrixType>::eige
|
|||||||
{
|
{
|
||||||
// we have a real eigen value
|
// we have a real eigen value
|
||||||
matV.col(j) = m_eivec.col(j).template cast<ComplexScalar>();
|
matV.col(j) = m_eivec.col(j).template cast<ComplexScalar>();
|
||||||
|
matV.col(j).normalize();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -432,7 +435,7 @@ void EigenSolver<MatrixType>::doComputeEigenvectors()
|
|||||||
Scalar norm = 0.0;
|
Scalar norm = 0.0;
|
||||||
for (Index j = 0; j < size; ++j)
|
for (Index j = 0; j < size; ++j)
|
||||||
{
|
{
|
||||||
norm += m_matT.row(j).segment(std::max(j-1,Index(0)), size-std::max(j-1,Index(0))).cwiseAbs().sum();
|
norm += m_matT.row(j).segment((std::max)(j-1,Index(0)), size-(std::max)(j-1,Index(0))).cwiseAbs().sum();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backsubstitute to find vectors of upper triangular form
|
// Backsubstitute to find vectors of upper triangular form
|
||||||
@@ -447,7 +450,7 @@ void EigenSolver<MatrixType>::doComputeEigenvectors()
|
|||||||
Scalar q = m_eivalues.coeff(n).imag();
|
Scalar q = m_eivalues.coeff(n).imag();
|
||||||
|
|
||||||
// Scalar vector
|
// Scalar vector
|
||||||
if (q == 0)
|
if (q == Scalar(0))
|
||||||
{
|
{
|
||||||
Scalar lastr=0, lastw=0;
|
Scalar lastr=0, lastw=0;
|
||||||
Index l = n;
|
Index l = n;
|
||||||
@@ -488,12 +491,12 @@ void EigenSolver<MatrixType>::doComputeEigenvectors()
|
|||||||
|
|
||||||
// Overflow control
|
// Overflow control
|
||||||
Scalar t = internal::abs(m_matT.coeff(i,n));
|
Scalar t = internal::abs(m_matT.coeff(i,n));
|
||||||
if ((eps * t) * t > 1)
|
if ((eps * t) * t > Scalar(1))
|
||||||
m_matT.col(n).tail(size-i) /= t;
|
m_matT.col(n).tail(size-i) /= t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (q < 0) // Complex vector
|
else if (q < Scalar(0) && n > 0) // Complex vector
|
||||||
{
|
{
|
||||||
Scalar lastra=0, lastsa=0, lastw=0;
|
Scalar lastra=0, lastsa=0, lastw=0;
|
||||||
Index l = n-1;
|
Index l = n-1;
|
||||||
@@ -527,7 +530,7 @@ void EigenSolver<MatrixType>::doComputeEigenvectors()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
l = i;
|
l = i;
|
||||||
if (m_eivalues.coeff(i).imag() == 0)
|
if (m_eivalues.coeff(i).imag() == RealScalar(0))
|
||||||
{
|
{
|
||||||
std::complex<Scalar> cc = cdiv(-ra,-sa,w,q);
|
std::complex<Scalar> cc = cdiv(-ra,-sa,w,q);
|
||||||
m_matT.coeffRef(i,n-1) = internal::real(cc);
|
m_matT.coeffRef(i,n-1) = internal::real(cc);
|
||||||
@@ -560,13 +563,18 @@ void EigenSolver<MatrixType>::doComputeEigenvectors()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Overflow control
|
// Overflow control
|
||||||
Scalar t = std::max(internal::abs(m_matT.coeff(i,n-1)),internal::abs(m_matT.coeff(i,n)));
|
using std::max;
|
||||||
if ((eps * t) * t > 1)
|
Scalar t = (max)(internal::abs(m_matT.coeff(i,n-1)),internal::abs(m_matT.coeff(i,n)));
|
||||||
|
if ((eps * t) * t > Scalar(1))
|
||||||
m_matT.block(i, n-1, size-i, 2) /= t;
|
m_matT.block(i, n-1, size-i, 2) /= t;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eigen_assert("Internal bug in EigenSolver"); // this should not happen
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Back transformation to get eigenvectors of original matrix
|
// Back transformation to get eigenvectors of original matrix
|
||||||
|
|||||||
@@ -70,13 +70,9 @@ class GeneralizedSelfAdjointEigenSolver : public SelfAdjointEigenSolver<_MatrixT
|
|||||||
/** \brief Default constructor for fixed-size matrices.
|
/** \brief Default constructor for fixed-size matrices.
|
||||||
*
|
*
|
||||||
* The default constructor is useful in cases in which the user intends to
|
* The default constructor is useful in cases in which the user intends to
|
||||||
* perform decompositions via compute(const MatrixType&, bool) or
|
* perform decompositions via compute(). This constructor
|
||||||
* compute(const MatrixType&, const MatrixType&, bool). This constructor
|
|
||||||
* can only be used if \p _MatrixType is a fixed-size matrix; use
|
* can only be used if \p _MatrixType is a fixed-size matrix; use
|
||||||
* SelfAdjointEigenSolver(Index) for dynamic-size matrices.
|
* GeneralizedSelfAdjointEigenSolver(Index) for dynamic-size matrices.
|
||||||
*
|
|
||||||
* Example: \include SelfAdjointEigenSolver_SelfAdjointEigenSolver.cpp
|
|
||||||
* Output: \verbinclude SelfAdjointEigenSolver_SelfAdjointEigenSolver.out
|
|
||||||
*/
|
*/
|
||||||
GeneralizedSelfAdjointEigenSolver() : Base() {}
|
GeneralizedSelfAdjointEigenSolver() : Base() {}
|
||||||
|
|
||||||
@@ -86,12 +82,11 @@ class GeneralizedSelfAdjointEigenSolver : public SelfAdjointEigenSolver<_MatrixT
|
|||||||
* eigenvalues and eigenvectors will be computed.
|
* eigenvalues and eigenvectors will be computed.
|
||||||
*
|
*
|
||||||
* This constructor is useful for dynamic-size matrices, when the user
|
* This constructor is useful for dynamic-size matrices, when the user
|
||||||
* intends to perform decompositions via compute(const MatrixType&, bool)
|
* intends to perform decompositions via compute(). The \p size
|
||||||
* or compute(const MatrixType&, const MatrixType&, bool). The \p size
|
|
||||||
* parameter is only used as a hint. It is not an error to give a wrong
|
* parameter is only used as a hint. It is not an error to give a wrong
|
||||||
* \p size, but it may impair performance.
|
* \p size, but it may impair performance.
|
||||||
*
|
*
|
||||||
* \sa compute(const MatrixType&, bool) for an example
|
* \sa compute() for an example
|
||||||
*/
|
*/
|
||||||
GeneralizedSelfAdjointEigenSolver(Index size)
|
GeneralizedSelfAdjointEigenSolver(Index size)
|
||||||
: Base(size)
|
: Base(size)
|
||||||
@@ -103,8 +98,8 @@ class GeneralizedSelfAdjointEigenSolver : public SelfAdjointEigenSolver<_MatrixT
|
|||||||
* Only the lower triangular part of the matrix is referenced.
|
* Only the lower triangular part of the matrix is referenced.
|
||||||
* \param[in] matB Positive-definite matrix in matrix pencil.
|
* \param[in] matB Positive-definite matrix in matrix pencil.
|
||||||
* Only the lower triangular part of the matrix is referenced.
|
* Only the lower triangular part of the matrix is referenced.
|
||||||
* \param[in] options A or-ed set of flags {ComputeEigenvectors,EigenvaluesOnly} | {Ax_lBx,ABx_lx,BAx_lx}.
|
* \param[in] options A or-ed set of flags {#ComputeEigenvectors,#EigenvaluesOnly} | {#Ax_lBx,#ABx_lx,#BAx_lx}.
|
||||||
* Default is ComputeEigenvectors|Ax_lBx.
|
* Default is #ComputeEigenvectors|#Ax_lBx.
|
||||||
*
|
*
|
||||||
* This constructor calls compute(const MatrixType&, const MatrixType&, int)
|
* This constructor calls compute(const MatrixType&, const MatrixType&, int)
|
||||||
* to compute the eigenvalues and (if requested) the eigenvectors of the
|
* to compute the eigenvalues and (if requested) the eigenvectors of the
|
||||||
@@ -136,8 +131,8 @@ class GeneralizedSelfAdjointEigenSolver : public SelfAdjointEigenSolver<_MatrixT
|
|||||||
* Only the lower triangular part of the matrix is referenced.
|
* Only the lower triangular part of the matrix is referenced.
|
||||||
* \param[in] matB Positive-definite matrix in matrix pencil.
|
* \param[in] matB Positive-definite matrix in matrix pencil.
|
||||||
* Only the lower triangular part of the matrix is referenced.
|
* Only the lower triangular part of the matrix is referenced.
|
||||||
* \param[in] options A or-ed set of flags {ComputeEigenvectors,EigenvaluesOnly} | {Ax_lBx,ABx_lx,BAx_lx}.
|
* \param[in] options A or-ed set of flags {#ComputeEigenvectors,#EigenvaluesOnly} | {#Ax_lBx,#ABx_lx,#BAx_lx}.
|
||||||
* Default is ComputeEigenvectors|Ax_lBx.
|
* Default is #ComputeEigenvectors|#Ax_lBx.
|
||||||
*
|
*
|
||||||
* \returns Reference to \c *this
|
* \returns Reference to \c *this
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -290,7 +290,7 @@ inline typename MatrixType::Scalar RealSchur<MatrixType>::computeNormOfT()
|
|||||||
// + m_matT.bottomLeftCorner(size-1,size-1).diagonal().cwiseAbs().sum();
|
// + m_matT.bottomLeftCorner(size-1,size-1).diagonal().cwiseAbs().sum();
|
||||||
Scalar norm = 0.0;
|
Scalar norm = 0.0;
|
||||||
for (Index j = 0; j < size; ++j)
|
for (Index j = 0; j < size; ++j)
|
||||||
norm += m_matT.row(j).segment(std::max(j-1,Index(0)), size-std::max(j-1,Index(0))).cwiseAbs().sum();
|
norm += m_matT.row(j).segment((std::max)(j-1,Index(0)), size-(std::max)(j-1,Index(0))).cwiseAbs().sum();
|
||||||
return norm;
|
return norm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,11 +324,11 @@ inline void RealSchur<MatrixType>::splitOffTwoRows(Index iu, bool computeU, Scal
|
|||||||
m_matT.coeffRef(iu,iu) += exshift;
|
m_matT.coeffRef(iu,iu) += exshift;
|
||||||
m_matT.coeffRef(iu-1,iu-1) += exshift;
|
m_matT.coeffRef(iu-1,iu-1) += exshift;
|
||||||
|
|
||||||
if (q >= 0) // Two real eigenvalues
|
if (q >= Scalar(0)) // Two real eigenvalues
|
||||||
{
|
{
|
||||||
Scalar z = internal::sqrt(internal::abs(q));
|
Scalar z = internal::sqrt(internal::abs(q));
|
||||||
JacobiRotation<Scalar> rot;
|
JacobiRotation<Scalar> rot;
|
||||||
if (p >= 0)
|
if (p >= Scalar(0))
|
||||||
rot.makeGivens(p + z, m_matT.coeff(iu, iu-1));
|
rot.makeGivens(p + z, m_matT.coeff(iu, iu-1));
|
||||||
else
|
else
|
||||||
rot.makeGivens(p - z, m_matT.coeff(iu, iu-1));
|
rot.makeGivens(p - z, m_matT.coeff(iu, iu-1));
|
||||||
@@ -369,7 +369,7 @@ inline void RealSchur<MatrixType>::computeShift(Index iu, Index iter, Scalar& ex
|
|||||||
{
|
{
|
||||||
Scalar s = (shiftInfo.coeff(1) - shiftInfo.coeff(0)) / Scalar(2.0);
|
Scalar s = (shiftInfo.coeff(1) - shiftInfo.coeff(0)) / Scalar(2.0);
|
||||||
s = s * s + shiftInfo.coeff(2);
|
s = s * s + shiftInfo.coeff(2);
|
||||||
if (s > 0)
|
if (s > Scalar(0))
|
||||||
{
|
{
|
||||||
s = internal::sqrt(s);
|
s = internal::sqrt(s);
|
||||||
if (shiftInfo.coeff(1) < shiftInfo.coeff(0))
|
if (shiftInfo.coeff(1) < shiftInfo.coeff(0))
|
||||||
@@ -442,7 +442,7 @@ inline void RealSchur<MatrixType>::performFrancisQRStep(Index il, Index im, Inde
|
|||||||
|
|
||||||
// These Householder transformations form the O(n^3) part of the algorithm
|
// These Householder transformations form the O(n^3) part of the algorithm
|
||||||
m_matT.block(k, k, 3, size-k).applyHouseholderOnTheLeft(ess, tau, workspace);
|
m_matT.block(k, k, 3, size-k).applyHouseholderOnTheLeft(ess, tau, workspace);
|
||||||
m_matT.block(0, k, std::min(iu,k+3) + 1, 3).applyHouseholderOnTheRight(ess, tau, workspace);
|
m_matT.block(0, k, (std::min)(iu,k+3) + 1, 3).applyHouseholderOnTheRight(ess, tau, workspace);
|
||||||
if (computeU)
|
if (computeU)
|
||||||
m_matU.block(0, k, size, 3).applyHouseholderOnTheRight(ess, tau, workspace);
|
m_matU.block(0, k, size, 3).applyHouseholderOnTheRight(ess, tau, workspace);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,12 +62,12 @@ class GeneralizedSelfAdjointEigenSolver;
|
|||||||
*
|
*
|
||||||
* Call the function compute() to compute the eigenvalues and eigenvectors of
|
* Call the function compute() to compute the eigenvalues and eigenvectors of
|
||||||
* a given matrix. Alternatively, you can use the
|
* a given matrix. Alternatively, you can use the
|
||||||
* SelfAdjointEigenSolver(const MatrixType&, bool) constructor which computes
|
* SelfAdjointEigenSolver(const MatrixType&, int) constructor which computes
|
||||||
* the eigenvalues and eigenvectors at construction time. Once the eigenvalue
|
* the eigenvalues and eigenvectors at construction time. Once the eigenvalue
|
||||||
* and eigenvectors are computed, they can be retrieved with the eigenvalues()
|
* and eigenvectors are computed, they can be retrieved with the eigenvalues()
|
||||||
* and eigenvectors() functions.
|
* and eigenvectors() functions.
|
||||||
*
|
*
|
||||||
* The documentation for SelfAdjointEigenSolver(const MatrixType&, bool)
|
* The documentation for SelfAdjointEigenSolver(const MatrixType&, int)
|
||||||
* contains an example of the typical use of this class.
|
* contains an example of the typical use of this class.
|
||||||
*
|
*
|
||||||
* To solve the \em generalized eigenvalue problem \f$ Av = \lambda Bv \f$ and
|
* To solve the \em generalized eigenvalue problem \f$ Av = \lambda Bv \f$ and
|
||||||
@@ -110,8 +110,7 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
|||||||
/** \brief Default constructor for fixed-size matrices.
|
/** \brief Default constructor for fixed-size matrices.
|
||||||
*
|
*
|
||||||
* The default constructor is useful in cases in which the user intends to
|
* The default constructor is useful in cases in which the user intends to
|
||||||
* perform decompositions via compute(const MatrixType&, bool) or
|
* perform decompositions via compute(). This constructor
|
||||||
* compute(const MatrixType&, const MatrixType&, bool). This constructor
|
|
||||||
* can only be used if \p _MatrixType is a fixed-size matrix; use
|
* can only be used if \p _MatrixType is a fixed-size matrix; use
|
||||||
* SelfAdjointEigenSolver(Index) for dynamic-size matrices.
|
* SelfAdjointEigenSolver(Index) for dynamic-size matrices.
|
||||||
*
|
*
|
||||||
@@ -131,12 +130,11 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
|||||||
* eigenvalues and eigenvectors will be computed.
|
* eigenvalues and eigenvectors will be computed.
|
||||||
*
|
*
|
||||||
* This constructor is useful for dynamic-size matrices, when the user
|
* This constructor is useful for dynamic-size matrices, when the user
|
||||||
* intends to perform decompositions via compute(const MatrixType&, bool)
|
* intends to perform decompositions via compute(). The \p size
|
||||||
* or compute(const MatrixType&, const MatrixType&, bool). The \p size
|
|
||||||
* parameter is only used as a hint. It is not an error to give a wrong
|
* parameter is only used as a hint. It is not an error to give a wrong
|
||||||
* \p size, but it may impair performance.
|
* \p size, but it may impair performance.
|
||||||
*
|
*
|
||||||
* \sa compute(const MatrixType&, bool) for an example
|
* \sa compute() for an example
|
||||||
*/
|
*/
|
||||||
SelfAdjointEigenSolver(Index size)
|
SelfAdjointEigenSolver(Index size)
|
||||||
: m_eivec(size, size),
|
: m_eivec(size, size),
|
||||||
@@ -149,17 +147,16 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
|||||||
*
|
*
|
||||||
* \param[in] matrix Selfadjoint matrix whose eigendecomposition is to
|
* \param[in] matrix Selfadjoint matrix whose eigendecomposition is to
|
||||||
* be computed. Only the lower triangular part of the matrix is referenced.
|
* be computed. Only the lower triangular part of the matrix is referenced.
|
||||||
* \param[in] options Can be ComputeEigenvectors (default) or EigenvaluesOnly.
|
* \param[in] options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly.
|
||||||
*
|
*
|
||||||
* This constructor calls compute(const MatrixType&, bool) to compute the
|
* This constructor calls compute(const MatrixType&, int) to compute the
|
||||||
* eigenvalues of the matrix \p matrix. The eigenvectors are computed if
|
* eigenvalues of the matrix \p matrix. The eigenvectors are computed if
|
||||||
* \p options equals ComputeEigenvectors.
|
* \p options equals #ComputeEigenvectors.
|
||||||
*
|
*
|
||||||
* Example: \include SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType.cpp
|
* Example: \include SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType.cpp
|
||||||
* Output: \verbinclude SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType.out
|
* Output: \verbinclude SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType.out
|
||||||
*
|
*
|
||||||
* \sa compute(const MatrixType&, bool),
|
* \sa compute(const MatrixType&, int)
|
||||||
* SelfAdjointEigenSolver(const MatrixType&, const MatrixType&, bool)
|
|
||||||
*/
|
*/
|
||||||
SelfAdjointEigenSolver(const MatrixType& matrix, int options = ComputeEigenvectors)
|
SelfAdjointEigenSolver(const MatrixType& matrix, int options = ComputeEigenvectors)
|
||||||
: m_eivec(matrix.rows(), matrix.cols()),
|
: m_eivec(matrix.rows(), matrix.cols()),
|
||||||
@@ -174,11 +171,11 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
|||||||
*
|
*
|
||||||
* \param[in] matrix Selfadjoint matrix whose eigendecomposition is to
|
* \param[in] matrix Selfadjoint matrix whose eigendecomposition is to
|
||||||
* be computed. Only the lower triangular part of the matrix is referenced.
|
* be computed. Only the lower triangular part of the matrix is referenced.
|
||||||
* \param[in] options Can be ComputeEigenvectors (default) or EigenvaluesOnly.
|
* \param[in] options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly.
|
||||||
* \returns Reference to \c *this
|
* \returns Reference to \c *this
|
||||||
*
|
*
|
||||||
* This function computes the eigenvalues of \p matrix. The eigenvalues()
|
* This function computes the eigenvalues of \p matrix. The eigenvalues()
|
||||||
* function can be used to retrieve them. If \p options equals ComputeEigenvectors,
|
* function can be used to retrieve them. If \p options equals #ComputeEigenvectors,
|
||||||
* then the eigenvectors are also computed and can be retrieved by
|
* then the eigenvectors are also computed and can be retrieved by
|
||||||
* calling eigenvectors().
|
* calling eigenvectors().
|
||||||
*
|
*
|
||||||
@@ -198,11 +195,11 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
|||||||
* Example: \include SelfAdjointEigenSolver_compute_MatrixType.cpp
|
* Example: \include SelfAdjointEigenSolver_compute_MatrixType.cpp
|
||||||
* Output: \verbinclude SelfAdjointEigenSolver_compute_MatrixType.out
|
* Output: \verbinclude SelfAdjointEigenSolver_compute_MatrixType.out
|
||||||
*
|
*
|
||||||
* \sa SelfAdjointEigenSolver(const MatrixType&, bool)
|
* \sa SelfAdjointEigenSolver(const MatrixType&, int)
|
||||||
*/
|
*/
|
||||||
SelfAdjointEigenSolver& compute(const MatrixType& matrix, int options = ComputeEigenvectors);
|
SelfAdjointEigenSolver& compute(const MatrixType& matrix, int options = ComputeEigenvectors);
|
||||||
|
|
||||||
/** \brief Returns the eigenvectors of given matrix (pencil).
|
/** \brief Returns the eigenvectors of given matrix.
|
||||||
*
|
*
|
||||||
* \returns A const reference to the matrix whose columns are the eigenvectors.
|
* \returns A const reference to the matrix whose columns are the eigenvectors.
|
||||||
*
|
*
|
||||||
@@ -227,14 +224,15 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
|||||||
return m_eivec;
|
return m_eivec;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Returns the eigenvalues of given matrix (pencil).
|
/** \brief Returns the eigenvalues of given matrix.
|
||||||
*
|
*
|
||||||
* \returns A const reference to the column vector containing the eigenvalues.
|
* \returns A const reference to the column vector containing the eigenvalues.
|
||||||
*
|
*
|
||||||
* \pre The eigenvalues have been computed before.
|
* \pre The eigenvalues have been computed before.
|
||||||
*
|
*
|
||||||
* The eigenvalues are repeated according to their algebraic multiplicity,
|
* The eigenvalues are repeated according to their algebraic multiplicity,
|
||||||
* so there are as many eigenvalues as rows in the matrix.
|
* so there are as many eigenvalues as rows in the matrix. The eigenvalues
|
||||||
|
* are sorted in increasing order.
|
||||||
*
|
*
|
||||||
* Example: \include SelfAdjointEigenSolver_eigenvalues.cpp
|
* Example: \include SelfAdjointEigenSolver_eigenvalues.cpp
|
||||||
* Output: \verbinclude SelfAdjointEigenSolver_eigenvalues.out
|
* Output: \verbinclude SelfAdjointEigenSolver_eigenvalues.out
|
||||||
@@ -389,7 +387,7 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
|
|||||||
{
|
{
|
||||||
m_eivalues.coeffRef(0,0) = internal::real(matrix.coeff(0,0));
|
m_eivalues.coeffRef(0,0) = internal::real(matrix.coeff(0,0));
|
||||||
if(computeEigenvectors)
|
if(computeEigenvectors)
|
||||||
m_eivec.setOnes();
|
m_eivec.setOnes(n,n);
|
||||||
m_info = Success;
|
m_info = Success;
|
||||||
m_isInitialized = true;
|
m_isInitialized = true;
|
||||||
m_eigenvectorsOk = computeEigenvectors;
|
m_eigenvectorsOk = computeEigenvectors;
|
||||||
@@ -402,10 +400,11 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
|
|||||||
|
|
||||||
// map the matrix coefficients to [-1:1] to avoid over- and underflow.
|
// map the matrix coefficients to [-1:1] to avoid over- and underflow.
|
||||||
RealScalar scale = matrix.cwiseAbs().maxCoeff();
|
RealScalar scale = matrix.cwiseAbs().maxCoeff();
|
||||||
|
if(scale==Scalar(0)) scale = 1;
|
||||||
mat = matrix / scale;
|
mat = matrix / scale;
|
||||||
m_subdiag.resize(n-1);
|
m_subdiag.resize(n-1);
|
||||||
internal::tridiagonalization_inplace(mat, diag, m_subdiag, computeEigenvectors);
|
internal::tridiagonalization_inplace(mat, diag, m_subdiag, computeEigenvectors);
|
||||||
|
|
||||||
Index end = n-1;
|
Index end = n-1;
|
||||||
Index start = 0;
|
Index start = 0;
|
||||||
Index iter = 0; // number of iterations we are working on one element
|
Index iter = 0; // number of iterations we are working on one element
|
||||||
@@ -458,7 +457,7 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// scale back the eigen values
|
// scale back the eigen values
|
||||||
m_eivalues *= scale;
|
m_eivalues *= scale;
|
||||||
|
|
||||||
@@ -471,12 +470,17 @@ namespace internal {
|
|||||||
template<int StorageOrder,typename RealScalar, typename Scalar, typename Index>
|
template<int StorageOrder,typename RealScalar, typename Scalar, typename Index>
|
||||||
static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n)
|
static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n)
|
||||||
{
|
{
|
||||||
|
// NOTE this version avoids over & underflow, however since the matrix is prescaled, overflow cannot occur,
|
||||||
|
// and underflows should be meaningless anyway. So I don't any reason to enable this version, but I keep
|
||||||
|
// it here for reference:
|
||||||
|
// RealScalar td = (diag[end-1] - diag[end])*RealScalar(0.5);
|
||||||
|
// RealScalar e = subdiag[end-1];
|
||||||
|
// RealScalar mu = diag[end] - (e / (td + (td>0 ? 1 : -1))) * (e / hypot(td,e));
|
||||||
RealScalar td = (diag[end-1] - diag[end])*RealScalar(0.5);
|
RealScalar td = (diag[end-1] - diag[end])*RealScalar(0.5);
|
||||||
RealScalar e2 = abs2(subdiag[end-1]);
|
RealScalar e2 = abs2(subdiag[end-1]);
|
||||||
RealScalar mu = diag[end] - e2 / (td + (td>0 ? 1 : -1) * sqrt(td*td + e2));
|
RealScalar mu = diag[end] - e2 / (td + (td>0 ? 1 : -1) * sqrt(td*td + e2));
|
||||||
RealScalar x = diag[start] - mu;
|
RealScalar x = diag[start] - mu;
|
||||||
RealScalar z = subdiag[start];
|
RealScalar z = subdiag[start];
|
||||||
|
|
||||||
for (Index k = start; k < end; ++k)
|
for (Index k = start; k < end; ++k)
|
||||||
{
|
{
|
||||||
JacobiRotation<RealScalar> rot;
|
JacobiRotation<RealScalar> rot;
|
||||||
@@ -489,6 +493,7 @@ static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index sta
|
|||||||
diag[k] = rot.c() * (rot.c() * diag[k] - rot.s() * subdiag[k]) - rot.s() * (rot.c() * subdiag[k] - rot.s() * diag[k+1]);
|
diag[k] = rot.c() * (rot.c() * diag[k] - rot.s() * subdiag[k]) - rot.s() * (rot.c() * subdiag[k] - rot.s() * diag[k+1]);
|
||||||
diag[k+1] = rot.s() * sdk + rot.c() * dkp1;
|
diag[k+1] = rot.s() * sdk + rot.c() * dkp1;
|
||||||
subdiag[k] = rot.c() * sdk - rot.s() * dkp1;
|
subdiag[k] = rot.c() * sdk - rot.s() * dkp1;
|
||||||
|
|
||||||
|
|
||||||
if (k > start)
|
if (k > start)
|
||||||
subdiag[k - 1] = rot.c() * subdiag[k-1] - rot.s() * z;
|
subdiag[k - 1] = rot.c() * subdiag[k-1] - rot.s() * z;
|
||||||
@@ -500,7 +505,7 @@ static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index sta
|
|||||||
z = -rot.s() * subdiag[k+1];
|
z = -rot.s() * subdiag[k+1];
|
||||||
subdiag[k + 1] = rot.c() * subdiag[k+1];
|
subdiag[k + 1] = rot.c() * subdiag[k+1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply the givens rotation to the unit matrix Q = Q * G
|
// apply the givens rotation to the unit matrix Q = Q * G
|
||||||
if (matrixQ)
|
if (matrixQ)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -111,13 +111,13 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the minimal corner */
|
/** \returns the minimal corner */
|
||||||
inline const VectorType& min() const { return m_min; }
|
inline const VectorType& (min)() const { return m_min; }
|
||||||
/** \returns a non const reference to the minimal corner */
|
/** \returns a non const reference to the minimal corner */
|
||||||
inline VectorType& min() { return m_min; }
|
inline VectorType& (min)() { return m_min; }
|
||||||
/** \returns the maximal corner */
|
/** \returns the maximal corner */
|
||||||
inline const VectorType& max() const { return m_max; }
|
inline const VectorType& (max)() const { return m_max; }
|
||||||
/** \returns a non const reference to the maximal corner */
|
/** \returns a non const reference to the maximal corner */
|
||||||
inline VectorType& max() { return m_max; }
|
inline VectorType& (max)() { return m_max; }
|
||||||
|
|
||||||
/** \returns the center of the box */
|
/** \returns the center of the box */
|
||||||
inline const CwiseUnaryOp<internal::scalar_quotient1_op<Scalar>,
|
inline const CwiseUnaryOp<internal::scalar_quotient1_op<Scalar>,
|
||||||
@@ -196,7 +196,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
|
|||||||
|
|
||||||
/** \returns true if the box \a b is entirely inside the box \c *this. */
|
/** \returns true if the box \a b is entirely inside the box \c *this. */
|
||||||
inline bool contains(const AlignedBox& b) const
|
inline bool contains(const AlignedBox& b) const
|
||||||
{ return (m_min.array()<=b.min().array()).all() && (b.max().array()<=m_max.array()).all(); }
|
{ return (m_min.array()<=(b.min)().array()).all() && ((b.max)().array()<=m_max.array()).all(); }
|
||||||
|
|
||||||
/** Extends \c *this such that it contains the point \a p and returns a reference to \c *this. */
|
/** Extends \c *this such that it contains the point \a p and returns a reference to \c *this. */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
@@ -287,8 +287,8 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
|
|||||||
template<typename OtherScalarType>
|
template<typename OtherScalarType>
|
||||||
inline explicit AlignedBox(const AlignedBox<OtherScalarType,AmbientDimAtCompileTime>& other)
|
inline explicit AlignedBox(const AlignedBox<OtherScalarType,AmbientDimAtCompileTime>& other)
|
||||||
{
|
{
|
||||||
m_min = other.min().template cast<Scalar>();
|
m_min = (other.min)().template cast<Scalar>();
|
||||||
m_max = other.max().template cast<Scalar>();
|
m_max = (other.max)().template cast<Scalar>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns \c true if \c *this is approximately equal to \a other, within the precision
|
/** \returns \c true if \c *this is approximately equal to \a other, within the precision
|
||||||
|
|||||||
@@ -171,6 +171,9 @@ template<typename Scalar>
|
|||||||
template<typename QuatDerived>
|
template<typename QuatDerived>
|
||||||
AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived>& q)
|
AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived>& q)
|
||||||
{
|
{
|
||||||
|
using std::acos;
|
||||||
|
using std::min;
|
||||||
|
using std::max;
|
||||||
Scalar n2 = q.vec().squaredNorm();
|
Scalar n2 = q.vec().squaredNorm();
|
||||||
if (n2 < NumTraits<Scalar>::dummy_precision()*NumTraits<Scalar>::dummy_precision())
|
if (n2 < NumTraits<Scalar>::dummy_precision()*NumTraits<Scalar>::dummy_precision())
|
||||||
{
|
{
|
||||||
@@ -179,7 +182,7 @@ AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_angle = Scalar(2)*std::acos(std::min(std::max(Scalar(-1),q.w()),Scalar(1)));
|
m_angle = Scalar(2)*acos((min)((max)(Scalar(-1),q.w()),Scalar(1)));
|
||||||
m_axis = q.vec() / internal::sqrt(n2);
|
m_axis = q.vec() / internal::sqrt(n2);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
|
|||||||
@@ -232,13 +232,15 @@ template<typename MatrixType,typename Lhs>
|
|||||||
struct traits<homogeneous_left_product_impl<Homogeneous<MatrixType,Vertical>,Lhs> >
|
struct traits<homogeneous_left_product_impl<Homogeneous<MatrixType,Vertical>,Lhs> >
|
||||||
{
|
{
|
||||||
typedef typename take_matrix_for_product<Lhs>::type LhsMatrixType;
|
typedef typename take_matrix_for_product<Lhs>::type LhsMatrixType;
|
||||||
|
typedef typename remove_all<MatrixType>::type MatrixTypeCleaned;
|
||||||
|
typedef typename remove_all<LhsMatrixType>::type LhsMatrixTypeCleaned;
|
||||||
typedef typename make_proper_matrix_type<
|
typedef typename make_proper_matrix_type<
|
||||||
typename traits<MatrixType>::Scalar,
|
typename traits<MatrixTypeCleaned>::Scalar,
|
||||||
LhsMatrixType::RowsAtCompileTime,
|
LhsMatrixTypeCleaned::RowsAtCompileTime,
|
||||||
MatrixType::ColsAtCompileTime,
|
MatrixTypeCleaned::ColsAtCompileTime,
|
||||||
MatrixType::PlainObject::Options,
|
MatrixTypeCleaned::PlainObject::Options,
|
||||||
LhsMatrixType::MaxRowsAtCompileTime,
|
LhsMatrixTypeCleaned::MaxRowsAtCompileTime,
|
||||||
MatrixType::MaxColsAtCompileTime>::type ReturnType;
|
MatrixTypeCleaned::MaxColsAtCompileTime>::type ReturnType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename MatrixType,typename Lhs>
|
template<typename MatrixType,typename Lhs>
|
||||||
@@ -246,7 +248,8 @@ struct homogeneous_left_product_impl<Homogeneous<MatrixType,Vertical>,Lhs>
|
|||||||
: public ReturnByValue<homogeneous_left_product_impl<Homogeneous<MatrixType,Vertical>,Lhs> >
|
: public ReturnByValue<homogeneous_left_product_impl<Homogeneous<MatrixType,Vertical>,Lhs> >
|
||||||
{
|
{
|
||||||
typedef typename traits<homogeneous_left_product_impl>::LhsMatrixType LhsMatrixType;
|
typedef typename traits<homogeneous_left_product_impl>::LhsMatrixType LhsMatrixType;
|
||||||
typedef typename remove_all<typename LhsMatrixType::Nested>::type LhsMatrixTypeNested;
|
typedef typename remove_all<LhsMatrixType>::type LhsMatrixTypeCleaned;
|
||||||
|
typedef typename remove_all<typename LhsMatrixTypeCleaned::Nested>::type LhsMatrixTypeNested;
|
||||||
typedef typename MatrixType::Index Index;
|
typedef typename MatrixType::Index Index;
|
||||||
homogeneous_left_product_impl(const Lhs& lhs, const MatrixType& rhs)
|
homogeneous_left_product_impl(const Lhs& lhs, const MatrixType& rhs)
|
||||||
: m_lhs(take_matrix_for_product<Lhs>::run(lhs)),
|
: m_lhs(take_matrix_for_product<Lhs>::run(lhs)),
|
||||||
@@ -267,7 +270,7 @@ struct homogeneous_left_product_impl<Homogeneous<MatrixType,Vertical>,Lhs>
|
|||||||
.template replicate<MatrixType::ColsAtCompileTime>(m_rhs.cols());
|
.template replicate<MatrixType::ColsAtCompileTime>(m_rhs.cols());
|
||||||
}
|
}
|
||||||
|
|
||||||
const typename LhsMatrixType::Nested m_lhs;
|
const typename LhsMatrixTypeCleaned::Nested m_lhs;
|
||||||
const typename MatrixType::Nested m_rhs;
|
const typename MatrixType::Nested m_rhs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ public:
|
|||||||
*
|
*
|
||||||
* \note If \a other is approximately parallel to *this, this method will return any point on *this.
|
* \note If \a other is approximately parallel to *this, this method will return any point on *this.
|
||||||
*/
|
*/
|
||||||
VectorType intersection(const Hyperplane& other)
|
VectorType intersection(const Hyperplane& other) const
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 2)
|
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 2)
|
||||||
Scalar det = coeffs().coeff(0) * other.coeffs().coeff(1) - coeffs().coeff(1) * other.coeffs().coeff(0);
|
Scalar det = coeffs().coeff(0) * other.coeffs().coeff(1) - coeffs().coeff(1) * other.coeffs().coeff(0);
|
||||||
@@ -213,8 +213,8 @@ public:
|
|||||||
/** Applies the transformation matrix \a mat to \c *this and returns a reference to \c *this.
|
/** Applies the transformation matrix \a mat to \c *this and returns a reference to \c *this.
|
||||||
*
|
*
|
||||||
* \param mat the Dim x Dim transformation matrix
|
* \param mat the Dim x Dim transformation matrix
|
||||||
* \param traits specifies whether the matrix \a mat represents an Isometry
|
* \param traits specifies whether the matrix \a mat represents an #Isometry
|
||||||
* or a more generic Affine transformation. The default is Affine.
|
* or a more generic #Affine transformation. The default is #Affine.
|
||||||
*/
|
*/
|
||||||
template<typename XprType>
|
template<typename XprType>
|
||||||
inline Hyperplane& transform(const MatrixBase<XprType>& mat, TransformTraits traits = Affine)
|
inline Hyperplane& transform(const MatrixBase<XprType>& mat, TransformTraits traits = Affine)
|
||||||
@@ -233,8 +233,8 @@ public:
|
|||||||
/** Applies the transformation \a t to \c *this and returns a reference to \c *this.
|
/** Applies the transformation \a t to \c *this and returns a reference to \c *this.
|
||||||
*
|
*
|
||||||
* \param t the transformation of dimension Dim
|
* \param t the transformation of dimension Dim
|
||||||
* \param traits specifies whether the transformation \a t represents an Isometry
|
* \param traits specifies whether the transformation \a t represents an #Isometry
|
||||||
* or a more generic Affine transformation. The default is Affine.
|
* or a more generic #Affine transformation. The default is #Affine.
|
||||||
* Other kind of transformations are not supported.
|
* Other kind of transformations are not supported.
|
||||||
*/
|
*/
|
||||||
template<int TrOptions>
|
template<int TrOptions>
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
*
|
*
|
||||||
* A parametrized line is defined by an origin point \f$ \mathbf{o} \f$ and a unit
|
* A parametrized line is defined by an origin point \f$ \mathbf{o} \f$ and a unit
|
||||||
* direction vector \f$ \mathbf{d} \f$ such that the line corresponds to
|
* direction vector \f$ \mathbf{d} \f$ such that the line corresponds to
|
||||||
* the set \f$ l(t) = \mathbf{o} + t \mathbf{d} \f$, \f$ l \in \mathbf{R} \f$.
|
* the set \f$ l(t) = \mathbf{o} + t \mathbf{d} \f$, \f$ t \in \mathbf{R} \f$.
|
||||||
*
|
*
|
||||||
* \param _Scalar the scalar type, i.e., the type of the coefficients
|
* \param _Scalar the scalar type, i.e., the type of the coefficients
|
||||||
* \param _AmbientDim the dimension of the ambient space, can be a compile time value or Dynamic.
|
* \param _AmbientDim the dimension of the ambient space, can be a compile time value or Dynamic.
|
||||||
@@ -107,7 +107,7 @@ public:
|
|||||||
{ return origin() + direction().dot(p-origin()) * direction(); }
|
{ return origin() + direction().dot(p-origin()) * direction(); }
|
||||||
|
|
||||||
template <int OtherOptions>
|
template <int OtherOptions>
|
||||||
Scalar intersection(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane);
|
Scalar intersection(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const;
|
||||||
|
|
||||||
/** \returns \c *this with scalar type casted to \a NewScalarType
|
/** \returns \c *this with scalar type casted to \a NewScalarType
|
||||||
*
|
*
|
||||||
@@ -159,7 +159,7 @@ inline ParametrizedLine<_Scalar, _AmbientDim,_Options>::ParametrizedLine(const H
|
|||||||
*/
|
*/
|
||||||
template <typename _Scalar, int _AmbientDim, int _Options>
|
template <typename _Scalar, int _AmbientDim, int _Options>
|
||||||
template <int OtherOptions>
|
template <int OtherOptions>
|
||||||
inline _Scalar ParametrizedLine<_Scalar, _AmbientDim,_Options>::intersection(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane)
|
inline _Scalar ParametrizedLine<_Scalar, _AmbientDim,_Options>::intersection(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const
|
||||||
{
|
{
|
||||||
return -(hyperplane.offset()+hyperplane.normal().dot(origin()))
|
return -(hyperplane.offset()+hyperplane.normal().dot(origin()))
|
||||||
/ hyperplane.normal().dot(direction());
|
/ hyperplane.normal().dot(direction());
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ public:
|
|||||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||||
typedef typename internal::traits<Derived>::Coefficients Coefficients;
|
typedef typename internal::traits<Derived>::Coefficients Coefficients;
|
||||||
|
enum {
|
||||||
|
Flags = Eigen::internal::traits<Derived>::Flags
|
||||||
|
};
|
||||||
|
|
||||||
// typedef typename Matrix<Scalar,4,1> Coefficients;
|
// typedef typename Matrix<Scalar,4,1> Coefficients;
|
||||||
/** the type of a 3D vector */
|
/** the type of a 3D vector */
|
||||||
@@ -222,7 +225,8 @@ struct traits<Quaternion<_Scalar,_Options> >
|
|||||||
typedef _Scalar Scalar;
|
typedef _Scalar Scalar;
|
||||||
typedef Matrix<_Scalar,4,1,_Options> Coefficients;
|
typedef Matrix<_Scalar,4,1,_Options> Coefficients;
|
||||||
enum{
|
enum{
|
||||||
PacketAccess = _Options & DontAlign ? Unaligned : Aligned
|
IsAligned = bool(EIGEN_ALIGN) && ((int(_Options)&Aligned)==Aligned),
|
||||||
|
Flags = IsAligned ? (AlignedBit | LvalueBit) : LvalueBit
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -294,33 +298,53 @@ typedef Quaternion<double> Quaterniond;
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
template<typename _Scalar, int _PacketAccess>
|
template<typename _Scalar, int _Options>
|
||||||
struct traits<Map<Quaternion<_Scalar>, _PacketAccess> >:
|
struct traits<Map<Quaternion<_Scalar>, _Options> >:
|
||||||
traits<Quaternion<_Scalar> >
|
traits<Quaternion<_Scalar, _Options> >
|
||||||
{
|
{
|
||||||
typedef _Scalar Scalar;
|
typedef _Scalar Scalar;
|
||||||
typedef Map<Matrix<_Scalar,4,1>, _PacketAccess> Coefficients;
|
typedef Map<Matrix<_Scalar,4,1>, _Options> Coefficients;
|
||||||
enum {
|
|
||||||
PacketAccess = _PacketAccess
|
typedef traits<Quaternion<_Scalar, _Options> > TraitsBase;
|
||||||
|
enum {
|
||||||
|
IsAligned = TraitsBase::IsAligned,
|
||||||
|
|
||||||
|
Flags = TraitsBase::Flags
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
template<typename _Scalar, int _Options>
|
||||||
|
struct traits<Map<const Quaternion<_Scalar>, _Options> >:
|
||||||
|
traits<Quaternion<_Scalar> >
|
||||||
|
{
|
||||||
|
typedef _Scalar Scalar;
|
||||||
|
typedef Map<const Matrix<_Scalar,4,1>, _Options> Coefficients;
|
||||||
|
|
||||||
|
typedef traits<Quaternion<_Scalar, _Options> > TraitsBase;
|
||||||
|
enum {
|
||||||
|
IsAligned = TraitsBase::IsAligned,
|
||||||
|
Flags = TraitsBase::Flags & ~LvalueBit
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Quaternion expression mapping a constant memory buffer
|
/** \brief Quaternion expression mapping a constant memory buffer
|
||||||
*
|
*
|
||||||
* \param _Scalar the type of the Quaternion coefficients
|
* \param _Scalar the type of the Quaternion coefficients
|
||||||
* \param PacketAccess see class Map
|
* \param _Options see class Map
|
||||||
*
|
*
|
||||||
* This is a specialization of class Map for Quaternion. This class allows to view
|
* This is a specialization of class Map for Quaternion. This class allows to view
|
||||||
* a 4 scalar memory buffer as an Eigen's Quaternion object.
|
* a 4 scalar memory buffer as an Eigen's Quaternion object.
|
||||||
*
|
*
|
||||||
* \sa class Map, class Quaternion, class QuaternionBase
|
* \sa class Map, class Quaternion, class QuaternionBase
|
||||||
*/
|
*/
|
||||||
template<typename _Scalar, int PacketAccess>
|
template<typename _Scalar, int _Options>
|
||||||
class Map<const Quaternion<_Scalar>, PacketAccess >
|
class Map<const Quaternion<_Scalar>, _Options >
|
||||||
: public QuaternionBase<Map<const Quaternion<_Scalar>, PacketAccess> >
|
: public QuaternionBase<Map<const Quaternion<_Scalar>, _Options> >
|
||||||
{
|
{
|
||||||
typedef QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> > Base;
|
typedef QuaternionBase<Map<const Quaternion<_Scalar>, _Options> > Base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef _Scalar Scalar;
|
typedef _Scalar Scalar;
|
||||||
@@ -333,7 +357,7 @@ class Map<const Quaternion<_Scalar>, PacketAccess >
|
|||||||
* The pointer \a coeffs must reference the four coeffecients of Quaternion in the following order:
|
* The pointer \a coeffs must reference the four coeffecients of Quaternion in the following order:
|
||||||
* \code *coeffs == {x, y, z, w} \endcode
|
* \code *coeffs == {x, y, z, w} \endcode
|
||||||
*
|
*
|
||||||
* If the template parameter PacketAccess is set to Aligned, then the pointer coeffs must be aligned. */
|
* If the template parameter _Options is set to #Aligned, then the pointer coeffs must be aligned. */
|
||||||
EIGEN_STRONG_INLINE Map(const Scalar* coeffs) : m_coeffs(coeffs) {}
|
EIGEN_STRONG_INLINE Map(const Scalar* coeffs) : m_coeffs(coeffs) {}
|
||||||
|
|
||||||
inline const Coefficients& coeffs() const { return m_coeffs;}
|
inline const Coefficients& coeffs() const { return m_coeffs;}
|
||||||
@@ -345,18 +369,18 @@ class Map<const Quaternion<_Scalar>, PacketAccess >
|
|||||||
/** \brief Expression of a quaternion from a memory buffer
|
/** \brief Expression of a quaternion from a memory buffer
|
||||||
*
|
*
|
||||||
* \param _Scalar the type of the Quaternion coefficients
|
* \param _Scalar the type of the Quaternion coefficients
|
||||||
* \param PacketAccess see class Map
|
* \param _Options see class Map
|
||||||
*
|
*
|
||||||
* This is a specialization of class Map for Quaternion. This class allows to view
|
* This is a specialization of class Map for Quaternion. This class allows to view
|
||||||
* a 4 scalar memory buffer as an Eigen's Quaternion object.
|
* a 4 scalar memory buffer as an Eigen's Quaternion object.
|
||||||
*
|
*
|
||||||
* \sa class Map, class Quaternion, class QuaternionBase
|
* \sa class Map, class Quaternion, class QuaternionBase
|
||||||
*/
|
*/
|
||||||
template<typename _Scalar, int PacketAccess>
|
template<typename _Scalar, int _Options>
|
||||||
class Map<Quaternion<_Scalar>, PacketAccess >
|
class Map<Quaternion<_Scalar>, _Options >
|
||||||
: public QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> >
|
: public QuaternionBase<Map<Quaternion<_Scalar>, _Options> >
|
||||||
{
|
{
|
||||||
typedef QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> > Base;
|
typedef QuaternionBase<Map<Quaternion<_Scalar>, _Options> > Base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef _Scalar Scalar;
|
typedef _Scalar Scalar;
|
||||||
@@ -369,7 +393,7 @@ class Map<Quaternion<_Scalar>, PacketAccess >
|
|||||||
* The pointer \a coeffs must reference the four coeffecients of Quaternion in the following order:
|
* The pointer \a coeffs must reference the four coeffecients of Quaternion in the following order:
|
||||||
* \code *coeffs == {x, y, z, w} \endcode
|
* \code *coeffs == {x, y, z, w} \endcode
|
||||||
*
|
*
|
||||||
* If the template parameter PacketAccess is set to Aligned, then the pointer coeffs must be aligned. */
|
* If the template parameter _Options is set to #Aligned, then the pointer coeffs must be aligned. */
|
||||||
EIGEN_STRONG_INLINE Map(Scalar* coeffs) : m_coeffs(coeffs) {}
|
EIGEN_STRONG_INLINE Map(Scalar* coeffs) : m_coeffs(coeffs) {}
|
||||||
|
|
||||||
inline Coefficients& coeffs() { return m_coeffs; }
|
inline Coefficients& coeffs() { return m_coeffs; }
|
||||||
@@ -399,7 +423,7 @@ typedef Map<Quaternion<double>, Aligned> QuaternionMapAlignedd;
|
|||||||
// Generic Quaternion * Quaternion product
|
// Generic Quaternion * Quaternion product
|
||||||
// This product can be specialized for a given architecture via the Arch template argument.
|
// This product can be specialized for a given architecture via the Arch template argument.
|
||||||
namespace internal {
|
namespace internal {
|
||||||
template<int Arch, class Derived1, class Derived2, typename Scalar, int PacketAccess> struct quat_product
|
template<int Arch, class Derived1, class Derived2, typename Scalar, int _Options> struct quat_product
|
||||||
{
|
{
|
||||||
EIGEN_STRONG_INLINE static Quaternion<Scalar> run(const QuaternionBase<Derived1>& a, const QuaternionBase<Derived2>& b){
|
EIGEN_STRONG_INLINE static Quaternion<Scalar> run(const QuaternionBase<Derived1>& a, const QuaternionBase<Derived2>& b){
|
||||||
return Quaternion<Scalar>
|
return Quaternion<Scalar>
|
||||||
@@ -423,7 +447,7 @@ QuaternionBase<Derived>::operator* (const QuaternionBase<OtherDerived>& other) c
|
|||||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||||
return internal::quat_product<Architecture::Target, Derived, OtherDerived,
|
return internal::quat_product<Architecture::Target, Derived, OtherDerived,
|
||||||
typename internal::traits<Derived>::Scalar,
|
typename internal::traits<Derived>::Scalar,
|
||||||
internal::traits<Derived>::PacketAccess && internal::traits<OtherDerived>::PacketAccess>::run(*this, other);
|
internal::traits<Derived>::IsAligned && internal::traits<OtherDerived>::IsAligned>::run(*this, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \sa operator*(Quaternion) */
|
/** \sa operator*(Quaternion) */
|
||||||
@@ -551,6 +575,7 @@ template<class Derived>
|
|||||||
template<typename Derived1, typename Derived2>
|
template<typename Derived1, typename Derived2>
|
||||||
inline Derived& QuaternionBase<Derived>::setFromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b)
|
inline Derived& QuaternionBase<Derived>::setFromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b)
|
||||||
{
|
{
|
||||||
|
using std::max;
|
||||||
Vector3 v0 = a.normalized();
|
Vector3 v0 = a.normalized();
|
||||||
Vector3 v1 = b.normalized();
|
Vector3 v1 = b.normalized();
|
||||||
Scalar c = v1.dot(v0);
|
Scalar c = v1.dot(v0);
|
||||||
@@ -565,7 +590,7 @@ inline Derived& QuaternionBase<Derived>::setFromTwoVectors(const MatrixBase<Deri
|
|||||||
// which yields a singular value problem
|
// which yields a singular value problem
|
||||||
if (c < Scalar(-1)+NumTraits<Scalar>::dummy_precision())
|
if (c < Scalar(-1)+NumTraits<Scalar>::dummy_precision())
|
||||||
{
|
{
|
||||||
c = std::max<Scalar>(c,-1);
|
c = max<Scalar>(c,-1);
|
||||||
Matrix<Scalar,2,3> m; m << v0.transpose(), v1.transpose();
|
Matrix<Scalar,2,3> m; m << v0.transpose(), v1.transpose();
|
||||||
JacobiSVD<Matrix<Scalar,2,3> > svd(m, ComputeFullV);
|
JacobiSVD<Matrix<Scalar,2,3> > svd(m, ComputeFullV);
|
||||||
Vector3 axis = svd.matrixV().col(2);
|
Vector3 axis = svd.matrixV().col(2);
|
||||||
@@ -625,10 +650,11 @@ template <class OtherDerived>
|
|||||||
inline typename internal::traits<Derived>::Scalar
|
inline typename internal::traits<Derived>::Scalar
|
||||||
QuaternionBase<Derived>::angularDistance(const QuaternionBase<OtherDerived>& other) const
|
QuaternionBase<Derived>::angularDistance(const QuaternionBase<OtherDerived>& other) const
|
||||||
{
|
{
|
||||||
|
using std::acos;
|
||||||
double d = internal::abs(this->dot(other));
|
double d = internal::abs(this->dot(other));
|
||||||
if (d>=1.0)
|
if (d>=1.0)
|
||||||
return Scalar(0);
|
return Scalar(0);
|
||||||
return static_cast<Scalar>(2 * std::acos(d));
|
return static_cast<Scalar>(2 * acos(d));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the spherical linear interpolation between the two quaternions
|
/** \returns the spherical linear interpolation between the two quaternions
|
||||||
@@ -639,6 +665,7 @@ template <class OtherDerived>
|
|||||||
Quaternion<typename internal::traits<Derived>::Scalar>
|
Quaternion<typename internal::traits<Derived>::Scalar>
|
||||||
QuaternionBase<Derived>::slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const
|
QuaternionBase<Derived>::slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const
|
||||||
{
|
{
|
||||||
|
using std::acos;
|
||||||
static const Scalar one = Scalar(1) - NumTraits<Scalar>::epsilon();
|
static const Scalar one = Scalar(1) - NumTraits<Scalar>::epsilon();
|
||||||
Scalar d = this->dot(other);
|
Scalar d = this->dot(other);
|
||||||
Scalar absD = internal::abs(d);
|
Scalar absD = internal::abs(d);
|
||||||
@@ -654,7 +681,7 @@ QuaternionBase<Derived>::slerp(Scalar t, const QuaternionBase<OtherDerived>& oth
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// theta is the angle between the 2 quaternions
|
// theta is the angle between the 2 quaternions
|
||||||
Scalar theta = std::acos(absD);
|
Scalar theta = acos(absD);
|
||||||
Scalar sinTheta = internal::sin(theta);
|
Scalar sinTheta = internal::sin(theta);
|
||||||
|
|
||||||
scale0 = internal::sin( ( Scalar(1) - t ) * theta) / sinTheta;
|
scale0 = internal::sin( ( Scalar(1) - t ) * theta) / sinTheta;
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ struct transform_traits
|
|||||||
|
|
||||||
template< typename TransformType,
|
template< typename TransformType,
|
||||||
typename MatrixType,
|
typename MatrixType,
|
||||||
bool IsProjective = transform_traits<TransformType>::IsProjective>
|
int Case = transform_traits<TransformType>::IsProjective ? 0
|
||||||
|
: int(MatrixType::RowsAtCompileTime) == int(transform_traits<TransformType>::HDim) ? 1
|
||||||
|
: 2>
|
||||||
struct transform_right_product_impl;
|
struct transform_right_product_impl;
|
||||||
|
|
||||||
template< typename Other,
|
template< typename Other,
|
||||||
@@ -81,15 +83,16 @@ template<typename TransformType> struct transform_take_affine_part;
|
|||||||
*
|
*
|
||||||
* \brief Represents an homogeneous transformation in a N dimensional space
|
* \brief Represents an homogeneous transformation in a N dimensional space
|
||||||
*
|
*
|
||||||
* \param _Scalar the scalar type, i.e., the type of the coefficients
|
* \tparam _Scalar the scalar type, i.e., the type of the coefficients
|
||||||
* \param _Dim the dimension of the space
|
* \tparam _Dim the dimension of the space
|
||||||
* \param _Mode the type of the transformation. Can be:
|
* \tparam _Mode the type of the transformation. Can be:
|
||||||
* - Affine: the transformation is stored as a (Dim+1)^2 matrix,
|
* - #Affine: the transformation is stored as a (Dim+1)^2 matrix,
|
||||||
* where the last row is assumed to be [0 ... 0 1].
|
* where the last row is assumed to be [0 ... 0 1].
|
||||||
* - AffineCompact: the transformation is stored as a (Dim)x(Dim+1) matrix.
|
* - #AffineCompact: the transformation is stored as a (Dim)x(Dim+1) matrix.
|
||||||
* - Projective: the transformation is stored as a (Dim+1)^2 matrix
|
* - #Projective: the transformation is stored as a (Dim+1)^2 matrix
|
||||||
* without any assumption.
|
* without any assumption.
|
||||||
* \param _Options can be \b AutoAlign or \b DontAlign. Default is \b AutoAlign
|
* \tparam _Options has the same meaning as in class Matrix. It allows to specify DontAlign and/or RowMajor.
|
||||||
|
* These Options are passed directly to the underlying matrix type.
|
||||||
*
|
*
|
||||||
* The homography is internally represented and stored by a matrix which
|
* The homography is internally represented and stored by a matrix which
|
||||||
* is available through the matrix() method. To understand the behavior of
|
* is available through the matrix() method. To understand the behavior of
|
||||||
@@ -177,6 +180,9 @@ template<typename TransformType> struct transform_take_affine_part;
|
|||||||
* Conversion methods from/to Qt's QMatrix and QTransform are available if the
|
* Conversion methods from/to Qt's QMatrix and QTransform are available if the
|
||||||
* preprocessor token EIGEN_QT_SUPPORT is defined.
|
* preprocessor token EIGEN_QT_SUPPORT is defined.
|
||||||
*
|
*
|
||||||
|
* This class can be extended with the help of the plugin mechanism described on the page
|
||||||
|
* \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_TRANSFORM_PLUGIN.
|
||||||
|
*
|
||||||
* \sa class Matrix, class Quaternion
|
* \sa class Matrix, class Quaternion
|
||||||
*/
|
*/
|
||||||
template<typename _Scalar, int _Dim, int _Mode, int _Options>
|
template<typename _Scalar, int _Dim, int _Mode, int _Options>
|
||||||
@@ -195,11 +201,11 @@ public:
|
|||||||
typedef _Scalar Scalar;
|
typedef _Scalar Scalar;
|
||||||
typedef DenseIndex Index;
|
typedef DenseIndex Index;
|
||||||
/** type of the matrix used to represent the transformation */
|
/** type of the matrix used to represent the transformation */
|
||||||
typedef Matrix<Scalar,Rows,HDim,Options&DontAlign> MatrixType;
|
typedef typename internal::make_proper_matrix_type<Scalar,Rows,HDim,Options>::type MatrixType;
|
||||||
/** constified MatrixType */
|
/** constified MatrixType */
|
||||||
typedef const MatrixType ConstMatrixType;
|
typedef const MatrixType ConstMatrixType;
|
||||||
/** type of the matrix used to represent the linear part of the transformation */
|
/** type of the matrix used to represent the linear part of the transformation */
|
||||||
typedef Matrix<Scalar,Dim,Dim> LinearMatrixType;
|
typedef Matrix<Scalar,Dim,Dim,Options> LinearMatrixType;
|
||||||
/** type of read/write reference to the linear part of the transformation */
|
/** type of read/write reference to the linear part of the transformation */
|
||||||
typedef Block<MatrixType,Dim,Dim> LinearPart;
|
typedef Block<MatrixType,Dim,Dim> LinearPart;
|
||||||
/** type of read reference to the linear part of the transformation */
|
/** type of read reference to the linear part of the transformation */
|
||||||
@@ -517,7 +523,7 @@ public:
|
|||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline Transform operator*(const RotationBase<Derived,Dim>& r) const;
|
inline Transform operator*(const RotationBase<Derived,Dim>& r) const;
|
||||||
|
|
||||||
LinearMatrixType rotation() const;
|
const LinearMatrixType rotation() const;
|
||||||
template<typename RotationMatrixType, typename ScalingMatrixType>
|
template<typename RotationMatrixType, typename ScalingMatrixType>
|
||||||
void computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const;
|
void computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const;
|
||||||
template<typename ScalingMatrixType, typename RotationMatrixType>
|
template<typename ScalingMatrixType, typename RotationMatrixType>
|
||||||
@@ -604,7 +610,7 @@ protected:
|
|||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
EIGEN_STRONG_INLINE static void check_template_params()
|
EIGEN_STRONG_INLINE static void check_template_params()
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT((Options & (DontAlign)) == Options, INVALID_MATRIX_TEMPLATE_PARAMETERS)
|
EIGEN_STATIC_ASSERT((Options & (DontAlign|RowMajor)) == Options, INVALID_MATRIX_TEMPLATE_PARAMETERS)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -666,7 +672,7 @@ Transform<Scalar,Dim,Mode,Options>::Transform(const QMatrix& other)
|
|||||||
*
|
*
|
||||||
* This function is available only if the token EIGEN_QT_SUPPORT is defined.
|
* This function is available only if the token EIGEN_QT_SUPPORT is defined.
|
||||||
*/
|
*/
|
||||||
template<typename Scalar, int Dim, int Mode,int Otpions>
|
template<typename Scalar, int Dim, int Mode,int Options>
|
||||||
Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QMatrix& other)
|
Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QMatrix& other)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||||
@@ -712,9 +718,13 @@ Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator
|
|||||||
{
|
{
|
||||||
check_template_params();
|
check_template_params();
|
||||||
EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||||
m_matrix << other.m11(), other.m21(), other.dx(),
|
if (Mode == int(AffineCompact))
|
||||||
other.m12(), other.m22(), other.dy(),
|
m_matrix << other.m11(), other.m21(), other.dx(),
|
||||||
other.m13(), other.m23(), other.m33();
|
other.m12(), other.m22(), other.dy();
|
||||||
|
else
|
||||||
|
m_matrix << other.m11(), other.m21(), other.dx(),
|
||||||
|
other.m12(), other.m22(), other.dy(),
|
||||||
|
other.m13(), other.m23(), other.m33();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -726,9 +736,14 @@ template<typename Scalar, int Dim, int Mode, int Options>
|
|||||||
QTransform Transform<Scalar,Dim,Mode,Options>::toQTransform(void) const
|
QTransform Transform<Scalar,Dim,Mode,Options>::toQTransform(void) const
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||||
return QTransform(matrix.coeff(0,0), matrix.coeff(1,0), matrix.coeff(2,0)
|
if (Mode == int(AffineCompact))
|
||||||
matrix.coeff(0,1), matrix.coeff(1,1), matrix.coeff(2,1)
|
return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0),
|
||||||
matrix.coeff(0,2), matrix.coeff(1,2), matrix.coeff(2,2));
|
m_matrix.coeff(0,1), m_matrix.coeff(1,1),
|
||||||
|
m_matrix.coeff(0,2), m_matrix.coeff(1,2));
|
||||||
|
else
|
||||||
|
return QTransform(m_matrix.coeff(0,0), m_matrix.coeff(1,0), m_matrix.coeff(2,0),
|
||||||
|
m_matrix.coeff(0,1), m_matrix.coeff(1,1), m_matrix.coeff(2,1),
|
||||||
|
m_matrix.coeff(0,2), m_matrix.coeff(1,2), m_matrix.coeff(2,2));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -964,7 +979,7 @@ inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::op
|
|||||||
* \sa computeRotationScaling(), computeScalingRotation(), class SVD
|
* \sa computeRotationScaling(), computeScalingRotation(), class SVD
|
||||||
*/
|
*/
|
||||||
template<typename Scalar, int Dim, int Mode, int Options>
|
template<typename Scalar, int Dim, int Mode, int Options>
|
||||||
typename Transform<Scalar,Dim,Mode,Options>::LinearMatrixType
|
const typename Transform<Scalar,Dim,Mode,Options>::LinearMatrixType
|
||||||
Transform<Scalar,Dim,Mode,Options>::rotation() const
|
Transform<Scalar,Dim,Mode,Options>::rotation() const
|
||||||
{
|
{
|
||||||
LinearMatrixType result;
|
LinearMatrixType result;
|
||||||
@@ -1076,10 +1091,10 @@ struct projective_transform_inverse<TransformType, Projective>
|
|||||||
*
|
*
|
||||||
* \param hint allows to optimize the inversion process when the transformation
|
* \param hint allows to optimize the inversion process when the transformation
|
||||||
* is known to be not a general transformation (optional). The possible values are:
|
* is known to be not a general transformation (optional). The possible values are:
|
||||||
* - Projective if the transformation is not necessarily affine, i.e., if the
|
* - #Projective if the transformation is not necessarily affine, i.e., if the
|
||||||
* last row is not guaranteed to be [0 ... 0 1]
|
* last row is not guaranteed to be [0 ... 0 1]
|
||||||
* - Affine if the last row can be assumed to be [0 ... 0 1]
|
* - #Affine if the last row can be assumed to be [0 ... 0 1]
|
||||||
* - Isometry if the transformation is only a concatenations of translations
|
* - #Isometry if the transformation is only a concatenations of translations
|
||||||
* and rotations.
|
* and rotations.
|
||||||
* The default is the template class parameter \c Mode.
|
* The default is the template class parameter \c Mode.
|
||||||
*
|
*
|
||||||
@@ -1136,9 +1151,9 @@ template<typename TransformType> struct transform_take_affine_part {
|
|||||||
{ return m.template block<TransformType::Dim,TransformType::HDim>(0,0); }
|
{ return m.template block<TransformType::Dim,TransformType::HDim>(0,0); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Scalar, int Dim>
|
template<typename Scalar, int Dim, int Options>
|
||||||
struct transform_take_affine_part<Transform<Scalar,Dim,AffineCompact> > {
|
struct transform_take_affine_part<Transform<Scalar,Dim,AffineCompact, Options> > {
|
||||||
typedef typename Transform<Scalar,Dim,AffineCompact>::MatrixType MatrixType;
|
typedef typename Transform<Scalar,Dim,AffineCompact,Options>::MatrixType MatrixType;
|
||||||
static inline MatrixType& run(MatrixType& m) { return m; }
|
static inline MatrixType& run(MatrixType& m) { return m; }
|
||||||
static inline const MatrixType& run(const MatrixType& m) { return m; }
|
static inline const MatrixType& run(const MatrixType& m) { return m; }
|
||||||
};
|
};
|
||||||
@@ -1178,7 +1193,7 @@ struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, HDim,HDim>
|
|||||||
template<typename Other, int Options, int Dim, int HDim>
|
template<typename Other, int Options, int Dim, int HDim>
|
||||||
struct transform_construct_from_matrix<Other, AffineCompact,Options,Dim,HDim, HDim,HDim>
|
struct transform_construct_from_matrix<Other, AffineCompact,Options,Dim,HDim, HDim,HDim>
|
||||||
{
|
{
|
||||||
static inline void run(Transform<typename Other::Scalar,Dim,AffineCompact> *transform, const Other& other)
|
static inline void run(Transform<typename Other::Scalar,Dim,AffineCompact,Options> *transform, const Other& other)
|
||||||
{ transform->matrix() = other.template block<Dim,HDim>(0,0); }
|
{ transform->matrix() = other.template block<Dim,HDim>(0,0); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1200,7 +1215,7 @@ struct transform_product_result
|
|||||||
};
|
};
|
||||||
|
|
||||||
template< typename TransformType, typename MatrixType >
|
template< typename TransformType, typename MatrixType >
|
||||||
struct transform_right_product_impl< TransformType, MatrixType, true >
|
struct transform_right_product_impl< TransformType, MatrixType, 0 >
|
||||||
{
|
{
|
||||||
typedef typename MatrixType::PlainObject ResultType;
|
typedef typename MatrixType::PlainObject ResultType;
|
||||||
|
|
||||||
@@ -1211,7 +1226,7 @@ struct transform_right_product_impl< TransformType, MatrixType, true >
|
|||||||
};
|
};
|
||||||
|
|
||||||
template< typename TransformType, typename MatrixType >
|
template< typename TransformType, typename MatrixType >
|
||||||
struct transform_right_product_impl< TransformType, MatrixType, false >
|
struct transform_right_product_impl< TransformType, MatrixType, 1 >
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
Dim = TransformType::Dim,
|
Dim = TransformType::Dim,
|
||||||
@@ -1224,20 +1239,39 @@ struct transform_right_product_impl< TransformType, MatrixType, false >
|
|||||||
|
|
||||||
EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other)
|
EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT(OtherRows==Dim || OtherRows==HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
|
EIGEN_STATIC_ASSERT(OtherRows==HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
|
||||||
|
|
||||||
typedef Block<ResultType, Dim, OtherCols> TopLeftLhs;
|
typedef Block<ResultType, Dim, OtherCols> TopLeftLhs;
|
||||||
typedef Block<const MatrixType, Dim, OtherCols> TopLeftRhs;
|
|
||||||
|
|
||||||
ResultType res(other.rows(),other.cols());
|
ResultType res(other.rows(),other.cols());
|
||||||
|
TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.affine() * other;
|
||||||
|
res.row(OtherRows-1) = other.row(OtherRows-1);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
TopLeftLhs(res, 0, 0, Dim, other.cols()) =
|
template< typename TransformType, typename MatrixType >
|
||||||
( T.linear() * TopLeftRhs(other, 0, 0, Dim, other.cols()) ).colwise() +
|
struct transform_right_product_impl< TransformType, MatrixType, 2 >
|
||||||
T.translation();
|
{
|
||||||
|
enum {
|
||||||
|
Dim = TransformType::Dim,
|
||||||
|
HDim = TransformType::HDim,
|
||||||
|
OtherRows = MatrixType::RowsAtCompileTime,
|
||||||
|
OtherCols = MatrixType::ColsAtCompileTime
|
||||||
|
};
|
||||||
|
|
||||||
// we need to take .rows() because OtherRows might be Dim or HDim
|
typedef typename MatrixType::PlainObject ResultType;
|
||||||
if (OtherRows==HDim)
|
|
||||||
res.row(other.rows()) = other.row(other.rows());
|
EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other)
|
||||||
|
{
|
||||||
|
EIGEN_STATIC_ASSERT(OtherRows==Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
|
||||||
|
|
||||||
|
typedef Block<ResultType, Dim, OtherCols> TopLeftLhs;
|
||||||
|
|
||||||
|
ResultType res(other.rows(),other.cols());
|
||||||
|
TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.linear() * other;
|
||||||
|
TopLeftLhs(res, 0, 0, Dim, other.cols()).colwise() += T.translation();
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,8 +72,9 @@ void MatrixBase<Derived>::makeHouseholder(
|
|||||||
|
|
||||||
if(tailSqNorm == RealScalar(0) && internal::imag(c0)==RealScalar(0))
|
if(tailSqNorm == RealScalar(0) && internal::imag(c0)==RealScalar(0))
|
||||||
{
|
{
|
||||||
tau = 0;
|
tau = RealScalar(0);
|
||||||
beta = internal::real(c0);
|
beta = internal::real(c0);
|
||||||
|
essential.setZero();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -104,9 +104,9 @@ bool JacobiRotation<Scalar>::makeJacobi(RealScalar x, Scalar y, RealScalar z)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
RealScalar tau = (x-z)/(RealScalar(2)*internal::abs(y));
|
RealScalar tau = (x-z)/(RealScalar(2)*internal::abs(y));
|
||||||
RealScalar w = internal::sqrt(internal::abs2(tau) + 1);
|
RealScalar w = internal::sqrt(internal::abs2(tau) + RealScalar(1));
|
||||||
RealScalar t;
|
RealScalar t;
|
||||||
if(tau>0)
|
if(tau>RealScalar(0))
|
||||||
{
|
{
|
||||||
t = RealScalar(1) / (tau + w);
|
t = RealScalar(1) / (tau + w);
|
||||||
}
|
}
|
||||||
@@ -114,8 +114,8 @@ bool JacobiRotation<Scalar>::makeJacobi(RealScalar x, Scalar y, RealScalar z)
|
|||||||
{
|
{
|
||||||
t = RealScalar(1) / (tau - w);
|
t = RealScalar(1) / (tau - w);
|
||||||
}
|
}
|
||||||
RealScalar sign_t = t > 0 ? 1 : -1;
|
RealScalar sign_t = t > RealScalar(0) ? RealScalar(1) : RealScalar(-1);
|
||||||
RealScalar n = RealScalar(1) / internal::sqrt(internal::abs2(t)+1);
|
RealScalar n = RealScalar(1) / internal::sqrt(internal::abs2(t)+RealScalar(1));
|
||||||
m_s = - sign_t * (internal::conj(y) / internal::abs(y)) * internal::abs(t) * n;
|
m_s = - sign_t * (internal::conj(y) / internal::abs(y)) * internal::abs(t) * n;
|
||||||
m_c = n;
|
m_c = n;
|
||||||
return true;
|
return true;
|
||||||
@@ -221,15 +221,15 @@ template<typename Scalar>
|
|||||||
void JacobiRotation<Scalar>::makeGivens(const Scalar& p, const Scalar& q, Scalar* r, internal::false_type)
|
void JacobiRotation<Scalar>::makeGivens(const Scalar& p, const Scalar& q, Scalar* r, internal::false_type)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(q==0)
|
if(q==Scalar(0))
|
||||||
{
|
{
|
||||||
m_c = p<Scalar(0) ? Scalar(-1) : Scalar(1);
|
m_c = p<Scalar(0) ? Scalar(-1) : Scalar(1);
|
||||||
m_s = 0;
|
m_s = Scalar(0);
|
||||||
if(r) *r = internal::abs(p);
|
if(r) *r = internal::abs(p);
|
||||||
}
|
}
|
||||||
else if(p==0)
|
else if(p==Scalar(0))
|
||||||
{
|
{
|
||||||
m_c = 0;
|
m_c = Scalar(0);
|
||||||
m_s = q<Scalar(0) ? Scalar(1) : Scalar(-1);
|
m_s = q<Scalar(0) ? Scalar(1) : Scalar(-1);
|
||||||
if(r) *r = internal::abs(q);
|
if(r) *r = internal::abs(q);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -533,7 +533,7 @@ template<typename MatrixType>
|
|||||||
MatrixType FullPivLU<MatrixType>::reconstructedMatrix() const
|
MatrixType FullPivLU<MatrixType>::reconstructedMatrix() const
|
||||||
{
|
{
|
||||||
eigen_assert(m_isInitialized && "LU is not initialized.");
|
eigen_assert(m_isInitialized && "LU is not initialized.");
|
||||||
const Index smalldim = std::min(m_lu.rows(), m_lu.cols());
|
const Index smalldim = (std::min)(m_lu.rows(), m_lu.cols());
|
||||||
// LU
|
// LU
|
||||||
MatrixType res(m_lu.rows(),m_lu.cols());
|
MatrixType res(m_lu.rows(),m_lu.cols());
|
||||||
// FIXME the .toDenseMatrix() should not be needed...
|
// FIXME the .toDenseMatrix() should not be needed...
|
||||||
@@ -695,7 +695,7 @@ struct solve_retval<FullPivLU<_MatrixType>, Rhs>
|
|||||||
const Index rows = dec().rows(), cols = dec().cols(),
|
const Index rows = dec().rows(), cols = dec().cols(),
|
||||||
nonzero_pivots = dec().nonzeroPivots();
|
nonzero_pivots = dec().nonzeroPivots();
|
||||||
eigen_assert(rhs().rows() == rows);
|
eigen_assert(rhs().rows() == rows);
|
||||||
const Index smalldim = std::min(rows, cols);
|
const Index smalldim = (std::min)(rows, cols);
|
||||||
|
|
||||||
if(nonzero_pivots == 0)
|
if(nonzero_pivots == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ struct partial_lu_impl
|
|||||||
{
|
{
|
||||||
const Index rows = lu.rows();
|
const Index rows = lu.rows();
|
||||||
const Index cols = lu.cols();
|
const Index cols = lu.cols();
|
||||||
const Index size = std::min(rows,cols);
|
const Index size = (std::min)(rows,cols);
|
||||||
nb_transpositions = 0;
|
nb_transpositions = 0;
|
||||||
int first_zero_pivot = -1;
|
int first_zero_pivot = -1;
|
||||||
for(Index k = 0; k < size; ++k)
|
for(Index k = 0; k < size; ++k)
|
||||||
@@ -268,7 +268,7 @@ struct partial_lu_impl
|
|||||||
|
|
||||||
row_transpositions[k] = row_of_biggest_in_col;
|
row_transpositions[k] = row_of_biggest_in_col;
|
||||||
|
|
||||||
if(biggest_in_corner != 0)
|
if(biggest_in_corner != RealScalar(0))
|
||||||
{
|
{
|
||||||
if(k != row_of_biggest_in_col)
|
if(k != row_of_biggest_in_col)
|
||||||
{
|
{
|
||||||
@@ -313,7 +313,7 @@ struct partial_lu_impl
|
|||||||
MapLU lu1(lu_data,StorageOrder==RowMajor?rows:luStride,StorageOrder==RowMajor?luStride:cols);
|
MapLU lu1(lu_data,StorageOrder==RowMajor?rows:luStride,StorageOrder==RowMajor?luStride:cols);
|
||||||
MatrixType lu(lu1,0,0,rows,cols);
|
MatrixType lu(lu1,0,0,rows,cols);
|
||||||
|
|
||||||
const Index size = std::min(rows,cols);
|
const Index size = (std::min)(rows,cols);
|
||||||
|
|
||||||
// if the matrix is too small, no blocking:
|
// if the matrix is too small, no blocking:
|
||||||
if(size<=16)
|
if(size<=16)
|
||||||
@@ -327,14 +327,14 @@ struct partial_lu_impl
|
|||||||
{
|
{
|
||||||
blockSize = size/8;
|
blockSize = size/8;
|
||||||
blockSize = (blockSize/16)*16;
|
blockSize = (blockSize/16)*16;
|
||||||
blockSize = std::min(std::max(blockSize,Index(8)), maxBlockSize);
|
blockSize = (std::min)((std::max)(blockSize,Index(8)), maxBlockSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
nb_transpositions = 0;
|
nb_transpositions = 0;
|
||||||
int first_zero_pivot = -1;
|
int first_zero_pivot = -1;
|
||||||
for(Index k = 0; k < size; k+=blockSize)
|
for(Index k = 0; k < size; k+=blockSize)
|
||||||
{
|
{
|
||||||
Index bs = std::min(size-k,blockSize); // actual size of the block
|
Index bs = (std::min)(size-k,blockSize); // actual size of the block
|
||||||
Index trows = rows - k - bs; // trailing rows
|
Index trows = rows - k - bs; // trailing rows
|
||||||
Index tsize = size - k - bs; // trailing size
|
Index tsize = size - k - bs; // trailing size
|
||||||
|
|
||||||
|
|||||||
@@ -182,8 +182,8 @@ struct compute_inverse_size4<Architecture::SSE, double, MatrixType, ResultType>
|
|||||||
};
|
};
|
||||||
static void run(const MatrixType& matrix, ResultType& result)
|
static void run(const MatrixType& matrix, ResultType& result)
|
||||||
{
|
{
|
||||||
const EIGEN_ALIGN16 long long int _Sign_NP[2] = { 0x8000000000000000ll, 0x0000000000000000ll };
|
const __m128d _Sign_NP = _mm_castsi128_pd(_mm_set_epi32(0x0,0x0,0x80000000,0x0));
|
||||||
const EIGEN_ALIGN16 long long int _Sign_PN[2] = { 0x0000000000000000ll, 0x8000000000000000ll };
|
const __m128d _Sign_PN = _mm_castsi128_pd(_mm_set_epi32(0x80000000,0x0,0x0,0x0));
|
||||||
|
|
||||||
// The inverse is calculated using "Divide and Conquer" technique. The
|
// The inverse is calculated using "Divide and Conquer" technique. The
|
||||||
// original matrix is divide into four 2x2 sub-matrices. Since each
|
// original matrix is divide into four 2x2 sub-matrices. Since each
|
||||||
@@ -316,8 +316,8 @@ struct compute_inverse_size4<Architecture::SSE, double, MatrixType, ResultType>
|
|||||||
iB1 = _mm_sub_pd(_mm_mul_pd(C1, dB), iB1);
|
iB1 = _mm_sub_pd(_mm_mul_pd(C1, dB), iB1);
|
||||||
iB2 = _mm_sub_pd(_mm_mul_pd(C2, dB), iB2);
|
iB2 = _mm_sub_pd(_mm_mul_pd(C2, dB), iB2);
|
||||||
|
|
||||||
d1 = _mm_xor_pd(rd, _mm_load_pd((double*)_Sign_PN));
|
d1 = _mm_xor_pd(rd, _Sign_PN);
|
||||||
d2 = _mm_xor_pd(rd, _mm_load_pd((double*)_Sign_NP));
|
d2 = _mm_xor_pd(rd, _Sign_NP);
|
||||||
|
|
||||||
// iC = B*|C| - A*C#*D;
|
// iC = B*|C| - A*C#*D;
|
||||||
dC = _mm_shuffle_pd(dC,dC,0);
|
dC = _mm_shuffle_pd(dC,dC,0);
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ template<typename _MatrixType> class ColPivHouseholderQR
|
|||||||
*/
|
*/
|
||||||
ColPivHouseholderQR(Index rows, Index cols)
|
ColPivHouseholderQR(Index rows, Index cols)
|
||||||
: m_qr(rows, cols),
|
: m_qr(rows, cols),
|
||||||
m_hCoeffs(std::min(rows,cols)),
|
m_hCoeffs((std::min)(rows,cols)),
|
||||||
m_colsPermutation(cols),
|
m_colsPermutation(cols),
|
||||||
m_colsTranspositions(cols),
|
m_colsTranspositions(cols),
|
||||||
m_temp(cols),
|
m_temp(cols),
|
||||||
@@ -103,7 +103,7 @@ template<typename _MatrixType> class ColPivHouseholderQR
|
|||||||
|
|
||||||
ColPivHouseholderQR(const MatrixType& matrix)
|
ColPivHouseholderQR(const MatrixType& matrix)
|
||||||
: m_qr(matrix.rows(), matrix.cols()),
|
: m_qr(matrix.rows(), matrix.cols()),
|
||||||
m_hCoeffs(std::min(matrix.rows(),matrix.cols())),
|
m_hCoeffs((std::min)(matrix.rows(),matrix.cols())),
|
||||||
m_colsPermutation(matrix.cols()),
|
m_colsPermutation(matrix.cols()),
|
||||||
m_colsTranspositions(matrix.cols()),
|
m_colsTranspositions(matrix.cols()),
|
||||||
m_temp(matrix.cols()),
|
m_temp(matrix.cols()),
|
||||||
@@ -330,12 +330,12 @@ template<typename _MatrixType> class ColPivHouseholderQR
|
|||||||
*/
|
*/
|
||||||
inline Index nonzeroPivots() const
|
inline Index nonzeroPivots() const
|
||||||
{
|
{
|
||||||
eigen_assert(m_isInitialized && "LU is not initialized.");
|
eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
||||||
return m_nonzero_pivots;
|
return m_nonzero_pivots;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the absolute value of the biggest pivot, i.e. the biggest
|
/** \returns the absolute value of the biggest pivot, i.e. the biggest
|
||||||
* diagonal coefficient of U.
|
* diagonal coefficient of R.
|
||||||
*/
|
*/
|
||||||
RealScalar maxPivot() const { return m_maxpivot; }
|
RealScalar maxPivot() const { return m_maxpivot; }
|
||||||
|
|
||||||
@@ -387,7 +387,7 @@ ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const
|
|||||||
for(Index k = 0; k < cols; ++k)
|
for(Index k = 0; k < cols; ++k)
|
||||||
m_colSqNorms.coeffRef(k) = m_qr.col(k).squaredNorm();
|
m_colSqNorms.coeffRef(k) = m_qr.col(k).squaredNorm();
|
||||||
|
|
||||||
RealScalar threshold_helper = m_colSqNorms.maxCoeff() * internal::abs2(NumTraits<Scalar>::epsilon()) / rows;
|
RealScalar threshold_helper = m_colSqNorms.maxCoeff() * internal::abs2(NumTraits<Scalar>::epsilon()) / RealScalar(rows);
|
||||||
|
|
||||||
m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
|
m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
|
||||||
m_maxpivot = RealScalar(0);
|
m_maxpivot = RealScalar(0);
|
||||||
@@ -413,7 +413,7 @@ ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const
|
|||||||
// Note that here, if we test instead for "biggest == 0", we get a failure every 1000 (or so)
|
// Note that here, if we test instead for "biggest == 0", we get a failure every 1000 (or so)
|
||||||
// repetitions of the unit test, with the result of solve() filled with large values of the order
|
// repetitions of the unit test, with the result of solve() filled with large values of the order
|
||||||
// of 1/(size*epsilon).
|
// of 1/(size*epsilon).
|
||||||
if(biggest_col_sq_norm < threshold_helper * (rows-k))
|
if(biggest_col_sq_norm < threshold_helper * RealScalar(rows-k))
|
||||||
{
|
{
|
||||||
m_nonzero_pivots = k;
|
m_nonzero_pivots = k;
|
||||||
m_hCoeffs.tail(size-k).setZero();
|
m_hCoeffs.tail(size-k).setZero();
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user