mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-07-20 11:54:27 +08:00
merge with default branch
This commit is contained in:
commit
eaaba30cac
@ -12,7 +12,7 @@ core
|
|||||||
core.*
|
core.*
|
||||||
*.bak
|
*.bak
|
||||||
*~
|
*~
|
||||||
build
|
build*
|
||||||
*.moc.*
|
*.moc.*
|
||||||
*.moc
|
*.moc
|
||||||
ui_*
|
ui_*
|
||||||
|
@ -3,18 +3,18 @@ project(Eigen)
|
|||||||
cmake_minimum_required(VERSION 2.6.2)
|
cmake_minimum_required(VERSION 2.6.2)
|
||||||
|
|
||||||
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||||
message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there.")
|
message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. (you may need to remove CMakeCache.txt ")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# automatically parse the version number
|
# automatically parse the version number
|
||||||
file(READ "${CMAKE_SOURCE_DIR}/Eigen/src/Core/util/Macros.h" _eigen2_version_header)
|
file(READ "${CMAKE_SOURCE_DIR}/Eigen/src/Core/util/Macros.h" _eigen_version_header)
|
||||||
string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen2_world_version_match "${_eigen2_version_header}")
|
string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen_world_version_match "${_eigen_version_header}")
|
||||||
set(EIGEN2_WORLD_VERSION "${CMAKE_MATCH_1}")
|
set(EIGEN_WORLD_VERSION "${CMAKE_MATCH_1}")
|
||||||
string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen2_major_version_match "${_eigen2_version_header}")
|
string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen_major_version_match "${_eigen_version_header}")
|
||||||
set(EIGEN2_MAJOR_VERSION "${CMAKE_MATCH_1}")
|
set(EIGEN_MAJOR_VERSION "${CMAKE_MATCH_1}")
|
||||||
string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen2_minor_version_match "${_eigen2_version_header}")
|
string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen_minor_version_match "${_eigen_version_header}")
|
||||||
set(EIGEN2_MINOR_VERSION "${CMAKE_MATCH_1}")
|
set(EIGEN_MINOR_VERSION "${CMAKE_MATCH_1}")
|
||||||
set(EIGEN_VERSION_NUMBER ${EIGEN2_WORLD_VERSION}.${EIGEN2_MAJOR_VERSION}.${EIGEN2_MINOR_VERSION})
|
set(EIGEN_VERSION_NUMBER ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})
|
||||||
|
|
||||||
# if the mercurial program is absent, this will leave the EIGEN_HG_CHANGESET string empty,
|
# if the mercurial program is absent, this will leave the EIGEN_HG_CHANGESET string empty,
|
||||||
# but won't stop CMake.
|
# but won't stop CMake.
|
||||||
@ -63,31 +63,43 @@ if(CMAKE_COMPILER_IS_GNUCXX)
|
|||||||
|
|
||||||
if(NOT EIGEN_TEST_LIB)
|
if(NOT EIGEN_TEST_LIB)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
|
||||||
endif(NOT EIGEN_TEST_LIB)
|
endif()
|
||||||
|
|
||||||
option(EIGEN_TEST_SSE2 "Enable/Disable SSE2 in tests/examples" OFF)
|
option(EIGEN_TEST_SSE2 "Enable/Disable SSE2 in tests/examples" OFF)
|
||||||
if(EIGEN_TEST_SSE2)
|
if(EIGEN_TEST_SSE2)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2")
|
||||||
message("Enabling SSE2 in tests/examples")
|
message("Enabling SSE2 in tests/examples")
|
||||||
endif(EIGEN_TEST_SSE2)
|
endif()
|
||||||
|
|
||||||
option(EIGEN_TEST_SSE3 "Enable/Disable SSE3 in tests/examples" OFF)
|
option(EIGEN_TEST_SSE3 "Enable/Disable SSE3 in tests/examples" OFF)
|
||||||
if(EIGEN_TEST_SSE3)
|
if(EIGEN_TEST_SSE3)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse3")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse3")
|
||||||
message("Enabling SSE3 in tests/examples")
|
message("Enabling SSE3 in tests/examples")
|
||||||
endif(EIGEN_TEST_SSE3)
|
endif()
|
||||||
|
|
||||||
option(EIGEN_TEST_SSSE3 "Enable/Disable SSSE3 in tests/examples" OFF)
|
option(EIGEN_TEST_SSSE3 "Enable/Disable SSSE3 in tests/examples" OFF)
|
||||||
if(EIGEN_TEST_SSSE3)
|
if(EIGEN_TEST_SSSE3)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mssse3")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mssse3")
|
||||||
message("Enabling SSSE3 in tests/examples")
|
message("Enabling SSSE3 in tests/examples")
|
||||||
endif(EIGEN_TEST_SSSE3)
|
endif()
|
||||||
|
|
||||||
|
option(EIGEN_TEST_SSE4_1 "Enable/Disable SSE4.1 in tests/examples" OFF)
|
||||||
|
if(EIGEN_TEST_SSE4_1)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1")
|
||||||
|
message("Enabling SSE4.1 in tests/examples")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
option(EIGEN_TEST_SSE4_2 "Enable/Disable SSE4.2 in tests/examples" OFF)
|
||||||
|
if(EIGEN_TEST_SSE4_2)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.2")
|
||||||
|
message("Enabling SSE4.2 in tests/examples")
|
||||||
|
endif()
|
||||||
|
|
||||||
option(EIGEN_TEST_ALTIVEC "Enable/Disable altivec in tests/examples" OFF)
|
option(EIGEN_TEST_ALTIVEC "Enable/Disable altivec in tests/examples" OFF)
|
||||||
if(EIGEN_TEST_ALTIVEC)
|
if(EIGEN_TEST_ALTIVEC)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maltivec -mabi=altivec")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maltivec -mabi=altivec")
|
||||||
message("Enabling AltiVec in tests/examples")
|
message("Enabling AltiVec in tests/examples")
|
||||||
endif(EIGEN_TEST_ALTIVEC)
|
endif()
|
||||||
|
|
||||||
endif(CMAKE_SYSTEM_NAME MATCHES Linux)
|
endif(CMAKE_SYSTEM_NAME MATCHES Linux)
|
||||||
endif(CMAKE_COMPILER_IS_GNUCXX)
|
endif(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
@ -112,19 +124,25 @@ endif(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)
|
|||||||
|
|
||||||
option(EIGEN_TEST_C++0x "Enables all C++0x features." OFF)
|
option(EIGEN_TEST_C++0x "Enables all C++0x features." OFF)
|
||||||
|
|
||||||
option(EIGEN_TEST_RVALUE_REF_SUPPORT "Enable rvalue references for unit tests." OFF)
|
option(EIGEN_TEST_MAX_WARNING_LEVEL "Sets the warning level to /Wall while building the unit tests." OFF)
|
||||||
|
mark_as_advanced(EIGEN_TEST_MAX_WARNING_LEVEL)
|
||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
set(INCLUDE_INSTALL_DIR
|
set(INCLUDE_INSTALL_DIR
|
||||||
"${CMAKE_INSTALL_PREFIX}/include/eigen2"
|
"${CMAKE_INSTALL_PREFIX}/include/eigen3"
|
||||||
CACHE PATH
|
CACHE PATH
|
||||||
"The directory where we install the header files"
|
"The directory where we install the header files"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
install(FILES
|
||||||
|
signature_of_eigen3_matrix_library
|
||||||
|
DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel
|
||||||
|
)
|
||||||
|
|
||||||
if(EIGEN_BUILD_PKGCONFIG)
|
if(EIGEN_BUILD_PKGCONFIG)
|
||||||
configure_file(eigen2.pc.in eigen2.pc)
|
configure_file(eigen3.pc.in eigen3.pc)
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/eigen2.pc
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/eigen3.pc
|
||||||
DESTINATION share/pkgconfig
|
DESTINATION share/pkgconfig
|
||||||
)
|
)
|
||||||
endif(EIGEN_BUILD_PKGCONFIG)
|
endif(EIGEN_BUILD_PKGCONFIG)
|
||||||
@ -135,6 +153,9 @@ add_subdirectory(doc EXCLUDE_FROM_ALL)
|
|||||||
|
|
||||||
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)
|
||||||
|
ei_init_testing()
|
||||||
|
|
||||||
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()
|
||||||
@ -147,6 +168,7 @@ add_subdirectory(demos EXCLUDE_FROM_ALL)
|
|||||||
|
|
||||||
add_subdirectory(blas EXCLUDE_FROM_ALL)
|
add_subdirectory(blas EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
# must be after test and unsupported, for configuring buildtests.in
|
||||||
add_subdirectory(scripts EXCLUDE_FROM_ALL)
|
add_subdirectory(scripts EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
# TODO: consider also replacing EIGEN_BUILD_BTL by a custom target "make btl"?
|
# TODO: consider also replacing EIGEN_BUILD_BTL by a custom target "make btl"?
|
||||||
|
@ -45,3 +45,5 @@ namespace Eigen {
|
|||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/EnableMSVCWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_ARRAY_MODULE_H
|
#endif // EIGEN_ARRAY_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
set(Eigen_HEADERS Core LU Cholesky QR Geometry Sparse Array SVD LeastSquares QtAlignedMalloc StdVector Householder Jacobi Eigenvalues)
|
file(GLOB Eigen_directory_files "*")
|
||||||
|
foreach(f ${Eigen_directory_files})
|
||||||
|
if(NOT f MATCHES ".txt" AND NOT f MATCHES "src")
|
||||||
|
list(APPEND Eigen_directory_files_to_install ${f})
|
||||||
|
endif()
|
||||||
|
endforeach(f ${Eigen_directory_files})
|
||||||
|
|
||||||
install(FILES
|
install(FILES
|
||||||
${Eigen_HEADERS}
|
${Eigen_directory_files_to_install}
|
||||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen COMPONENT Devel
|
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen COMPONENT Devel
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -63,3 +63,4 @@ namespace Eigen {
|
|||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/EnableMSVCWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_CHOLESKY_MODULE_H
|
#endif // EIGEN_CHOLESKY_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
@ -71,6 +71,12 @@
|
|||||||
#ifdef __SSSE3__
|
#ifdef __SSSE3__
|
||||||
#include <tmmintrin.h>
|
#include <tmmintrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __SSE4_1__
|
||||||
|
#include <smmintrin.h>
|
||||||
|
#endif
|
||||||
|
#ifdef __SSE4_2__
|
||||||
|
#include <nmmintrin.h>
|
||||||
|
#endif
|
||||||
#elif defined __ALTIVEC__
|
#elif defined __ALTIVEC__
|
||||||
#define EIGEN_VECTORIZE
|
#define EIGEN_VECTORIZE
|
||||||
#define EIGEN_VECTORIZE_ALTIVEC
|
#define EIGEN_VECTORIZE_ALTIVEC
|
||||||
@ -216,3 +222,4 @@ struct Dense {};
|
|||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/EnableMSVCWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_CORE_H
|
#endif // EIGEN_CORE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
@ -73,3 +73,4 @@ namespace Eigen {
|
|||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/EnableMSVCWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_EIGENVALUES_MODULE_H
|
#endif // EIGEN_EIGENVALUES_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
@ -57,3 +57,5 @@ namespace Eigen {
|
|||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/EnableMSVCWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_GEOMETRY_MODULE_H
|
#endif // EIGEN_GEOMETRY_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
/** \defgroup Householder_Module Householder module
|
/** \defgroup Householder_Module Householder module
|
||||||
* This module provides householder transformations.
|
* This module provides Householder transformations.
|
||||||
*
|
*
|
||||||
* \code
|
* \code
|
||||||
* #include <Eigen/Householder>
|
* #include <Eigen/Householder>
|
||||||
@ -23,3 +23,4 @@ namespace Eigen {
|
|||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/EnableMSVCWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_HOUSEHOLDER_MODULE_H
|
#endif // EIGEN_HOUSEHOLDER_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
@ -26,3 +26,5 @@ namespace Eigen {
|
|||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/EnableMSVCWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_JACOBI_MODULE_H
|
#endif // EIGEN_JACOBI_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|
||||||
|
5
Eigen/LU
5
Eigen/LU
@ -26,8 +26,13 @@ namespace Eigen {
|
|||||||
#include "src/LU/Determinant.h"
|
#include "src/LU/Determinant.h"
|
||||||
#include "src/LU/Inverse.h"
|
#include "src/LU/Inverse.h"
|
||||||
|
|
||||||
|
#if defined EIGEN_VECTORIZE_SSE
|
||||||
|
#include "src/LU/arch/Inverse_SSE.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace Eigen
|
} // namespace Eigen
|
||||||
|
|
||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/EnableMSVCWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_LU_MODULE_H
|
#endif // EIGEN_LU_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
@ -25,3 +25,4 @@ namespace Eigen {
|
|||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/EnableMSVCWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_REGRESSION_MODULE_H
|
#endif // EIGEN_REGRESSION_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
1
Eigen/QR
1
Eigen/QR
@ -67,3 +67,4 @@ namespace Eigen {
|
|||||||
#include "Eigenvalues"
|
#include "Eigenvalues"
|
||||||
|
|
||||||
#endif // EIGEN_QR_MODULE_H
|
#endif // EIGEN_QR_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
@ -31,3 +31,4 @@ void *qRealloc(void *ptr, size_t size)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // EIGEN_QTMALLOC_MODULE_H
|
#endif // EIGEN_QTMALLOC_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
@ -31,3 +31,4 @@ namespace Eigen {
|
|||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/EnableMSVCWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_SVD_MODULE_H
|
#endif // EIGEN_SVD_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
@ -87,7 +87,6 @@ struct Sparse {};
|
|||||||
|
|
||||||
#include "src/Sparse/SparseUtil.h"
|
#include "src/Sparse/SparseUtil.h"
|
||||||
#include "src/Sparse/SparseMatrixBase.h"
|
#include "src/Sparse/SparseMatrixBase.h"
|
||||||
#include "src/Sparse/SparseNestByValue.h"
|
|
||||||
#include "src/Sparse/CompressedStorage.h"
|
#include "src/Sparse/CompressedStorage.h"
|
||||||
#include "src/Sparse/AmbiVector.h"
|
#include "src/Sparse/AmbiVector.h"
|
||||||
#include "src/Sparse/RandomSetter.h"
|
#include "src/Sparse/RandomSetter.h"
|
||||||
@ -134,3 +133,5 @@ struct Sparse {};
|
|||||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
#include "src/Core/util/EnableMSVCWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_SPARSE_MODULE_H
|
#endif // EIGEN_SPARSE_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|
||||||
|
@ -166,3 +166,5 @@ class vector<T,Eigen::aligned_allocator<T> >
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif // EIGEN_STDVECTOR_MODULE_H
|
#endif // EIGEN_STDVECTOR_MODULE_H
|
||||||
|
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||||
|
|
||||||
|
@ -56,7 +56,8 @@ struct ei_functor_traits<ei_scalar_add_op<Scalar> >
|
|||||||
*
|
*
|
||||||
* \sa class CwiseUnaryOp, Cwise::sqrt()
|
* \sa class CwiseUnaryOp, Cwise::sqrt()
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_sqrt_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_sqrt_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_sqrt_op)
|
||||||
inline const Scalar operator() (const Scalar& a) const { return ei_sqrt(a); }
|
inline const Scalar operator() (const Scalar& a) const { return ei_sqrt(a); }
|
||||||
typedef typename ei_packet_traits<Scalar>::type Packet;
|
typedef typename ei_packet_traits<Scalar>::type Packet;
|
||||||
inline Packet packetOp(const Packet& a) const { return ei_psqrt(a); }
|
inline Packet packetOp(const Packet& a) const { return ei_psqrt(a); }
|
||||||
@ -77,7 +78,8 @@ struct ei_functor_traits<ei_scalar_sqrt_op<Scalar> >
|
|||||||
*
|
*
|
||||||
* \sa class CwiseUnaryOp, Cwise::cos()
|
* \sa class CwiseUnaryOp, Cwise::cos()
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_cos_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_cos_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_cos_op)
|
||||||
inline Scalar operator() (const Scalar& a) const { return ei_cos(a); }
|
inline Scalar operator() (const Scalar& a) const { return ei_cos(a); }
|
||||||
typedef typename ei_packet_traits<Scalar>::type Packet;
|
typedef typename ei_packet_traits<Scalar>::type Packet;
|
||||||
inline Packet packetOp(const Packet& a) const { return ei_pcos(a); }
|
inline Packet packetOp(const Packet& a) const { return ei_pcos(a); }
|
||||||
@ -87,7 +89,7 @@ struct ei_functor_traits<ei_scalar_cos_op<Scalar> >
|
|||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
Cost = 5 * NumTraits<Scalar>::MulCost,
|
Cost = 5 * NumTraits<Scalar>::MulCost,
|
||||||
PacketAccess = ei_packet_traits<Scalar>::HasCos && EIGEN_FAST_MATH
|
PacketAccess = ei_packet_traits<Scalar>::HasCos
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -99,7 +101,8 @@ struct ei_functor_traits<ei_scalar_cos_op<Scalar> >
|
|||||||
*
|
*
|
||||||
* \sa class CwiseUnaryOp, Cwise::sin()
|
* \sa class CwiseUnaryOp, Cwise::sin()
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_sin_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_sin_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_sin_op)
|
||||||
inline const Scalar operator() (const Scalar& a) const { return ei_sin(a); }
|
inline const Scalar operator() (const Scalar& a) const { return ei_sin(a); }
|
||||||
typedef typename ei_packet_traits<Scalar>::type Packet;
|
typedef typename ei_packet_traits<Scalar>::type Packet;
|
||||||
inline Packet packetOp(const Packet& a) const { return ei_psin(a); }
|
inline Packet packetOp(const Packet& a) const { return ei_psin(a); }
|
||||||
@ -109,7 +112,7 @@ struct ei_functor_traits<ei_scalar_sin_op<Scalar> >
|
|||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
Cost = 5 * NumTraits<Scalar>::MulCost,
|
Cost = 5 * NumTraits<Scalar>::MulCost,
|
||||||
PacketAccess = ei_packet_traits<Scalar>::HasSin && EIGEN_FAST_MATH
|
PacketAccess = ei_packet_traits<Scalar>::HasSin
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -143,6 +146,7 @@ struct ei_functor_traits<ei_scalar_pow_op<Scalar> >
|
|||||||
*/
|
*/
|
||||||
template<typename Scalar>
|
template<typename Scalar>
|
||||||
struct ei_scalar_inverse_op {
|
struct ei_scalar_inverse_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_inverse_op)
|
||||||
inline Scalar operator() (const Scalar& a) const { return Scalar(1)/a; }
|
inline Scalar operator() (const Scalar& a) const { return Scalar(1)/a; }
|
||||||
template<typename PacketScalar>
|
template<typename PacketScalar>
|
||||||
inline const PacketScalar packetOp(const PacketScalar& a) const
|
inline const PacketScalar packetOp(const PacketScalar& a) const
|
||||||
@ -162,6 +166,7 @@ struct ei_functor_traits<ei_scalar_inverse_op<Scalar> >
|
|||||||
*/
|
*/
|
||||||
template<typename Scalar>
|
template<typename Scalar>
|
||||||
struct ei_scalar_square_op {
|
struct ei_scalar_square_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_square_op)
|
||||||
inline Scalar operator() (const Scalar& a) const { return a*a; }
|
inline Scalar operator() (const Scalar& a) const { return a*a; }
|
||||||
template<typename PacketScalar>
|
template<typename PacketScalar>
|
||||||
inline const PacketScalar packetOp(const PacketScalar& a) const
|
inline const PacketScalar packetOp(const PacketScalar& a) const
|
||||||
@ -181,6 +186,7 @@ struct ei_functor_traits<ei_scalar_square_op<Scalar> >
|
|||||||
*/
|
*/
|
||||||
template<typename Scalar>
|
template<typename Scalar>
|
||||||
struct ei_scalar_cube_op {
|
struct ei_scalar_cube_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_cube_op)
|
||||||
inline Scalar operator() (const Scalar& a) const { return a*a*a; }
|
inline Scalar operator() (const Scalar& a) const { return a*a*a; }
|
||||||
template<typename PacketScalar>
|
template<typename PacketScalar>
|
||||||
inline const PacketScalar packetOp(const PacketScalar& a) const
|
inline const PacketScalar packetOp(const PacketScalar& a) const
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
#ifndef EIGEN_RANDOM_H
|
#ifndef EIGEN_RANDOM_H
|
||||||
#define EIGEN_RANDOM_H
|
#define EIGEN_RANDOM_H
|
||||||
|
|
||||||
template<typename Scalar> struct ei_scalar_random_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_random_op {
|
||||||
inline ei_scalar_random_op(void) {}
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_random_op)
|
||||||
inline const Scalar operator() (int, int) const { return ei_random<Scalar>(); }
|
inline const Scalar operator() (int, int) const { return ei_random<Scalar>(); }
|
||||||
};
|
};
|
||||||
template<typename Scalar>
|
template<typename Scalar>
|
||||||
|
@ -97,9 +97,6 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
|
|||||||
const typename MatrixType::Nested m_matrix;
|
const typename MatrixType::Nested m_matrix;
|
||||||
const ei_int_if_dynamic<RowFactor> m_rowFactor;
|
const ei_int_if_dynamic<RowFactor> m_rowFactor;
|
||||||
const ei_int_if_dynamic<ColFactor> m_colFactor;
|
const ei_int_if_dynamic<ColFactor> m_colFactor;
|
||||||
|
|
||||||
private:
|
|
||||||
Replicate& operator=(const Replicate&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \nonstableyet
|
/** \nonstableyet
|
||||||
|
@ -134,11 +134,11 @@ DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
|||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename ThenDerived>
|
template<typename ThenDerived>
|
||||||
inline const Select<Derived,ThenDerived, NestByValue<typename ThenDerived::ConstantReturnType> >
|
inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
|
||||||
DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
||||||
typename ThenDerived::Scalar elseScalar) const
|
typename ThenDerived::Scalar elseScalar) const
|
||||||
{
|
{
|
||||||
return Select<Derived,ThenDerived,NestByValue<typename ThenDerived::ConstantReturnType> >(
|
return Select<Derived,ThenDerived,typename ThenDerived::ConstantReturnType>(
|
||||||
derived(), thenMatrix.derived(), ThenDerived::Constant(rows(),cols(),elseScalar));
|
derived(), thenMatrix.derived(), ThenDerived::Constant(rows(),cols(),elseScalar));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,11 +151,11 @@ DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
|||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename ElseDerived>
|
template<typename ElseDerived>
|
||||||
inline const Select<Derived, NestByValue<typename ElseDerived::ConstantReturnType>, ElseDerived >
|
inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
|
||||||
DenseBase<Derived>::select(typename ElseDerived::Scalar thenScalar,
|
DenseBase<Derived>::select(typename ElseDerived::Scalar thenScalar,
|
||||||
const DenseBase<ElseDerived>& elseMatrix) const
|
const DenseBase<ElseDerived>& elseMatrix) const
|
||||||
{
|
{
|
||||||
return Select<Derived,NestByValue<typename ElseDerived::ConstantReturnType>,ElseDerived>(
|
return Select<Derived,typename ElseDerived::ConstantReturnType,ElseDerived>(
|
||||||
derived(), ElseDerived::Constant(rows(),cols(),thenScalar), elseMatrix.derived());
|
derived(), ElseDerived::Constant(rows(),cols(),thenScalar), elseMatrix.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,8 @@ class PartialReduxExpr : ei_no_assignment_operator,
|
|||||||
|
|
||||||
#define EIGEN_MEMBER_FUNCTOR(MEMBER,COST) \
|
#define EIGEN_MEMBER_FUNCTOR(MEMBER,COST) \
|
||||||
template <typename ResultType> \
|
template <typename ResultType> \
|
||||||
struct ei_member_##MEMBER EIGEN_EMPTY_STRUCT { \
|
struct ei_member_##MEMBER { \
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_member_##MEMBER) \
|
||||||
typedef ResultType result_type; \
|
typedef ResultType result_type; \
|
||||||
template<typename Scalar, int Size> struct Cost \
|
template<typename Scalar, int Size> struct Cost \
|
||||||
{ enum { value = COST }; }; \
|
{ enum { value = COST }; }; \
|
||||||
@ -124,6 +125,9 @@ class PartialReduxExpr : ei_no_assignment_operator,
|
|||||||
|
|
||||||
EIGEN_MEMBER_FUNCTOR(squaredNorm, Size * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
EIGEN_MEMBER_FUNCTOR(squaredNorm, Size * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
EIGEN_MEMBER_FUNCTOR(norm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
EIGEN_MEMBER_FUNCTOR(norm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
|
EIGEN_MEMBER_FUNCTOR(stableNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
|
EIGEN_MEMBER_FUNCTOR(blueNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
|
EIGEN_MEMBER_FUNCTOR(hypotNorm, (Size-1) * ei_functor_traits<ei_scalar_hypot_op<Scalar> >::Cost );
|
||||||
EIGEN_MEMBER_FUNCTOR(sum, (Size-1)*NumTraits<Scalar>::AddCost);
|
EIGEN_MEMBER_FUNCTOR(sum, (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
EIGEN_MEMBER_FUNCTOR(mean, (Size-1)*NumTraits<Scalar>::AddCost + NumTraits<Scalar>::MulCost);
|
EIGEN_MEMBER_FUNCTOR(mean, (Size-1)*NumTraits<Scalar>::AddCost + NumTraits<Scalar>::MulCost);
|
||||||
EIGEN_MEMBER_FUNCTOR(minCoeff, (Size-1)*NumTraits<Scalar>::AddCost);
|
EIGEN_MEMBER_FUNCTOR(minCoeff, (Size-1)*NumTraits<Scalar>::AddCost);
|
||||||
@ -291,6 +295,33 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
|||||||
const typename ReturnType<ei_member_norm>::Type norm() const
|
const typename ReturnType<ei_member_norm>::Type norm() const
|
||||||
{ return _expression(); }
|
{ return _expression(); }
|
||||||
|
|
||||||
|
|
||||||
|
/** \returns a row (or column) vector expression of the norm
|
||||||
|
* of each column (or row) of the referenced expression, using
|
||||||
|
* blue's algorithm.
|
||||||
|
*
|
||||||
|
* \sa MatrixBase::blueNorm() */
|
||||||
|
const typename ReturnType<ei_member_blueNorm>::Type blueNorm() const
|
||||||
|
{ return _expression(); }
|
||||||
|
|
||||||
|
|
||||||
|
/** \returns a row (or column) vector expression of the norm
|
||||||
|
* of each column (or row) of the referenced expression, avoiding
|
||||||
|
* underflow and overflow.
|
||||||
|
*
|
||||||
|
* \sa MatrixBase::stableNorm() */
|
||||||
|
const typename ReturnType<ei_member_stableNorm>::Type stableNorm() const
|
||||||
|
{ return _expression(); }
|
||||||
|
|
||||||
|
|
||||||
|
/** \returns a row (or column) vector expression of the norm
|
||||||
|
* of each column (or row) of the referenced expression, avoiding
|
||||||
|
* underflow and overflow using a concatenation of hypot() calls.
|
||||||
|
*
|
||||||
|
* \sa MatrixBase::hypotNorm() */
|
||||||
|
const typename ReturnType<ei_member_hypotNorm>::Type hypotNorm() const
|
||||||
|
{ return _expression(); }
|
||||||
|
|
||||||
/** \returns a row (or column) vector expression of the sum
|
/** \returns a row (or column) vector expression of the sum
|
||||||
* of each column (or row) of the referenced expression.
|
* of each column (or row) of the referenced expression.
|
||||||
*
|
*
|
||||||
@ -409,22 +440,22 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
|||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
CwiseBinaryOp<ei_scalar_sum_op<Scalar>,
|
CwiseBinaryOp<ei_scalar_sum_op<Scalar>,
|
||||||
ExpressionType,
|
ExpressionType,
|
||||||
NestByValue<typename ExtendedType<OtherDerived>::Type> >
|
typename ExtendedType<OtherDerived>::Type>
|
||||||
operator+(const MatrixBase<OtherDerived>& other) const
|
operator+(const MatrixBase<OtherDerived>& other) const
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived);
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived);
|
||||||
return m_matrix + extendedTo(other).nestByValue();
|
return m_matrix + extendedTo(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the expression of the difference between each subvector of \c *this and the vector \a other */
|
/** Returns the expression of the difference between each subvector of \c *this and the vector \a other */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
CwiseBinaryOp<ei_scalar_difference_op<Scalar>,
|
CwiseBinaryOp<ei_scalar_difference_op<Scalar>,
|
||||||
ExpressionType,
|
ExpressionType,
|
||||||
NestByValue<typename ExtendedType<OtherDerived>::Type> >
|
typename ExtendedType<OtherDerived>::Type>
|
||||||
operator-(const MatrixBase<OtherDerived>& other) const
|
operator-(const MatrixBase<OtherDerived>& other) const
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived);
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived);
|
||||||
return m_matrix - extendedTo(other).nestByValue();
|
return m_matrix - extendedTo(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////// Geometry module ///////////
|
/////////// Geometry module ///////////
|
||||||
@ -451,19 +482,16 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
|||||||
Direction==Horizontal ? 1 : int(ei_traits<ExpressionType>::ColsAtCompileTime)>
|
Direction==Horizontal ? 1 : int(ei_traits<ExpressionType>::ColsAtCompileTime)>
|
||||||
HNormalized_Factors;
|
HNormalized_Factors;
|
||||||
typedef CwiseBinaryOp<ei_scalar_quotient_op<typename ei_traits<ExpressionType>::Scalar>,
|
typedef CwiseBinaryOp<ei_scalar_quotient_op<typename ei_traits<ExpressionType>::Scalar>,
|
||||||
NestByValue<HNormalized_Block>,
|
HNormalized_Block,
|
||||||
NestByValue<Replicate<NestByValue<HNormalized_Factors>,
|
Replicate<HNormalized_Factors,
|
||||||
Direction==Vertical ? HNormalized_SizeMinusOne : 1,
|
Direction==Vertical ? HNormalized_SizeMinusOne : 1,
|
||||||
Direction==Horizontal ? HNormalized_SizeMinusOne : 1> > >
|
Direction==Horizontal ? HNormalized_SizeMinusOne : 1> >
|
||||||
HNormalizedReturnType;
|
HNormalizedReturnType;
|
||||||
|
|
||||||
const HNormalizedReturnType hnormalized() const;
|
const HNormalizedReturnType hnormalized() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ExpressionTypeNested m_matrix;
|
ExpressionTypeNested m_matrix;
|
||||||
|
|
||||||
private:
|
|
||||||
VectorwiseOp& operator=(const VectorwiseOp&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \array_module
|
/** \array_module
|
||||||
|
@ -224,18 +224,18 @@ template<> struct ei_llt_inplace<UpperTriangular>
|
|||||||
template<typename MatrixType> struct LLT_Traits<MatrixType,LowerTriangular>
|
template<typename MatrixType> struct LLT_Traits<MatrixType,LowerTriangular>
|
||||||
{
|
{
|
||||||
typedef TriangularView<MatrixType, LowerTriangular> MatrixL;
|
typedef TriangularView<MatrixType, LowerTriangular> MatrixL;
|
||||||
typedef TriangularView<NestByValue<typename MatrixType::AdjointReturnType>, UpperTriangular> MatrixU;
|
typedef TriangularView<typename MatrixType::AdjointReturnType, UpperTriangular> MatrixU;
|
||||||
inline static MatrixL getL(const MatrixType& m) { return m; }
|
inline static MatrixL getL(const MatrixType& m) { return m; }
|
||||||
inline static MatrixU getU(const MatrixType& m) { return m.adjoint().nestByValue(); }
|
inline static MatrixU getU(const MatrixType& m) { return m.adjoint(); }
|
||||||
static bool inplace_decomposition(MatrixType& m)
|
static bool inplace_decomposition(MatrixType& m)
|
||||||
{ return ei_llt_inplace<LowerTriangular>::blocked(m); }
|
{ return ei_llt_inplace<LowerTriangular>::blocked(m); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename MatrixType> struct LLT_Traits<MatrixType,UpperTriangular>
|
template<typename MatrixType> struct LLT_Traits<MatrixType,UpperTriangular>
|
||||||
{
|
{
|
||||||
typedef TriangularView<NestByValue<typename MatrixType::AdjointReturnType>, LowerTriangular> MatrixL;
|
typedef TriangularView<typename MatrixType::AdjointReturnType, LowerTriangular> MatrixL;
|
||||||
typedef TriangularView<MatrixType, UpperTriangular> MatrixU;
|
typedef TriangularView<MatrixType, UpperTriangular> MatrixU;
|
||||||
inline static MatrixL getL(const MatrixType& m) { return m.adjoint().nestByValue(); }
|
inline static MatrixL getL(const MatrixType& m) { return m.adjoint(); }
|
||||||
inline static MatrixU getU(const MatrixType& m) { return m; }
|
inline static MatrixU getU(const MatrixType& m) { return m; }
|
||||||
static bool inplace_decomposition(MatrixType& m)
|
static bool inplace_decomposition(MatrixType& m)
|
||||||
{ return ei_llt_inplace<UpperTriangular>::blocked(m); }
|
{ return ei_llt_inplace<UpperTriangular>::blocked(m); }
|
||||||
|
@ -57,7 +57,7 @@ template<typename Derived> struct AnyMatrixBase
|
|||||||
{ derived().evalTo(dst); }
|
{ derived().evalTo(dst); }
|
||||||
|
|
||||||
/** \internal Don't use it, but do the equivalent: \code dst += *this; \endcode */
|
/** \internal Don't use it, but do the equivalent: \code dst += *this; \endcode */
|
||||||
template<typename Dest> inline void addToDense(Dest& dst) const
|
template<typename Dest> inline void addTo(Dest& dst) const
|
||||||
{
|
{
|
||||||
// This is the default implementation,
|
// This is the default implementation,
|
||||||
// derived class can reimplement it in a more optimized way.
|
// derived class can reimplement it in a more optimized way.
|
||||||
@ -67,7 +67,7 @@ template<typename Derived> struct AnyMatrixBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** \internal Don't use it, but do the equivalent: \code dst -= *this; \endcode */
|
/** \internal Don't use it, but do the equivalent: \code dst -= *this; \endcode */
|
||||||
template<typename Dest> inline void subToDense(Dest& dst) const
|
template<typename Dest> inline void subTo(Dest& dst) const
|
||||||
{
|
{
|
||||||
// This is the default implementation,
|
// This is the default implementation,
|
||||||
// derived class can reimplement it in a more optimized way.
|
// derived class can reimplement it in a more optimized way.
|
||||||
@ -114,7 +114,7 @@ template<typename Derived>
|
|||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
Derived& DenseBase<Derived>::operator+=(const AnyMatrixBase<OtherDerived> &other)
|
Derived& DenseBase<Derived>::operator+=(const AnyMatrixBase<OtherDerived> &other)
|
||||||
{
|
{
|
||||||
other.derived().addToDense(derived());
|
other.derived().addTo(derived());
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ template<typename Derived>
|
|||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
Derived& DenseBase<Derived>::operator-=(const AnyMatrixBase<OtherDerived> &other)
|
Derived& DenseBase<Derived>::operator-=(const AnyMatrixBase<OtherDerived> &other)
|
||||||
{
|
{
|
||||||
other.derived().subToDense(derived());
|
other.derived().subTo(derived());
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#define EIGEN_ASSIGN_H
|
#define EIGEN_ASSIGN_H
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Part 1 : the logic deciding a strategy for vectorization and unrolling
|
* Part 1 : the logic deciding a strategy for traversal and unrolling *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
template <typename Derived, typename OtherDerived>
|
template <typename Derived, typename OtherDerived>
|
||||||
@ -53,44 +53,53 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MightVectorize = (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit)
|
StorageOrdersAgree = (int(Derived::Flags)&RowMajorBit)==(int(OtherDerived::Flags)&RowMajorBit),
|
||||||
&& ((int(Derived::Flags)&RowMajorBit)==(int(OtherDerived::Flags)&RowMajorBit)),
|
MightVectorize = StorageOrdersAgree
|
||||||
|
&& (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit),
|
||||||
MayInnerVectorize = MightVectorize && int(InnerSize)!=Dynamic && int(InnerSize)%int(PacketSize)==0
|
MayInnerVectorize = MightVectorize && int(InnerSize)!=Dynamic && int(InnerSize)%int(PacketSize)==0
|
||||||
&& int(DstIsAligned) && int(SrcIsAligned),
|
&& int(DstIsAligned) && int(SrcIsAligned),
|
||||||
MayLinearVectorize = MightVectorize && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit)
|
MayLinearize = StorageOrdersAgree && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit),
|
||||||
&& (DstIsAligned || InnerMaxSize == Dynamic),/* If the destination isn't aligned,
|
MayLinearVectorize = MightVectorize && MayLinearize
|
||||||
we have to do runtime checks and we don't unroll, so it's only good for large enough sizes. See remark below
|
&& (DstIsAligned || InnerMaxSize == Dynamic),
|
||||||
about InnerMaxSize. */
|
/* If the destination isn't aligned, we have to do runtime checks and we don't unroll,
|
||||||
MaySliceVectorize = MightVectorize && int(InnerMaxSize)>=3*PacketSize /* slice vectorization can be slow, so we only
|
so it's only good for large enough sizes. See remark below about InnerMaxSize. */
|
||||||
want it if the slices are big, which is indicated by InnerMaxSize rather than InnerSize, think of the case
|
MaySliceVectorize = MightVectorize && int(InnerMaxSize)>=3*PacketSize
|
||||||
of a dynamic block in a fixed-size matrix */
|
/* slice vectorization can be slow, so we only want it if the slices are big, which is
|
||||||
|
indicated by InnerMaxSize rather than InnerSize, think of the case of a dynamic block
|
||||||
|
in a fixed-size matrix */
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
Vectorization = int(MayInnerVectorize) ? int(InnerVectorization)
|
Traversal = int(MayInnerVectorize) ? int(InnerVectorizedTraversal)
|
||||||
: int(MayLinearVectorize) ? int(LinearVectorization)
|
: int(MayLinearVectorize) ? int(LinearVectorizedTraversal)
|
||||||
: int(MaySliceVectorize) ? int(SliceVectorization)
|
: int(MaySliceVectorize) ? int(SliceVectorizedTraversal)
|
||||||
: int(NoVectorization)
|
: int(MayLinearize) ? int(LinearTraversal)
|
||||||
|
: int(DefaultTraversal),
|
||||||
|
Vectorized = int(Traversal) == InnerVectorizedTraversal
|
||||||
|
|| int(Traversal) == LinearVectorizedTraversal
|
||||||
|
|| int(Traversal) == SliceVectorizedTraversal
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Vectorization) == int(NoVectorization) ? 1 : int(PacketSize)),
|
UnrollingLimit = EIGEN_UNROLLING_LIMIT * (Vectorized ? int(PacketSize) : 1),
|
||||||
MayUnrollCompletely = int(Derived::SizeAtCompileTime) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit),
|
MayUnrollCompletely = int(Derived::SizeAtCompileTime) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit),
|
||||||
MayUnrollInner = int(InnerSize * OtherDerived::CoeffReadCost) <= int(UnrollingLimit)
|
MayUnrollInner = int(InnerSize) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit)
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
Unrolling = (int(Vectorization) == int(InnerVectorization) || int(Vectorization) == int(NoVectorization))
|
Unrolling = (int(Traversal) == int(InnerVectorizedTraversal) || int(Traversal) == int(DefaultTraversal))
|
||||||
? (
|
? (
|
||||||
int(MayUnrollCompletely) ? int(CompleteUnrolling)
|
int(MayUnrollCompletely) ? int(CompleteUnrolling)
|
||||||
: int(MayUnrollInner) ? int(InnerUnrolling)
|
: int(MayUnrollInner) ? int(InnerUnrolling)
|
||||||
: int(NoUnrolling)
|
: int(NoUnrolling)
|
||||||
)
|
)
|
||||||
: int(Vectorization) == int(LinearVectorization)
|
: int(Traversal) == int(LinearVectorizedTraversal)
|
||||||
? ( int(MayUnrollCompletely) && int(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) )
|
? ( int(MayUnrollCompletely) && int(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) )
|
||||||
|
: int(Traversal) == int(LinearTraversal)
|
||||||
|
? ( int(MayUnrollCompletely) ? int(CompleteUnrolling) : int(NoUnrolling) )
|
||||||
: int(NoUnrolling)
|
: int(NoUnrolling)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -102,11 +111,12 @@ public:
|
|||||||
EIGEN_DEBUG_VAR(InnerSize)
|
EIGEN_DEBUG_VAR(InnerSize)
|
||||||
EIGEN_DEBUG_VAR(InnerMaxSize)
|
EIGEN_DEBUG_VAR(InnerMaxSize)
|
||||||
EIGEN_DEBUG_VAR(PacketSize)
|
EIGEN_DEBUG_VAR(PacketSize)
|
||||||
|
EIGEN_DEBUG_VAR(StorageOrdersAgree)
|
||||||
EIGEN_DEBUG_VAR(MightVectorize)
|
EIGEN_DEBUG_VAR(MightVectorize)
|
||||||
EIGEN_DEBUG_VAR(MayInnerVectorize)
|
EIGEN_DEBUG_VAR(MayInnerVectorize)
|
||||||
EIGEN_DEBUG_VAR(MayLinearVectorize)
|
EIGEN_DEBUG_VAR(MayLinearVectorize)
|
||||||
EIGEN_DEBUG_VAR(MaySliceVectorize)
|
EIGEN_DEBUG_VAR(MaySliceVectorize)
|
||||||
EIGEN_DEBUG_VAR(Vectorization)
|
EIGEN_DEBUG_VAR(Traversal)
|
||||||
EIGEN_DEBUG_VAR(UnrollingLimit)
|
EIGEN_DEBUG_VAR(UnrollingLimit)
|
||||||
EIGEN_DEBUG_VAR(MayUnrollCompletely)
|
EIGEN_DEBUG_VAR(MayUnrollCompletely)
|
||||||
EIGEN_DEBUG_VAR(MayUnrollInner)
|
EIGEN_DEBUG_VAR(MayUnrollInner)
|
||||||
@ -118,12 +128,12 @@ public:
|
|||||||
* Part 2 : meta-unrollers
|
* Part 2 : meta-unrollers
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
/***********************
|
/************************
|
||||||
*** No vectorization ***
|
*** Default traversal ***
|
||||||
***********************/
|
************************/
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Index, int Stop>
|
template<typename Derived1, typename Derived2, int Index, int Stop>
|
||||||
struct ei_assign_novec_CompleteUnrolling
|
struct ei_assign_DefaultTraversal_CompleteUnrolling
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
row = int(Derived1::Flags)&RowMajorBit
|
row = int(Derived1::Flags)&RowMajorBit
|
||||||
@ -137,18 +147,18 @@ struct ei_assign_novec_CompleteUnrolling
|
|||||||
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
||||||
{
|
{
|
||||||
dst.copyCoeff(row, col, src);
|
dst.copyCoeff(row, col, src);
|
||||||
ei_assign_novec_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src);
|
ei_assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Stop>
|
template<typename Derived1, typename Derived2, int Stop>
|
||||||
struct ei_assign_novec_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
|
struct ei_assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
|
||||||
{
|
{
|
||||||
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {}
|
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Index, int Stop>
|
template<typename Derived1, typename Derived2, int Index, int Stop>
|
||||||
struct ei_assign_novec_InnerUnrolling
|
struct ei_assign_DefaultTraversal_InnerUnrolling
|
||||||
{
|
{
|
||||||
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int row_or_col)
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int row_or_col)
|
||||||
{
|
{
|
||||||
@ -156,16 +166,36 @@ struct ei_assign_novec_InnerUnrolling
|
|||||||
const int row = rowMajor ? row_or_col : Index;
|
const int row = rowMajor ? row_or_col : Index;
|
||||||
const int col = rowMajor ? Index : row_or_col;
|
const int col = rowMajor ? Index : row_or_col;
|
||||||
dst.copyCoeff(row, col, src);
|
dst.copyCoeff(row, col, src);
|
||||||
ei_assign_novec_InnerUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src, row_or_col);
|
ei_assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src, row_or_col);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Stop>
|
template<typename Derived1, typename Derived2, int Stop>
|
||||||
struct ei_assign_novec_InnerUnrolling<Derived1, Derived2, Stop, Stop>
|
struct ei_assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Stop, Stop>
|
||||||
{
|
{
|
||||||
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &, int) {}
|
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &, int) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/***********************
|
||||||
|
*** Linear traversal ***
|
||||||
|
***********************/
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2, int Index, int Stop>
|
||||||
|
struct ei_assign_LinearTraversal_CompleteUnrolling
|
||||||
|
{
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
||||||
|
{
|
||||||
|
dst.copyCoeff(Index, src);
|
||||||
|
ei_assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2, int Stop>
|
||||||
|
struct ei_assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
|
||||||
|
{
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {}
|
||||||
|
};
|
||||||
|
|
||||||
/**************************
|
/**************************
|
||||||
*** Inner vectorization ***
|
*** Inner vectorization ***
|
||||||
**************************/
|
**************************/
|
||||||
@ -221,16 +251,16 @@ struct ei_assign_innervec_InnerUnrolling<Derived1, Derived2, Stop, Stop>
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2,
|
template<typename Derived1, typename Derived2,
|
||||||
int Vectorization = ei_assign_traits<Derived1, Derived2>::Vectorization,
|
int Traversal = ei_assign_traits<Derived1, Derived2>::Traversal,
|
||||||
int Unrolling = ei_assign_traits<Derived1, Derived2>::Unrolling>
|
int Unrolling = ei_assign_traits<Derived1, Derived2>::Unrolling>
|
||||||
struct ei_assign_impl;
|
struct ei_assign_impl;
|
||||||
|
|
||||||
/***********************
|
/************************
|
||||||
*** No vectorization ***
|
*** Default traversal ***
|
||||||
***********************/
|
************************/
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2>
|
template<typename Derived1, typename Derived2>
|
||||||
struct ei_assign_impl<Derived1, Derived2, NoVectorization, NoUnrolling>
|
struct ei_assign_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling>
|
||||||
{
|
{
|
||||||
inline static void run(Derived1 &dst, const Derived2 &src)
|
inline static void run(Derived1 &dst, const Derived2 &src)
|
||||||
{
|
{
|
||||||
@ -248,17 +278,17 @@ struct ei_assign_impl<Derived1, Derived2, NoVectorization, NoUnrolling>
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2>
|
template<typename Derived1, typename Derived2>
|
||||||
struct ei_assign_impl<Derived1, Derived2, NoVectorization, CompleteUnrolling>
|
struct ei_assign_impl<Derived1, Derived2, DefaultTraversal, CompleteUnrolling>
|
||||||
{
|
{
|
||||||
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
||||||
{
|
{
|
||||||
ei_assign_novec_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
|
ei_assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
|
||||||
::run(dst, src);
|
::run(dst, src);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2>
|
template<typename Derived1, typename Derived2>
|
||||||
struct ei_assign_impl<Derived1, Derived2, NoVectorization, InnerUnrolling>
|
struct ei_assign_impl<Derived1, Derived2, DefaultTraversal, InnerUnrolling>
|
||||||
{
|
{
|
||||||
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
||||||
{
|
{
|
||||||
@ -266,17 +296,42 @@ struct ei_assign_impl<Derived1, Derived2, NoVectorization, InnerUnrolling>
|
|||||||
const int innerSize = rowMajor ? Derived1::ColsAtCompileTime : Derived1::RowsAtCompileTime;
|
const int innerSize = rowMajor ? Derived1::ColsAtCompileTime : Derived1::RowsAtCompileTime;
|
||||||
const int outerSize = dst.outerSize();
|
const int outerSize = dst.outerSize();
|
||||||
for(int j = 0; j < outerSize; ++j)
|
for(int j = 0; j < outerSize; ++j)
|
||||||
ei_assign_novec_InnerUnrolling<Derived1, Derived2, 0, innerSize>
|
ei_assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, 0, innerSize>
|
||||||
::run(dst, src, j);
|
::run(dst, src, j);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/***********************
|
||||||
|
*** Linear traversal ***
|
||||||
|
***********************/
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2>
|
||||||
|
struct ei_assign_impl<Derived1, Derived2, LinearTraversal, NoUnrolling>
|
||||||
|
{
|
||||||
|
inline static void run(Derived1 &dst, const Derived2 &src)
|
||||||
|
{
|
||||||
|
const int size = dst.size();
|
||||||
|
for(int i = 0; i < size; ++i)
|
||||||
|
dst.copyCoeff(i, src);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived1, typename Derived2>
|
||||||
|
struct ei_assign_impl<Derived1, Derived2, LinearTraversal, CompleteUnrolling>
|
||||||
|
{
|
||||||
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
||||||
|
{
|
||||||
|
ei_assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
|
||||||
|
::run(dst, src);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**************************
|
/**************************
|
||||||
*** Inner vectorization ***
|
*** Inner vectorization ***
|
||||||
**************************/
|
**************************/
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2>
|
template<typename Derived1, typename Derived2>
|
||||||
struct ei_assign_impl<Derived1, Derived2, InnerVectorization, NoUnrolling>
|
struct ei_assign_impl<Derived1, Derived2, InnerVectorizedTraversal, NoUnrolling>
|
||||||
{
|
{
|
||||||
inline static void run(Derived1 &dst, const Derived2 &src)
|
inline static void run(Derived1 &dst, const Derived2 &src)
|
||||||
{
|
{
|
||||||
@ -295,7 +350,7 @@ struct ei_assign_impl<Derived1, Derived2, InnerVectorization, NoUnrolling>
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2>
|
template<typename Derived1, typename Derived2>
|
||||||
struct ei_assign_impl<Derived1, Derived2, InnerVectorization, CompleteUnrolling>
|
struct ei_assign_impl<Derived1, Derived2, InnerVectorizedTraversal, CompleteUnrolling>
|
||||||
{
|
{
|
||||||
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
||||||
{
|
{
|
||||||
@ -305,7 +360,7 @@ struct ei_assign_impl<Derived1, Derived2, InnerVectorization, CompleteUnrolling>
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2>
|
template<typename Derived1, typename Derived2>
|
||||||
struct ei_assign_impl<Derived1, Derived2, InnerVectorization, InnerUnrolling>
|
struct ei_assign_impl<Derived1, Derived2, InnerVectorizedTraversal, InnerUnrolling>
|
||||||
{
|
{
|
||||||
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
||||||
{
|
{
|
||||||
@ -323,7 +378,7 @@ struct ei_assign_impl<Derived1, Derived2, InnerVectorization, InnerUnrolling>
|
|||||||
***************************/
|
***************************/
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2>
|
template<typename Derived1, typename Derived2>
|
||||||
struct ei_assign_impl<Derived1, Derived2, LinearVectorization, NoUnrolling>
|
struct ei_assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling>
|
||||||
{
|
{
|
||||||
inline static void run(Derived1 &dst, const Derived2 &src)
|
inline static void run(Derived1 &dst, const Derived2 &src)
|
||||||
{
|
{
|
||||||
@ -347,7 +402,7 @@ struct ei_assign_impl<Derived1, Derived2, LinearVectorization, NoUnrolling>
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2>
|
template<typename Derived1, typename Derived2>
|
||||||
struct ei_assign_impl<Derived1, Derived2, LinearVectorization, CompleteUnrolling>
|
struct ei_assign_impl<Derived1, Derived2, LinearVectorizedTraversal, CompleteUnrolling>
|
||||||
{
|
{
|
||||||
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
||||||
{
|
{
|
||||||
@ -356,7 +411,7 @@ struct ei_assign_impl<Derived1, Derived2, LinearVectorization, CompleteUnrolling
|
|||||||
const int alignedSize = (size/packetSize)*packetSize;
|
const int alignedSize = (size/packetSize)*packetSize;
|
||||||
|
|
||||||
ei_assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, alignedSize>::run(dst, src);
|
ei_assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, alignedSize>::run(dst, src);
|
||||||
ei_assign_novec_CompleteUnrolling<Derived1, Derived2, alignedSize, size>::run(dst, src);
|
ei_assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, alignedSize, size>::run(dst, src);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -365,7 +420,7 @@ struct ei_assign_impl<Derived1, Derived2, LinearVectorization, CompleteUnrolling
|
|||||||
***************************/
|
***************************/
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2>
|
template<typename Derived1, typename Derived2>
|
||||||
struct ei_assign_impl<Derived1, Derived2, SliceVectorization, NoUnrolling>
|
struct ei_assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling>
|
||||||
{
|
{
|
||||||
inline static void run(Derived1 &dst, const Derived2 &src)
|
inline static void run(Derived1 &dst, const Derived2 &src)
|
||||||
{
|
{
|
||||||
@ -429,6 +484,9 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>
|
|||||||
ei_assign_impl<Derived, OtherDerived>::run(derived(),other.derived());
|
ei_assign_impl<Derived, OtherDerived>::run(derived(),other.derived());
|
||||||
#ifdef EIGEN_DEBUG_ASSIGN
|
#ifdef EIGEN_DEBUG_ASSIGN
|
||||||
ei_assign_traits<Derived, OtherDerived>::debug();
|
ei_assign_traits<Derived, OtherDerived>::debug();
|
||||||
|
#endif
|
||||||
|
#ifndef EIGEN_NO_DEBUG
|
||||||
|
checkTransposeAliasing(other.derived());
|
||||||
#endif
|
#endif
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ class BandMatrix : public AnyMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs
|
|||||||
MaxColsAtCompileTime = ei_traits<BandMatrix>::MaxColsAtCompileTime
|
MaxColsAtCompileTime = ei_traits<BandMatrix>::MaxColsAtCompileTime
|
||||||
};
|
};
|
||||||
typedef typename ei_traits<BandMatrix>::Scalar Scalar;
|
typedef typename ei_traits<BandMatrix>::Scalar Scalar;
|
||||||
typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> PlainMatrixType;
|
typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> DenseMatrixType;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum {
|
enum {
|
||||||
@ -87,7 +87,7 @@ class BandMatrix : public AnyMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs
|
|||||||
: m_data(1+supers+subs,cols),
|
: m_data(1+supers+subs,cols),
|
||||||
m_rows(rows), m_supers(supers), m_subs(subs)
|
m_rows(rows), m_supers(supers), m_subs(subs)
|
||||||
{
|
{
|
||||||
m_data.setConstant(666);
|
//m_data.setConstant(666);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the number of columns */
|
/** \returns the number of columns */
|
||||||
@ -141,7 +141,7 @@ class BandMatrix : public AnyMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs
|
|||||||
};
|
};
|
||||||
typedef Block<DataType,1, DiagonalSize> BuildType;
|
typedef Block<DataType,1, DiagonalSize> BuildType;
|
||||||
typedef typename ei_meta_if<Conjugate,
|
typedef typename ei_meta_if<Conjugate,
|
||||||
CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>,NestByValue<BuildType> >,
|
CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>,BuildType >,
|
||||||
BuildType>::ret Type;
|
BuildType>::ret Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -171,9 +171,9 @@ class BandMatrix : public AnyMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs
|
|||||||
return Block<DataType,1,Dynamic>(m_data, supers()-i, std::max(0,i), 1, diagonalLength(i));
|
return Block<DataType,1,Dynamic>(m_data, supers()-i, std::max(0,i), 1, diagonalLength(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
PlainMatrixType toDense() const
|
DenseMatrixType toDenseMatrix() const
|
||||||
{
|
{
|
||||||
PlainMatrixType res(rows(),cols());
|
DenseMatrixType res(rows(),cols());
|
||||||
res.setZero();
|
res.setZero();
|
||||||
res.diagonal() = diagonal();
|
res.diagonal() = diagonal();
|
||||||
for (int i=1; i<=supers();++i)
|
for (int i=1; i<=supers();++i)
|
||||||
|
@ -379,6 +379,38 @@ EIGEN_STRONG_INLINE void DenseBase<Derived>::copyPacket(int index, const DenseBa
|
|||||||
other.derived().template packet<LoadMode>(index));
|
other.derived().template packet<LoadMode>(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Derived, typename Integer, bool JustReturnZero>
|
||||||
|
struct ei_alignmentOffset_impl
|
||||||
|
{
|
||||||
|
inline static Integer run(const DenseBase<Derived>&, Integer)
|
||||||
|
{ return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived, typename Integer>
|
||||||
|
struct ei_alignmentOffset_impl<Derived, Integer, false>
|
||||||
|
{
|
||||||
|
inline static Integer run(const DenseBase<Derived>& m, Integer maxOffset)
|
||||||
|
{
|
||||||
|
return ei_alignmentOffset(&m.const_cast_derived().coeffRef(0,0), maxOffset);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \internal \returns the number of elements which have to be skipped, starting
|
||||||
|
* from the address of coeffRef(0,0), to find the first 16-byte aligned element.
|
||||||
|
*
|
||||||
|
* \note If the expression doesn't have the DirectAccessBit, this function returns 0.
|
||||||
|
*
|
||||||
|
* There is also the variant ei_alignmentOffset(const Scalar*, Integer) defined in Memory.h.
|
||||||
|
*/
|
||||||
|
template<typename Derived, typename Integer>
|
||||||
|
inline static Integer ei_alignmentOffset(const DenseBase<Derived>& m, Integer maxOffset)
|
||||||
|
{
|
||||||
|
return ei_alignmentOffset_impl<Derived, Integer,
|
||||||
|
(Derived::Flags & AlignedBit) || !(Derived::Flags & DirectAccessBit)>
|
||||||
|
::run(m, maxOffset);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // EIGEN_COEFFS_H
|
#endif // EIGEN_COEFFS_H
|
||||||
|
@ -116,9 +116,6 @@ struct CommaInitializer
|
|||||||
int m_row; // current row id
|
int m_row; // current row id
|
||||||
int m_col; // current col id
|
int m_col; // current col id
|
||||||
int m_currentBlockRows; // current block height
|
int m_currentBlockRows; // current block height
|
||||||
|
|
||||||
private:
|
|
||||||
CommaInitializer& operator=(const CommaInitializer&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \anchor MatrixBaseCommaInitRef
|
/** \anchor MatrixBaseCommaInitRef
|
||||||
|
@ -65,11 +65,16 @@ struct ei_traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > : ei_traits<Lhs>
|
|||||||
RhsCoeffReadCost = _RhsNested::CoeffReadCost,
|
RhsCoeffReadCost = _RhsNested::CoeffReadCost,
|
||||||
LhsFlags = _LhsNested::Flags,
|
LhsFlags = _LhsNested::Flags,
|
||||||
RhsFlags = _RhsNested::Flags,
|
RhsFlags = _RhsNested::Flags,
|
||||||
|
StorageOrdersAgree = (int(Lhs::Flags)&RowMajorBit)==(int(Rhs::Flags)&RowMajorBit),
|
||||||
Flags = (int(LhsFlags) | int(RhsFlags)) & (
|
Flags = (int(LhsFlags) | int(RhsFlags)) & (
|
||||||
HereditaryBits
|
HereditaryBits
|
||||||
| (int(LhsFlags) & int(RhsFlags) & (LinearAccessBit | AlignedBit))
|
| (int(LhsFlags) & int(RhsFlags) &
|
||||||
| (ei_functor_traits<BinaryOp>::PacketAccess && ((int(LhsFlags) & RowMajorBit)==(int(RhsFlags) & RowMajorBit))
|
( AlignedBit
|
||||||
? (int(LhsFlags) & int(RhsFlags) & PacketAccessBit) : 0)),
|
| (StorageOrdersAgree ? LinearAccessBit : 0)
|
||||||
|
| (ei_functor_traits<BinaryOp>::PacketAccess && StorageOrdersAgree ? PacketAccessBit : 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + ei_functor_traits<BinaryOp>::Cost
|
CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + ei_functor_traits<BinaryOp>::Cost
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -274,21 +274,12 @@ template<typename Derived> class DenseBase
|
|||||||
Eigen::Transpose<Derived> transpose();
|
Eigen::Transpose<Derived> transpose();
|
||||||
const Eigen::Transpose<Derived> transpose() const;
|
const Eigen::Transpose<Derived> transpose() const;
|
||||||
void transposeInPlace();
|
void transposeInPlace();
|
||||||
#ifndef EIGEN_NO_DEBUG
|
#ifndef EIGEN_NO_DEBUG
|
||||||
|
protected:
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
Derived& lazyAssign(const Transpose<OtherDerived>& other);
|
void checkTransposeAliasing(const OtherDerived& other) const;
|
||||||
template<typename DerivedA, typename DerivedB>
|
public:
|
||||||
Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,Transpose<DerivedA>,DerivedB>& other);
|
#endif
|
||||||
template<typename DerivedA, typename DerivedB>
|
|
||||||
Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,Transpose<DerivedB> >& other);
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
|
||||||
Derived& lazyAssign(const CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<OtherDerived> > >& other);
|
|
||||||
template<typename DerivedA, typename DerivedB>
|
|
||||||
Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedA> > >,DerivedB>& other);
|
|
||||||
template<typename DerivedA, typename DerivedB>
|
|
||||||
Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedB> > > >& other);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RowXpr row(int i);
|
RowXpr row(int i);
|
||||||
const RowXpr row(int i) const;
|
const RowXpr row(int i) const;
|
||||||
@ -382,18 +373,19 @@ template<typename Derived> class DenseBase
|
|||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
bool isApprox(const DenseBase<OtherDerived>& other,
|
bool isApprox(const DenseBase<OtherDerived>& other,
|
||||||
RealScalar prec = precision<Scalar>()) const;
|
RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
bool isMuchSmallerThan(const RealScalar& other,
|
bool isMuchSmallerThan(const RealScalar& other,
|
||||||
RealScalar prec = precision<Scalar>()) const;
|
RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
bool isMuchSmallerThan(const DenseBase<OtherDerived>& other,
|
bool isMuchSmallerThan(const DenseBase<OtherDerived>& other,
|
||||||
RealScalar prec = precision<Scalar>()) const;
|
RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
|
|
||||||
bool isApproxToConstant(const Scalar& value, RealScalar prec = precision<Scalar>()) const;
|
bool isApproxToConstant(const Scalar& value, RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
bool isConstant(const Scalar& value, RealScalar prec = precision<Scalar>()) const;
|
bool isConstant(const Scalar& value, RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
bool isZero(RealScalar prec = precision<Scalar>()) const;
|
bool isZero(RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
bool isOnes(RealScalar prec = precision<Scalar>()) const;
|
bool isOnes(RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
|
|
||||||
|
// FIXME
|
||||||
EIGEN_STRONG_INLINE Derived& operator*=(const Scalar& other)
|
EIGEN_STRONG_INLINE Derived& operator*=(const Scalar& other)
|
||||||
{
|
{
|
||||||
SelfCwiseBinaryOp<ei_scalar_product_op<Scalar>, Derived> tmp(derived());
|
SelfCwiseBinaryOp<ei_scalar_product_op<Scalar>, Derived> tmp(derived());
|
||||||
@ -409,6 +401,7 @@ template<typename Derived> class DenseBase
|
|||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME
|
||||||
// template<typename OtherDerived>
|
// template<typename OtherDerived>
|
||||||
// inline bool operator==(const DenseBase<OtherDerived>& other) const
|
// inline bool operator==(const DenseBase<OtherDerived>& other) const
|
||||||
// { return cwiseEqual(other).all(); }
|
// { return cwiseEqual(other).all(); }
|
||||||
@ -487,11 +480,11 @@ template<typename Derived> class DenseBase
|
|||||||
const DenseBase<ElseDerived>& elseMatrix) const;
|
const DenseBase<ElseDerived>& elseMatrix) const;
|
||||||
|
|
||||||
template<typename ThenDerived>
|
template<typename ThenDerived>
|
||||||
inline const Select<Derived,ThenDerived, NestByValue<typename ThenDerived::ConstantReturnType> >
|
inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
|
||||||
select(const DenseBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const;
|
select(const DenseBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const;
|
||||||
|
|
||||||
template<typename ElseDerived>
|
template<typename ElseDerived>
|
||||||
inline const Select<Derived, NestByValue<typename ElseDerived::ConstantReturnType>, ElseDerived >
|
inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
|
||||||
select(typename ElseDerived::Scalar thenScalar, const DenseBase<ElseDerived>& elseMatrix) const;
|
select(typename ElseDerived::Scalar thenScalar, const DenseBase<ElseDerived>& elseMatrix) const;
|
||||||
|
|
||||||
template<int p> RealScalar lpNorm() const;
|
template<int p> RealScalar lpNorm() const;
|
||||||
|
@ -175,8 +175,14 @@ class DenseStorageBase : public _Base<Derived>
|
|||||||
&& (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
|
&& (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
|
||||||
&& (MaxColsAtCompileTime == Dynamic || MaxColsAtCompileTime >= cols)
|
&& (MaxColsAtCompileTime == Dynamic || MaxColsAtCompileTime >= cols)
|
||||||
&& (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
|
&& (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
|
||||||
m_storage.resize(rows * cols, rows, cols);
|
#ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
|
||||||
EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
|
int size = rows*cols;
|
||||||
|
bool size_changed = size != this->size();
|
||||||
|
m_storage.resize(size, rows, cols);
|
||||||
|
if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
|
||||||
|
#else
|
||||||
|
m_storage.resize(rows*cols, rows, cols);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resizes \c *this to a vector of length \a size
|
/** Resizes \c *this to a vector of length \a size
|
||||||
@ -194,11 +200,16 @@ class DenseStorageBase : public _Base<Derived>
|
|||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(DenseStorageBase)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(DenseStorageBase)
|
||||||
ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
|
ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
|
||||||
|
#ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
|
||||||
|
bool size_changed = size != this->size();
|
||||||
|
#endif
|
||||||
if(RowsAtCompileTime == 1)
|
if(RowsAtCompileTime == 1)
|
||||||
m_storage.resize(size, 1, size);
|
m_storage.resize(size, 1, size);
|
||||||
else
|
else
|
||||||
m_storage.resize(size, size, 1);
|
m_storage.resize(size, size, 1);
|
||||||
EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
|
#ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
|
||||||
|
if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resizes the matrix, changing only the number of columns. For the parameter of type NoChange_t, just pass the special value \c NoChange
|
/** Resizes the matrix, changing only the number of columns. For the parameter of type NoChange_t, just pass the special value \c NoChange
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#ifndef EIGEN_DIAGONALMATRIX_H
|
#ifndef EIGEN_DIAGONALMATRIX_H
|
||||||
#define EIGEN_DIAGONALMATRIX_H
|
#define EIGEN_DIAGONALMATRIX_H
|
||||||
|
|
||||||
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
class DiagonalBase : public AnyMatrixBase<Derived>
|
class DiagonalBase : public AnyMatrixBase<Derived>
|
||||||
{
|
{
|
||||||
@ -44,19 +45,17 @@ class DiagonalBase : public AnyMatrixBase<Derived>
|
|||||||
|
|
||||||
typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, 0, MaxRowsAtCompileTime, MaxColsAtCompileTime> DenseMatrixType;
|
typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, 0, MaxRowsAtCompileTime, MaxColsAtCompileTime> DenseMatrixType;
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
||||||
inline Derived& derived() { return *static_cast<Derived*>(this); }
|
inline Derived& derived() { return *static_cast<Derived*>(this); }
|
||||||
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
|
|
||||||
DenseMatrixType toDenseMatrix() const { return derived(); }
|
DenseMatrixType toDenseMatrix() const { return derived(); }
|
||||||
template<typename DenseDerived>
|
template<typename DenseDerived>
|
||||||
void evalTo(MatrixBase<DenseDerived> &other) const;
|
void evalTo(MatrixBase<DenseDerived> &other) const;
|
||||||
template<typename DenseDerived>
|
template<typename DenseDerived>
|
||||||
void addToDense(MatrixBase<DenseDerived> &other) const
|
void addTo(MatrixBase<DenseDerived> &other) const
|
||||||
{ other.diagonal() += diagonal(); }
|
{ other.diagonal() += diagonal(); }
|
||||||
template<typename DenseDerived>
|
template<typename DenseDerived>
|
||||||
void subToDense(MatrixBase<DenseDerived> &other) const
|
void subTo(MatrixBase<DenseDerived> &other) const
|
||||||
{ other.diagonal() -= diagonal(); }
|
{ other.diagonal() -= diagonal(); }
|
||||||
|
|
||||||
inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); }
|
inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); }
|
||||||
@ -83,16 +82,18 @@ void DiagonalBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
|
|||||||
other.setZero();
|
other.setZero();
|
||||||
other.diagonal() = diagonal();
|
other.diagonal() = diagonal();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/** \class DiagonalMatrix
|
/** \class DiagonalMatrix
|
||||||
* \nonstableyet
|
|
||||||
*
|
*
|
||||||
* \brief Represents a diagonal matrix with its storage
|
* \brief Represents a diagonal matrix with its storage
|
||||||
*
|
*
|
||||||
* \param _Scalar the type of coefficients
|
* \param _Scalar the type of coefficients
|
||||||
* \param _Size the dimension of the matrix, or Dynamic
|
* \param SizeAtCompileTime the dimension of the matrix, or Dynamic
|
||||||
|
* \param MaxSizeAtCompileTime the dimension of the matrix, or Dynamic. This parameter is optional and defaults
|
||||||
|
* to SizeAtCompileTime. Most of the time, you do not need to specify it.
|
||||||
*
|
*
|
||||||
* \sa class Matrix
|
* \sa class DiagonalWrapper
|
||||||
*/
|
*/
|
||||||
template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime>
|
template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime>
|
||||||
struct ei_traits<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> >
|
struct ei_traits<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> >
|
||||||
@ -106,10 +107,11 @@ class DiagonalMatrix
|
|||||||
: public DiagonalBase<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> >
|
: public DiagonalBase<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
typedef typename ei_traits<DiagonalMatrix>::DiagonalVectorType DiagonalVectorType;
|
typedef typename ei_traits<DiagonalMatrix>::DiagonalVectorType DiagonalVectorType;
|
||||||
typedef const DiagonalMatrix& Nested;
|
typedef const DiagonalMatrix& Nested;
|
||||||
typedef _Scalar Scalar;
|
typedef _Scalar Scalar;
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -117,7 +119,9 @@ class DiagonalMatrix
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/** const version of diagonal(). */
|
||||||
inline const DiagonalVectorType& diagonal() const { return m_diagonal; }
|
inline const DiagonalVectorType& diagonal() const { return m_diagonal; }
|
||||||
|
/** \returns a reference to the stored vector of diagonal coefficients. */
|
||||||
inline DiagonalVectorType& diagonal() { return m_diagonal; }
|
inline DiagonalVectorType& diagonal() { return m_diagonal; }
|
||||||
|
|
||||||
/** Default constructor without initialization */
|
/** Default constructor without initialization */
|
||||||
@ -126,23 +130,27 @@ class DiagonalMatrix
|
|||||||
/** Constructs a diagonal matrix with given dimension */
|
/** Constructs a diagonal matrix with given dimension */
|
||||||
inline DiagonalMatrix(int dim) : m_diagonal(dim) {}
|
inline DiagonalMatrix(int dim) : m_diagonal(dim) {}
|
||||||
|
|
||||||
/** 2D only */
|
/** 2D constructor. */
|
||||||
inline DiagonalMatrix(const Scalar& x, const Scalar& y) : m_diagonal(x,y) {}
|
inline DiagonalMatrix(const Scalar& x, const Scalar& y) : m_diagonal(x,y) {}
|
||||||
|
|
||||||
/** 3D only */
|
/** 3D constructor. */
|
||||||
inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {}
|
inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {}
|
||||||
|
|
||||||
|
/** Copy constructor. */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
inline DiagonalMatrix(const DiagonalBase<OtherDerived>& other) : m_diagonal(other.diagonal()) {}
|
inline DiagonalMatrix(const DiagonalBase<OtherDerived>& other) : m_diagonal(other.diagonal()) {}
|
||||||
|
|
||||||
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
/** copy constructor. prevent a default copy constructor from hiding the other templated constructor */
|
/** copy constructor. prevent a default copy constructor from hiding the other templated constructor */
|
||||||
inline DiagonalMatrix(const DiagonalMatrix& other) : m_diagonal(other.diagonal()) {}
|
inline DiagonalMatrix(const DiagonalMatrix& other) : m_diagonal(other.diagonal()) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
/** generic constructor from expression of the diagonal coefficients */
|
/** generic constructor from expression of the diagonal coefficients */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
explicit inline DiagonalMatrix(const MatrixBase<OtherDerived>& other) : m_diagonal(other)
|
explicit inline DiagonalMatrix(const MatrixBase<OtherDerived>& other) : m_diagonal(other)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
/** Copy operator. */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
DiagonalMatrix& operator=(const DiagonalBase<OtherDerived>& other)
|
DiagonalMatrix& operator=(const DiagonalBase<OtherDerived>& other)
|
||||||
{
|
{
|
||||||
@ -150,6 +158,7 @@ class DiagonalMatrix
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
/** This is a special case of the templated operator=. Its purpose is to
|
/** This is a special case of the templated operator=. Its purpose is to
|
||||||
* prevent a default operator= from hiding the templated operator=.
|
* prevent a default operator= from hiding the templated operator=.
|
||||||
*/
|
*/
|
||||||
@ -158,23 +167,28 @@ class DiagonalMatrix
|
|||||||
m_diagonal = other.m_diagonal();
|
m_diagonal = other.m_diagonal();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Resizes to given size. */
|
||||||
inline void resize(int size) { m_diagonal.resize(size); }
|
inline void resize(int size) { m_diagonal.resize(size); }
|
||||||
|
/** Sets all coefficients to zero. */
|
||||||
inline void setZero() { m_diagonal.setZero(); }
|
inline void setZero() { m_diagonal.setZero(); }
|
||||||
|
/** Resizes and sets all coefficients to zero. */
|
||||||
inline void setZero(int size) { m_diagonal.setZero(size); }
|
inline void setZero(int size) { m_diagonal.setZero(size); }
|
||||||
|
/** Sets this matrix to be the identity matrix of the current size. */
|
||||||
inline void setIdentity() { m_diagonal.setOnes(); }
|
inline void setIdentity() { m_diagonal.setOnes(); }
|
||||||
|
/** Sets this matrix to be the identity matrix of the given size. */
|
||||||
inline void setIdentity(int size) { m_diagonal.setOnes(size); }
|
inline void setIdentity(int size) { m_diagonal.setOnes(size); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \class DiagonalWrapper
|
/** \class DiagonalWrapper
|
||||||
* \nonstableyet
|
|
||||||
*
|
*
|
||||||
* \brief Expression of a diagonal matrix
|
* \brief Expression of a diagonal matrix
|
||||||
*
|
*
|
||||||
* \param _DiagonalVectorType the type of the vector of diagonal coefficients
|
* \param _DiagonalVectorType the type of the vector of diagonal coefficients
|
||||||
*
|
*
|
||||||
* This class is an expression of a diagonal matrix with given vector of diagonal
|
* This class is an expression of a diagonal matrix, but not storing its own vector of diagonal coefficients,
|
||||||
* coefficients. It is the return type of MatrixBase::asDiagonal()
|
* instead wrapping an existing vector expression. It is the return type of MatrixBase::asDiagonal()
|
||||||
* and most of the time this is the only way that it is used.
|
* and most of the time this is the only way that it is used.
|
||||||
*
|
*
|
||||||
* \sa class DiagonalMatrix, class DiagonalBase, MatrixBase::asDiagonal()
|
* \sa class DiagonalMatrix, class DiagonalBase, MatrixBase::asDiagonal()
|
||||||
@ -198,18 +212,22 @@ class DiagonalWrapper
|
|||||||
: public DiagonalBase<DiagonalWrapper<_DiagonalVectorType> >, ei_no_assignment_operator
|
: public DiagonalBase<DiagonalWrapper<_DiagonalVectorType> >, ei_no_assignment_operator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
typedef _DiagonalVectorType DiagonalVectorType;
|
typedef _DiagonalVectorType DiagonalVectorType;
|
||||||
typedef DiagonalWrapper Nested;
|
typedef DiagonalWrapper Nested;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Constructor from expression of diagonal coefficients to wrap. */
|
||||||
inline DiagonalWrapper(const DiagonalVectorType& diagonal) : m_diagonal(diagonal) {}
|
inline DiagonalWrapper(const DiagonalVectorType& diagonal) : m_diagonal(diagonal) {}
|
||||||
|
|
||||||
|
/** \returns a const reference to the wrapped expression of diagonal coefficients. */
|
||||||
const DiagonalVectorType& diagonal() const { return m_diagonal; }
|
const DiagonalVectorType& diagonal() const { return m_diagonal; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const typename DiagonalVectorType::Nested m_diagonal;
|
const typename DiagonalVectorType::Nested m_diagonal;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \nonstableyet
|
/** \returns a pseudo-expression of a diagonal matrix with *this as vector of diagonal coefficients
|
||||||
* \returns a pseudo-expression of a diagonal matrix with *this as vector of diagonal coefficients
|
|
||||||
*
|
*
|
||||||
* \only_for_vectors
|
* \only_for_vectors
|
||||||
*
|
*
|
||||||
@ -225,8 +243,7 @@ MatrixBase<Derived>::asDiagonal() const
|
|||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \nonstableyet
|
/** \returns true if *this is approximately equal to a diagonal matrix,
|
||||||
* \returns true if *this is approximately equal to a diagonal matrix,
|
|
||||||
* within the precision given by \a prec.
|
* within the precision given by \a prec.
|
||||||
*
|
*
|
||||||
* Example: \include MatrixBase_isDiagonal.cpp
|
* Example: \include MatrixBase_isDiagonal.cpp
|
||||||
|
@ -34,10 +34,10 @@ struct ei_dot_traits
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
Vectorization = (int(Derived1::Flags)&int(Derived2::Flags)&ActualPacketAccessBit)
|
Traversal = (int(Derived1::Flags)&int(Derived2::Flags)&ActualPacketAccessBit)
|
||||||
&& (int(Derived1::Flags)&int(Derived2::Flags)&LinearAccessBit)
|
&& (int(Derived1::Flags)&int(Derived2::Flags)&LinearAccessBit)
|
||||||
? LinearVectorization
|
? LinearVectorizedTraversal
|
||||||
: NoVectorization
|
: DefaultTraversal
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -46,7 +46,7 @@ private:
|
|||||||
PacketSize = ei_packet_traits<Scalar>::size,
|
PacketSize = ei_packet_traits<Scalar>::size,
|
||||||
Cost = Derived1::SizeAtCompileTime * (Derived1::CoeffReadCost + Derived2::CoeffReadCost + NumTraits<Scalar>::MulCost)
|
Cost = Derived1::SizeAtCompileTime * (Derived1::CoeffReadCost + Derived2::CoeffReadCost + NumTraits<Scalar>::MulCost)
|
||||||
+ (Derived1::SizeAtCompileTime-1) * NumTraits<Scalar>::AddCost,
|
+ (Derived1::SizeAtCompileTime-1) * NumTraits<Scalar>::AddCost,
|
||||||
UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Vectorization) == int(NoVectorization) ? 1 : int(PacketSize))
|
UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Traversal) == int(DefaultTraversal) ? 1 : int(PacketSize))
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -142,13 +142,13 @@ struct ei_dot_vec_unroller<Derived1, Derived2, Index, Stop, true>
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2,
|
template<typename Derived1, typename Derived2,
|
||||||
int Vectorization = ei_dot_traits<Derived1, Derived2>::Vectorization,
|
int Traversal = ei_dot_traits<Derived1, Derived2>::Traversal,
|
||||||
int Unrolling = ei_dot_traits<Derived1, Derived2>::Unrolling
|
int Unrolling = ei_dot_traits<Derived1, Derived2>::Unrolling
|
||||||
>
|
>
|
||||||
struct ei_dot_impl;
|
struct ei_dot_impl;
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2>
|
template<typename Derived1, typename Derived2>
|
||||||
struct ei_dot_impl<Derived1, Derived2, NoVectorization, NoUnrolling>
|
struct ei_dot_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling>
|
||||||
{
|
{
|
||||||
typedef typename Derived1::Scalar Scalar;
|
typedef typename Derived1::Scalar Scalar;
|
||||||
static Scalar run(const Derived1& v1, const Derived2& v2)
|
static Scalar run(const Derived1& v1, const Derived2& v2)
|
||||||
@ -163,12 +163,12 @@ struct ei_dot_impl<Derived1, Derived2, NoVectorization, NoUnrolling>
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2>
|
template<typename Derived1, typename Derived2>
|
||||||
struct ei_dot_impl<Derived1, Derived2, NoVectorization, CompleteUnrolling>
|
struct ei_dot_impl<Derived1, Derived2, DefaultTraversal, CompleteUnrolling>
|
||||||
: public ei_dot_novec_unroller<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
|
: public ei_dot_novec_unroller<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2>
|
template<typename Derived1, typename Derived2>
|
||||||
struct ei_dot_impl<Derived1, Derived2, LinearVectorization, NoUnrolling>
|
struct ei_dot_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling>
|
||||||
{
|
{
|
||||||
typedef typename Derived1::Scalar Scalar;
|
typedef typename Derived1::Scalar Scalar;
|
||||||
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
|
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
|
||||||
@ -221,20 +221,20 @@ struct ei_dot_impl<Derived1, Derived2, LinearVectorization, NoUnrolling>
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2>
|
template<typename Derived1, typename Derived2>
|
||||||
struct ei_dot_impl<Derived1, Derived2, LinearVectorization, CompleteUnrolling>
|
struct ei_dot_impl<Derived1, Derived2, LinearVectorizedTraversal, CompleteUnrolling>
|
||||||
{
|
{
|
||||||
typedef typename Derived1::Scalar Scalar;
|
typedef typename Derived1::Scalar Scalar;
|
||||||
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
|
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
|
||||||
enum {
|
enum {
|
||||||
PacketSize = ei_packet_traits<Scalar>::size,
|
PacketSize = ei_packet_traits<Scalar>::size,
|
||||||
Size = Derived1::SizeAtCompileTime,
|
Size = Derived1::SizeAtCompileTime,
|
||||||
VectorizationSize = (Size / PacketSize) * PacketSize
|
VectorizedSize = (Size / PacketSize) * PacketSize
|
||||||
};
|
};
|
||||||
static Scalar run(const Derived1& v1, const Derived2& v2)
|
static Scalar run(const Derived1& v1, const Derived2& v2)
|
||||||
{
|
{
|
||||||
Scalar res = ei_predux(ei_dot_vec_unroller<Derived1, Derived2, 0, VectorizationSize>::run(v1, v2));
|
Scalar res = ei_predux(ei_dot_vec_unroller<Derived1, Derived2, 0, VectorizedSize>::run(v1, v2));
|
||||||
if (VectorizationSize != Size)
|
if (VectorizedSize != Size)
|
||||||
res += ei_dot_novec_unroller<Derived1, Derived2, VectorizationSize, Size-VectorizationSize>::run(v1, v2);
|
res += ei_dot_novec_unroller<Derived1, Derived2, VectorizedSize, Size-VectorizedSize>::run(v1, v2);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -37,12 +37,6 @@ template<typename XprType> struct ei_shape_of
|
|||||||
// matrix. Unless we change the overall design, here is a workaround.
|
// matrix. Unless we change the overall design, here is a workaround.
|
||||||
// There is an example in unsuported/Eigen/src/AutoDiff/AutoDiffScalar.
|
// There is an example in unsuported/Eigen/src/AutoDiff/AutoDiffScalar.
|
||||||
|
|
||||||
template<typename XprType, int Shape = ei_shape_of<XprType>::ret>
|
|
||||||
struct MakeNestByValue
|
|
||||||
{
|
|
||||||
typedef NestByValue<XprType> Type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Func, typename XprType, int Shape = ei_shape_of<XprType>::ret>
|
template<typename Func, typename XprType, int Shape = ei_shape_of<XprType>::ret>
|
||||||
struct MakeCwiseUnaryOp
|
struct MakeCwiseUnaryOp
|
||||||
{
|
{
|
||||||
|
@ -32,7 +32,8 @@
|
|||||||
*
|
*
|
||||||
* \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, MatrixBase::sum()
|
* \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, MatrixBase::sum()
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_sum_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_sum_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_sum_op)
|
||||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; }
|
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; }
|
||||||
template<typename PacketScalar>
|
template<typename PacketScalar>
|
||||||
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
|
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
|
||||||
@ -54,7 +55,8 @@ struct ei_functor_traits<ei_scalar_sum_op<Scalar> > {
|
|||||||
*
|
*
|
||||||
* \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux()
|
* \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux()
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_product_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_product_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_product_op)
|
||||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a * b; }
|
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a * b; }
|
||||||
template<typename PacketScalar>
|
template<typename PacketScalar>
|
||||||
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
|
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
|
||||||
@ -76,7 +78,8 @@ struct ei_functor_traits<ei_scalar_product_op<Scalar> > {
|
|||||||
*
|
*
|
||||||
* \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff()
|
* \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff()
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_min_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_min_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_min_op)
|
||||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::min(a, b); }
|
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::min(a, b); }
|
||||||
template<typename PacketScalar>
|
template<typename PacketScalar>
|
||||||
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
|
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
|
||||||
@ -98,7 +101,8 @@ struct ei_functor_traits<ei_scalar_min_op<Scalar> > {
|
|||||||
*
|
*
|
||||||
* \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff()
|
* \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff()
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_max_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_max_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_max_op)
|
||||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::max(a, b); }
|
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::max(a, b); }
|
||||||
template<typename PacketScalar>
|
template<typename PacketScalar>
|
||||||
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
|
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
|
||||||
@ -120,7 +124,8 @@ struct ei_functor_traits<ei_scalar_max_op<Scalar> > {
|
|||||||
*
|
*
|
||||||
* \sa MatrixBase::stableNorm(), class Redux
|
* \sa MatrixBase::stableNorm(), class Redux
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_hypot_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_hypot_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_hypot_op)
|
||||||
// typedef typename NumTraits<Scalar>::Real result_type;
|
// 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
|
||||||
{
|
{
|
||||||
@ -142,7 +147,8 @@ struct ei_functor_traits<ei_scalar_hypot_op<Scalar> > {
|
|||||||
*
|
*
|
||||||
* \sa class CwiseBinaryOp, MatrixBase::operator-
|
* \sa class CwiseBinaryOp, MatrixBase::operator-
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_difference_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_difference_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_difference_op)
|
||||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; }
|
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; }
|
||||||
template<typename PacketScalar>
|
template<typename PacketScalar>
|
||||||
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
|
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
|
||||||
@ -161,7 +167,8 @@ struct ei_functor_traits<ei_scalar_difference_op<Scalar> > {
|
|||||||
*
|
*
|
||||||
* \sa class CwiseBinaryOp, Cwise::operator/()
|
* \sa class CwiseBinaryOp, Cwise::operator/()
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_quotient_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_quotient_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_quotient_op)
|
||||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; }
|
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; }
|
||||||
template<typename PacketScalar>
|
template<typename PacketScalar>
|
||||||
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
|
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
|
||||||
@ -185,7 +192,8 @@ struct ei_functor_traits<ei_scalar_quotient_op<Scalar> > {
|
|||||||
*
|
*
|
||||||
* \sa class CwiseUnaryOp, MatrixBase::operator-
|
* \sa class CwiseUnaryOp, MatrixBase::operator-
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_opposite_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_opposite_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_opposite_op)
|
||||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; }
|
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; }
|
||||||
template<typename PacketScalar>
|
template<typename PacketScalar>
|
||||||
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
|
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
|
||||||
@ -203,7 +211,8 @@ struct ei_functor_traits<ei_scalar_opposite_op<Scalar> >
|
|||||||
*
|
*
|
||||||
* \sa class CwiseUnaryOp, Cwise::abs
|
* \sa class CwiseUnaryOp, Cwise::abs
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_abs_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_abs_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_abs_op)
|
||||||
typedef typename NumTraits<Scalar>::Real result_type;
|
typedef typename NumTraits<Scalar>::Real result_type;
|
||||||
EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return ei_abs(a); }
|
EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return ei_abs(a); }
|
||||||
template<typename PacketScalar>
|
template<typename PacketScalar>
|
||||||
@ -224,7 +233,8 @@ struct ei_functor_traits<ei_scalar_abs_op<Scalar> >
|
|||||||
*
|
*
|
||||||
* \sa class CwiseUnaryOp, Cwise::abs2
|
* \sa class CwiseUnaryOp, Cwise::abs2
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_abs2_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_abs2_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_abs2_op)
|
||||||
typedef typename NumTraits<Scalar>::Real result_type;
|
typedef typename NumTraits<Scalar>::Real result_type;
|
||||||
EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return ei_abs2(a); }
|
EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return ei_abs2(a); }
|
||||||
template<typename PacketScalar>
|
template<typename PacketScalar>
|
||||||
@ -240,7 +250,8 @@ struct ei_functor_traits<ei_scalar_abs2_op<Scalar> >
|
|||||||
*
|
*
|
||||||
* \sa class CwiseUnaryOp, MatrixBase::conjugate()
|
* \sa class CwiseUnaryOp, MatrixBase::conjugate()
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_conjugate_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_conjugate_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_conjugate_op)
|
||||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return ei_conj(a); }
|
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return ei_conj(a); }
|
||||||
template<typename PacketScalar>
|
template<typename PacketScalar>
|
||||||
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const { return a; }
|
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const { return a; }
|
||||||
@ -260,7 +271,8 @@ struct ei_functor_traits<ei_scalar_conjugate_op<Scalar> >
|
|||||||
* \sa class CwiseUnaryOp, MatrixBase::cast()
|
* \sa class CwiseUnaryOp, MatrixBase::cast()
|
||||||
*/
|
*/
|
||||||
template<typename Scalar, typename NewType>
|
template<typename Scalar, typename NewType>
|
||||||
struct ei_scalar_cast_op EIGEN_EMPTY_STRUCT {
|
struct ei_scalar_cast_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_cast_op)
|
||||||
typedef NewType result_type;
|
typedef NewType result_type;
|
||||||
EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return static_cast<NewType>(a); }
|
EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return static_cast<NewType>(a); }
|
||||||
};
|
};
|
||||||
@ -274,7 +286,8 @@ struct ei_functor_traits<ei_scalar_cast_op<Scalar,NewType> >
|
|||||||
* \sa class CwiseUnaryOp, MatrixBase::real()
|
* \sa class CwiseUnaryOp, MatrixBase::real()
|
||||||
*/
|
*/
|
||||||
template<typename Scalar>
|
template<typename Scalar>
|
||||||
struct ei_scalar_real_op EIGEN_EMPTY_STRUCT {
|
struct ei_scalar_real_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_real_op)
|
||||||
typedef typename NumTraits<Scalar>::Real result_type;
|
typedef typename NumTraits<Scalar>::Real result_type;
|
||||||
EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return ei_real(a); }
|
EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return ei_real(a); }
|
||||||
EIGEN_STRONG_INLINE result_type& operator() (Scalar& a) const { return ei_real_ref(a); }
|
EIGEN_STRONG_INLINE result_type& operator() (Scalar& a) const { return ei_real_ref(a); }
|
||||||
@ -289,7 +302,8 @@ struct ei_functor_traits<ei_scalar_real_op<Scalar> >
|
|||||||
* \sa class CwiseUnaryOp, MatrixBase::imag()
|
* \sa class CwiseUnaryOp, MatrixBase::imag()
|
||||||
*/
|
*/
|
||||||
template<typename Scalar>
|
template<typename Scalar>
|
||||||
struct ei_scalar_imag_op EIGEN_EMPTY_STRUCT {
|
struct ei_scalar_imag_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_imag_op)
|
||||||
typedef typename NumTraits<Scalar>::Real result_type;
|
typedef typename NumTraits<Scalar>::Real result_type;
|
||||||
EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return ei_imag(a); }
|
EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return ei_imag(a); }
|
||||||
EIGEN_STRONG_INLINE result_type& operator() (Scalar& a) const { return ei_imag_ref(a); }
|
EIGEN_STRONG_INLINE result_type& operator() (Scalar& a) const { return ei_imag_ref(a); }
|
||||||
@ -304,7 +318,8 @@ struct ei_functor_traits<ei_scalar_imag_op<Scalar> >
|
|||||||
*
|
*
|
||||||
* \sa class CwiseUnaryOp, Cwise::exp()
|
* \sa class CwiseUnaryOp, Cwise::exp()
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_exp_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_exp_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_exp_op)
|
||||||
inline const Scalar operator() (const Scalar& a) const { return ei_exp(a); }
|
inline const Scalar operator() (const Scalar& a) const { return ei_exp(a); }
|
||||||
typedef typename ei_packet_traits<Scalar>::type Packet;
|
typedef typename ei_packet_traits<Scalar>::type Packet;
|
||||||
inline Packet packetOp(const Packet& a) const { return ei_pexp(a); }
|
inline Packet packetOp(const Packet& a) const { return ei_pexp(a); }
|
||||||
@ -319,7 +334,8 @@ struct ei_functor_traits<ei_scalar_exp_op<Scalar> >
|
|||||||
*
|
*
|
||||||
* \sa class CwiseUnaryOp, Cwise::log()
|
* \sa class CwiseUnaryOp, Cwise::log()
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_log_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_log_op {
|
||||||
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_log_op)
|
||||||
inline const Scalar operator() (const Scalar& a) const { return ei_log(a); }
|
inline const Scalar operator() (const Scalar& a) const { return ei_log(a); }
|
||||||
typedef typename ei_packet_traits<Scalar>::type Packet;
|
typedef typename ei_packet_traits<Scalar>::type Packet;
|
||||||
inline Packet packetOp(const Packet& a) const { return ei_plog(a); }
|
inline Packet packetOp(const Packet& a) const { return ei_plog(a); }
|
||||||
@ -351,8 +367,6 @@ struct ei_scalar_multiple_op {
|
|||||||
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
|
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
|
||||||
{ return ei_pmul(a, ei_pset1(m_other)); }
|
{ return ei_pmul(a, ei_pset1(m_other)); }
|
||||||
typename ei_makeconst<typename NumTraits<Scalar>::Nested>::type m_other;
|
typename ei_makeconst<typename NumTraits<Scalar>::Nested>::type m_other;
|
||||||
private:
|
|
||||||
ei_scalar_multiple_op& operator=(const ei_scalar_multiple_op&);
|
|
||||||
};
|
};
|
||||||
template<typename Scalar>
|
template<typename Scalar>
|
||||||
struct ei_functor_traits<ei_scalar_multiple_op<Scalar> >
|
struct ei_functor_traits<ei_scalar_multiple_op<Scalar> >
|
||||||
@ -380,8 +394,6 @@ struct ei_scalar_quotient1_impl {
|
|||||||
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
|
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
|
||||||
{ return ei_pmul(a, ei_pset1(m_other)); }
|
{ return ei_pmul(a, ei_pset1(m_other)); }
|
||||||
const Scalar m_other;
|
const Scalar m_other;
|
||||||
private:
|
|
||||||
ei_scalar_quotient1_impl& operator=(const ei_scalar_quotient1_impl&);
|
|
||||||
};
|
};
|
||||||
template<typename Scalar>
|
template<typename Scalar>
|
||||||
struct ei_functor_traits<ei_scalar_quotient1_impl<Scalar,true> >
|
struct ei_functor_traits<ei_scalar_quotient1_impl<Scalar,true> >
|
||||||
@ -427,15 +439,13 @@ struct ei_scalar_constant_op {
|
|||||||
EIGEN_STRONG_INLINE const Scalar operator() (int, int = 0) const { return m_other; }
|
EIGEN_STRONG_INLINE const Scalar operator() (int, int = 0) const { return m_other; }
|
||||||
EIGEN_STRONG_INLINE const PacketScalar packetOp() const { return ei_pset1(m_other); }
|
EIGEN_STRONG_INLINE const PacketScalar packetOp() const { return ei_pset1(m_other); }
|
||||||
const Scalar m_other;
|
const Scalar m_other;
|
||||||
private:
|
|
||||||
ei_scalar_constant_op& operator=(const ei_scalar_constant_op&);
|
|
||||||
};
|
};
|
||||||
template<typename Scalar>
|
template<typename Scalar>
|
||||||
struct ei_functor_traits<ei_scalar_constant_op<Scalar> >
|
struct ei_functor_traits<ei_scalar_constant_op<Scalar> >
|
||||||
{ enum { Cost = 1, PacketAccess = ei_packet_traits<Scalar>::size>1, IsRepeatable = true }; };
|
{ enum { Cost = 1, PacketAccess = ei_packet_traits<Scalar>::size>1, IsRepeatable = true }; };
|
||||||
|
|
||||||
template<typename Scalar> struct ei_scalar_identity_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_identity_op {
|
||||||
EIGEN_STRONG_INLINE ei_scalar_identity_op(void) {}
|
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_identity_op)
|
||||||
EIGEN_STRONG_INLINE const Scalar operator() (int row, int col) const { return row==col ? Scalar(1) : Scalar(0); }
|
EIGEN_STRONG_INLINE const Scalar operator() (int row, int col) const { return row==col ? Scalar(1) : Scalar(0); }
|
||||||
};
|
};
|
||||||
template<typename Scalar>
|
template<typename Scalar>
|
||||||
|
@ -30,7 +30,7 @@ template<typename T> inline typename NumTraits<T>::Real epsilon()
|
|||||||
return std::numeric_limits<typename NumTraits<T>::Real>::epsilon();
|
return std::numeric_limits<typename NumTraits<T>::Real>::epsilon();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> inline typename NumTraits<T>::Real precision();
|
template<typename T> inline typename NumTraits<T>::Real dummy_precision();
|
||||||
|
|
||||||
template<typename T> inline T ei_random(T a, T b);
|
template<typename T> inline T ei_random(T a, T b);
|
||||||
template<typename T> inline T ei_random();
|
template<typename T> inline T ei_random();
|
||||||
@ -55,7 +55,7 @@ template<typename T> inline typename NumTraits<T>::Real ei_hypot(T x, T y)
|
|||||||
*** int ***
|
*** int ***
|
||||||
**************/
|
**************/
|
||||||
|
|
||||||
template<> inline int precision<int>() { return 0; }
|
template<> inline int dummy_precision<int>() { return 0; }
|
||||||
inline int ei_real(int x) { return x; }
|
inline int ei_real(int x) { return x; }
|
||||||
inline int& ei_real_ref(int& x) { return x; }
|
inline int& ei_real_ref(int& x) { return x; }
|
||||||
inline int ei_imag(int) { return 0; }
|
inline int ei_imag(int) { return 0; }
|
||||||
@ -92,15 +92,15 @@ template<> inline int ei_random()
|
|||||||
{
|
{
|
||||||
return ei_random<int>(-ei_random_amplitude<int>(), ei_random_amplitude<int>());
|
return ei_random<int>(-ei_random_amplitude<int>(), ei_random_amplitude<int>());
|
||||||
}
|
}
|
||||||
inline bool ei_isMuchSmallerThan(int a, int, int = precision<int>())
|
inline bool ei_isMuchSmallerThan(int a, int, int = dummy_precision<int>())
|
||||||
{
|
{
|
||||||
return a == 0;
|
return a == 0;
|
||||||
}
|
}
|
||||||
inline bool ei_isApprox(int a, int b, int = precision<int>())
|
inline bool ei_isApprox(int a, int b, int = dummy_precision<int>())
|
||||||
{
|
{
|
||||||
return a == b;
|
return a == b;
|
||||||
}
|
}
|
||||||
inline bool ei_isApproxOrLessThan(int a, int b, int = precision<int>())
|
inline bool ei_isApproxOrLessThan(int a, int b, int = dummy_precision<int>())
|
||||||
{
|
{
|
||||||
return a <= b;
|
return a <= b;
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@ inline bool ei_isApproxOrLessThan(int a, int b, int = precision<int>())
|
|||||||
*** float ***
|
*** float ***
|
||||||
**************/
|
**************/
|
||||||
|
|
||||||
template<> inline float precision<float>() { return 1e-5f; }
|
template<> inline float dummy_precision<float>() { return 1e-5f; }
|
||||||
inline float ei_real(float x) { return x; }
|
inline float ei_real(float x) { return x; }
|
||||||
inline float& ei_real_ref(float& x) { return x; }
|
inline float& ei_real_ref(float& x) { return x; }
|
||||||
inline float ei_imag(float) { return 0.f; }
|
inline float ei_imag(float) { return 0.f; }
|
||||||
@ -140,15 +140,15 @@ template<> inline float ei_random()
|
|||||||
{
|
{
|
||||||
return ei_random<float>(-ei_random_amplitude<float>(), ei_random_amplitude<float>());
|
return ei_random<float>(-ei_random_amplitude<float>(), ei_random_amplitude<float>());
|
||||||
}
|
}
|
||||||
inline bool ei_isMuchSmallerThan(float a, float b, float prec = precision<float>())
|
inline bool ei_isMuchSmallerThan(float a, float b, float prec = dummy_precision<float>())
|
||||||
{
|
{
|
||||||
return ei_abs(a) <= ei_abs(b) * prec;
|
return ei_abs(a) <= ei_abs(b) * prec;
|
||||||
}
|
}
|
||||||
inline bool ei_isApprox(float a, float b, float prec = precision<float>())
|
inline bool ei_isApprox(float a, float b, float prec = dummy_precision<float>())
|
||||||
{
|
{
|
||||||
return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec;
|
return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec;
|
||||||
}
|
}
|
||||||
inline bool ei_isApproxOrLessThan(float a, float b, float prec = precision<float>())
|
inline bool ei_isApproxOrLessThan(float a, float b, float prec = dummy_precision<float>())
|
||||||
{
|
{
|
||||||
return a <= b || ei_isApprox(a, b, prec);
|
return a <= b || ei_isApprox(a, b, prec);
|
||||||
}
|
}
|
||||||
@ -157,7 +157,7 @@ inline bool ei_isApproxOrLessThan(float a, float b, float prec = precision<float
|
|||||||
*** double ***
|
*** double ***
|
||||||
**************/
|
**************/
|
||||||
|
|
||||||
template<> inline double precision<double>() { return 1e-12; }
|
template<> inline double dummy_precision<double>() { return 1e-12; }
|
||||||
|
|
||||||
inline double ei_real(double x) { return x; }
|
inline double ei_real(double x) { return x; }
|
||||||
inline double& ei_real_ref(double& x) { return x; }
|
inline double& ei_real_ref(double& x) { return x; }
|
||||||
@ -189,15 +189,15 @@ template<> inline double ei_random()
|
|||||||
{
|
{
|
||||||
return ei_random<double>(-ei_random_amplitude<double>(), ei_random_amplitude<double>());
|
return ei_random<double>(-ei_random_amplitude<double>(), ei_random_amplitude<double>());
|
||||||
}
|
}
|
||||||
inline bool ei_isMuchSmallerThan(double a, double b, double prec = precision<double>())
|
inline bool ei_isMuchSmallerThan(double a, double b, double prec = dummy_precision<double>())
|
||||||
{
|
{
|
||||||
return ei_abs(a) <= ei_abs(b) * prec;
|
return ei_abs(a) <= ei_abs(b) * prec;
|
||||||
}
|
}
|
||||||
inline bool ei_isApprox(double a, double b, double prec = precision<double>())
|
inline bool ei_isApprox(double a, double b, double prec = dummy_precision<double>())
|
||||||
{
|
{
|
||||||
return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec;
|
return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec;
|
||||||
}
|
}
|
||||||
inline bool ei_isApproxOrLessThan(double a, double b, double prec = precision<double>())
|
inline bool ei_isApproxOrLessThan(double a, double b, double prec = dummy_precision<double>())
|
||||||
{
|
{
|
||||||
return a <= b || ei_isApprox(a, b, prec);
|
return a <= b || ei_isApprox(a, b, prec);
|
||||||
}
|
}
|
||||||
@ -206,7 +206,7 @@ inline bool ei_isApproxOrLessThan(double a, double b, double prec = precision<do
|
|||||||
*** complex<float> ***
|
*** complex<float> ***
|
||||||
*********************/
|
*********************/
|
||||||
|
|
||||||
template<> inline float precision<std::complex<float> >() { return precision<float>(); }
|
template<> inline float dummy_precision<std::complex<float> >() { return dummy_precision<float>(); }
|
||||||
inline float ei_real(const std::complex<float>& x) { return std::real(x); }
|
inline float ei_real(const std::complex<float>& x) { return std::real(x); }
|
||||||
inline float ei_imag(const std::complex<float>& x) { return std::imag(x); }
|
inline float ei_imag(const std::complex<float>& x) { return std::imag(x); }
|
||||||
inline float& ei_real_ref(std::complex<float>& x) { return reinterpret_cast<float*>(&x)[0]; }
|
inline float& ei_real_ref(std::complex<float>& x) { return reinterpret_cast<float*>(&x)[0]; }
|
||||||
@ -224,15 +224,15 @@ template<> inline std::complex<float> ei_random()
|
|||||||
{
|
{
|
||||||
return std::complex<float>(ei_random<float>(), ei_random<float>());
|
return std::complex<float>(ei_random<float>(), ei_random<float>());
|
||||||
}
|
}
|
||||||
inline bool ei_isMuchSmallerThan(const std::complex<float>& a, const std::complex<float>& b, float prec = precision<float>())
|
inline bool ei_isMuchSmallerThan(const std::complex<float>& a, const std::complex<float>& b, float prec = dummy_precision<float>())
|
||||||
{
|
{
|
||||||
return ei_abs2(a) <= ei_abs2(b) * prec * prec;
|
return ei_abs2(a) <= ei_abs2(b) * prec * prec;
|
||||||
}
|
}
|
||||||
inline bool ei_isMuchSmallerThan(const std::complex<float>& a, float b, float prec = precision<float>())
|
inline bool ei_isMuchSmallerThan(const std::complex<float>& a, float b, float prec = dummy_precision<float>())
|
||||||
{
|
{
|
||||||
return ei_abs2(a) <= ei_abs2(b) * prec * prec;
|
return ei_abs2(a) <= ei_abs2(b) * prec * prec;
|
||||||
}
|
}
|
||||||
inline bool ei_isApprox(const std::complex<float>& a, const std::complex<float>& b, float prec = precision<float>())
|
inline bool ei_isApprox(const std::complex<float>& a, const std::complex<float>& b, float prec = dummy_precision<float>())
|
||||||
{
|
{
|
||||||
return ei_isApprox(ei_real(a), ei_real(b), prec)
|
return ei_isApprox(ei_real(a), ei_real(b), prec)
|
||||||
&& ei_isApprox(ei_imag(a), ei_imag(b), prec);
|
&& ei_isApprox(ei_imag(a), ei_imag(b), prec);
|
||||||
@ -243,7 +243,7 @@ inline bool ei_isApprox(const std::complex<float>& a, const std::complex<float>&
|
|||||||
*** complex<double> ***
|
*** complex<double> ***
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
template<> inline double precision<std::complex<double> >() { return precision<double>(); }
|
template<> inline double dummy_precision<std::complex<double> >() { return dummy_precision<double>(); }
|
||||||
inline double ei_real(const std::complex<double>& x) { return std::real(x); }
|
inline double ei_real(const std::complex<double>& x) { return std::real(x); }
|
||||||
inline double ei_imag(const std::complex<double>& x) { return std::imag(x); }
|
inline double ei_imag(const std::complex<double>& x) { return std::imag(x); }
|
||||||
inline double& ei_real_ref(std::complex<double>& x) { return reinterpret_cast<double*>(&x)[0]; }
|
inline double& ei_real_ref(std::complex<double>& x) { return reinterpret_cast<double*>(&x)[0]; }
|
||||||
@ -261,15 +261,15 @@ template<> inline std::complex<double> ei_random()
|
|||||||
{
|
{
|
||||||
return std::complex<double>(ei_random<double>(), ei_random<double>());
|
return std::complex<double>(ei_random<double>(), ei_random<double>());
|
||||||
}
|
}
|
||||||
inline bool ei_isMuchSmallerThan(const std::complex<double>& a, const std::complex<double>& b, double prec = precision<double>())
|
inline bool ei_isMuchSmallerThan(const std::complex<double>& a, const std::complex<double>& b, double prec = dummy_precision<double>())
|
||||||
{
|
{
|
||||||
return ei_abs2(a) <= ei_abs2(b) * prec * prec;
|
return ei_abs2(a) <= ei_abs2(b) * prec * prec;
|
||||||
}
|
}
|
||||||
inline bool ei_isMuchSmallerThan(const std::complex<double>& a, double b, double prec = precision<double>())
|
inline bool ei_isMuchSmallerThan(const std::complex<double>& a, double b, double prec = dummy_precision<double>())
|
||||||
{
|
{
|
||||||
return ei_abs2(a) <= ei_abs2(b) * prec * prec;
|
return ei_abs2(a) <= ei_abs2(b) * prec * prec;
|
||||||
}
|
}
|
||||||
inline bool ei_isApprox(const std::complex<double>& a, const std::complex<double>& b, double prec = precision<double>())
|
inline bool ei_isApprox(const std::complex<double>& a, const std::complex<double>& b, double prec = dummy_precision<double>())
|
||||||
{
|
{
|
||||||
return ei_isApprox(ei_real(a), ei_real(b), prec)
|
return ei_isApprox(ei_real(a), ei_real(b), prec)
|
||||||
&& ei_isApprox(ei_imag(a), ei_imag(b), prec);
|
&& ei_isApprox(ei_imag(a), ei_imag(b), prec);
|
||||||
@ -281,7 +281,7 @@ inline bool ei_isApprox(const std::complex<double>& a, const std::complex<double
|
|||||||
*** long double ***
|
*** long double ***
|
||||||
******************/
|
******************/
|
||||||
|
|
||||||
template<> inline long double precision<long double>() { return precision<double>(); }
|
template<> inline long double dummy_precision<long double>() { return dummy_precision<double>(); }
|
||||||
inline long double ei_real(long double x) { return x; }
|
inline long double ei_real(long double x) { return x; }
|
||||||
inline long double& ei_real_ref(long double& x) { return x; }
|
inline long double& ei_real_ref(long double& x) { return x; }
|
||||||
inline long double ei_imag(long double) { return 0.; }
|
inline long double ei_imag(long double) { return 0.; }
|
||||||
@ -304,15 +304,15 @@ template<> inline long double ei_random()
|
|||||||
{
|
{
|
||||||
return ei_random<double>(-ei_random_amplitude<double>(), ei_random_amplitude<double>());
|
return ei_random<double>(-ei_random_amplitude<double>(), ei_random_amplitude<double>());
|
||||||
}
|
}
|
||||||
inline bool ei_isMuchSmallerThan(long double a, long double b, long double prec = precision<long double>())
|
inline bool ei_isMuchSmallerThan(long double a, long double b, long double prec = dummy_precision<long double>())
|
||||||
{
|
{
|
||||||
return ei_abs(a) <= ei_abs(b) * prec;
|
return ei_abs(a) <= ei_abs(b) * prec;
|
||||||
}
|
}
|
||||||
inline bool ei_isApprox(long double a, long double b, long double prec = precision<long double>())
|
inline bool ei_isApprox(long double a, long double b, long double prec = dummy_precision<long double>())
|
||||||
{
|
{
|
||||||
return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec;
|
return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec;
|
||||||
}
|
}
|
||||||
inline bool ei_isApproxOrLessThan(long double a, long double b, long double prec = precision<long double>())
|
inline bool ei_isApproxOrLessThan(long double a, long double b, long double prec = dummy_precision<long double>())
|
||||||
{
|
{
|
||||||
return a <= b || ei_isApprox(a, b, prec);
|
return a <= b || ei_isApprox(a, b, prec);
|
||||||
}
|
}
|
||||||
@ -321,7 +321,7 @@ inline bool ei_isApproxOrLessThan(long double a, long double b, long double prec
|
|||||||
*** bool ***
|
*** bool ***
|
||||||
**************/
|
**************/
|
||||||
|
|
||||||
template<> inline bool precision<bool>() { return 0; }
|
template<> inline bool dummy_precision<bool>() { return 0; }
|
||||||
inline bool ei_real(bool x) { return x; }
|
inline bool ei_real(bool x) { return x; }
|
||||||
inline bool& ei_real_ref(bool& x) { return x; }
|
inline bool& ei_real_ref(bool& x) { return x; }
|
||||||
inline bool ei_imag(bool) { return 0; }
|
inline bool ei_imag(bool) { return 0; }
|
||||||
@ -334,15 +334,15 @@ template<> inline bool ei_random()
|
|||||||
{
|
{
|
||||||
return (ei_random<int>(0,1) == 1);
|
return (ei_random<int>(0,1) == 1);
|
||||||
}
|
}
|
||||||
inline bool ei_isMuchSmallerThan(bool a, bool, bool = precision<bool>())
|
inline bool ei_isMuchSmallerThan(bool a, bool, bool = dummy_precision<bool>())
|
||||||
{
|
{
|
||||||
return !a;
|
return !a;
|
||||||
}
|
}
|
||||||
inline bool ei_isApprox(bool a, bool b, bool = precision<bool>())
|
inline bool ei_isApprox(bool a, bool b, bool = dummy_precision<bool>())
|
||||||
{
|
{
|
||||||
return a == b;
|
return a == b;
|
||||||
}
|
}
|
||||||
inline bool ei_isApproxOrLessThan(bool a, bool b, bool = precision<bool>())
|
inline bool ei_isApproxOrLessThan(bool a, bool b, bool = dummy_precision<bool>())
|
||||||
{
|
{
|
||||||
return int(a) <= int(b);
|
return int(a) <= int(b);
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,6 @@ class Matrix
|
|||||||
using Base::coeff;
|
using Base::coeff;
|
||||||
using Base::coeffRef;
|
using Base::coeffRef;
|
||||||
|
|
||||||
|
|
||||||
/** Copies the value of the expression \a other into \c *this with automatic resizing.
|
/** Copies the value of the expression \a other into \c *this with automatic resizing.
|
||||||
*
|
*
|
||||||
* *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
|
* *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
|
||||||
@ -286,9 +285,6 @@ class Matrix
|
|||||||
other.evalTo(*this);
|
other.evalTo(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Destructor */
|
|
||||||
inline ~Matrix() {}
|
|
||||||
|
|
||||||
/** \sa MatrixBase::operator=(const AnyMatrixBase<OtherDerived>&) */
|
/** \sa MatrixBase::operator=(const AnyMatrixBase<OtherDerived>&) */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_STRONG_INLINE Matrix(const AnyMatrixBase<OtherDerived> &other)
|
EIGEN_STRONG_INLINE Matrix(const AnyMatrixBase<OtherDerived> &other)
|
||||||
|
@ -144,7 +144,7 @@ template<typename Derived> class MatrixBase
|
|||||||
typedef CwiseNullaryOp<ei_scalar_constant_op<Scalar>,Derived> ConstantReturnType;
|
typedef CwiseNullaryOp<ei_scalar_constant_op<Scalar>,Derived> ConstantReturnType;
|
||||||
/** \internal the return type of MatrixBase::adjoint() */
|
/** \internal the return type of MatrixBase::adjoint() */
|
||||||
typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
|
typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
|
||||||
CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<Derived> > >,
|
CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::Transpose<Derived> >,
|
||||||
Transpose<Derived>
|
Transpose<Derived>
|
||||||
>::ret AdjointReturnType;
|
>::ret AdjointReturnType;
|
||||||
/** \internal the return type of MatrixBase::eigenvalues() */
|
/** \internal the return type of MatrixBase::eigenvalues() */
|
||||||
@ -259,16 +259,16 @@ template<typename Derived> class MatrixBase
|
|||||||
|
|
||||||
Derived& setIdentity();
|
Derived& setIdentity();
|
||||||
|
|
||||||
bool isIdentity(RealScalar prec = precision<Scalar>()) const;
|
bool isIdentity(RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
bool isDiagonal(RealScalar prec = precision<Scalar>()) const;
|
bool isDiagonal(RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
|
|
||||||
bool isUpperTriangular(RealScalar prec = precision<Scalar>()) const;
|
bool isUpperTriangular(RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
bool isLowerTriangular(RealScalar prec = precision<Scalar>()) const;
|
bool isLowerTriangular(RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
bool isOrthogonal(const MatrixBase<OtherDerived>& other,
|
bool isOrthogonal(const MatrixBase<OtherDerived>& other,
|
||||||
RealScalar prec = precision<Scalar>()) const;
|
RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
bool isUnitary(RealScalar prec = precision<Scalar>()) const;
|
bool isUnitary(RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
|
|
||||||
/** \returns true if each coefficients of \c *this and \a other are all exactly equal.
|
/** \returns true if each coefficients of \c *this and \a other are all exactly equal.
|
||||||
* \warning When using floating point scalar values you probably should rather use a
|
* \warning When using floating point scalar values you probably should rather use a
|
||||||
@ -332,13 +332,13 @@ template<typename Derived> class MatrixBase
|
|||||||
ResultType& inverse,
|
ResultType& inverse,
|
||||||
typename ResultType::Scalar& determinant,
|
typename ResultType::Scalar& determinant,
|
||||||
bool& invertible,
|
bool& invertible,
|
||||||
const RealScalar& absDeterminantThreshold = precision<Scalar>()
|
const RealScalar& absDeterminantThreshold = dummy_precision<Scalar>()
|
||||||
) const;
|
) const;
|
||||||
template<typename ResultType>
|
template<typename ResultType>
|
||||||
void computeInverseWithCheck(
|
void computeInverseWithCheck(
|
||||||
ResultType& inverse,
|
ResultType& inverse,
|
||||||
bool& invertible,
|
bool& invertible,
|
||||||
const RealScalar& absDeterminantThreshold = precision<Scalar>()
|
const RealScalar& absDeterminantThreshold = dummy_precision<Scalar>()
|
||||||
) const;
|
) const;
|
||||||
Scalar determinant() const;
|
Scalar determinant() const;
|
||||||
|
|
||||||
@ -376,7 +376,7 @@ template<typename Derived> class MatrixBase
|
|||||||
ei_traits<Derived>::ColsAtCompileTime==1 ? SizeMinusOne : 1,
|
ei_traits<Derived>::ColsAtCompileTime==1 ? SizeMinusOne : 1,
|
||||||
ei_traits<Derived>::ColsAtCompileTime==1 ? 1 : SizeMinusOne> StartMinusOne;
|
ei_traits<Derived>::ColsAtCompileTime==1 ? 1 : SizeMinusOne> StartMinusOne;
|
||||||
typedef CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>,
|
typedef CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>,
|
||||||
NestByValue<StartMinusOne> > HNormalizedReturnType;
|
StartMinusOne > HNormalizedReturnType;
|
||||||
|
|
||||||
const HNormalizedReturnType hnormalized() const;
|
const HNormalizedReturnType hnormalized() const;
|
||||||
typedef Homogeneous<Derived,MatrixBase<Derived>::ColsAtCompileTime==1?Vertical:Horizontal> HomogeneousReturnType;
|
typedef Homogeneous<Derived,MatrixBase<Derived>::ColsAtCompileTime==1?Vertical:Horizontal> HomogeneousReturnType;
|
||||||
|
@ -117,7 +117,6 @@ template<typename T, int Size, int _Options> class ei_matrix_storage<T, Size, Dy
|
|||||||
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
|
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
|
||||||
: m_data(ei_constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
|
: m_data(ei_constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
|
||||||
inline ei_matrix_storage(int, int rows, int cols) : m_rows(rows), m_cols(cols) {}
|
inline ei_matrix_storage(int, int rows, int cols) : m_rows(rows), m_cols(cols) {}
|
||||||
inline ~ei_matrix_storage() {}
|
|
||||||
inline void swap(ei_matrix_storage& other)
|
inline void swap(ei_matrix_storage& other)
|
||||||
{ std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
|
{ std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
|
||||||
inline int rows(void) const {return m_rows;}
|
inline int rows(void) const {return m_rows;}
|
||||||
@ -141,7 +140,6 @@ template<typename T, int Size, int _Cols, int _Options> class ei_matrix_storage<
|
|||||||
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
|
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
|
||||||
: m_data(ei_constructor_without_unaligned_array_assert()), m_rows(0) {}
|
: m_data(ei_constructor_without_unaligned_array_assert()), m_rows(0) {}
|
||||||
inline ei_matrix_storage(int, int rows, int) : m_rows(rows) {}
|
inline ei_matrix_storage(int, int rows, int) : m_rows(rows) {}
|
||||||
inline ~ei_matrix_storage() {}
|
|
||||||
inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
|
inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
|
||||||
inline int rows(void) const {return m_rows;}
|
inline int rows(void) const {return m_rows;}
|
||||||
inline int cols(void) const {return _Cols;}
|
inline int cols(void) const {return _Cols;}
|
||||||
@ -163,7 +161,6 @@ template<typename T, int Size, int _Rows, int _Options> class ei_matrix_storage<
|
|||||||
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
|
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
|
||||||
: m_data(ei_constructor_without_unaligned_array_assert()), m_cols(0) {}
|
: m_data(ei_constructor_without_unaligned_array_assert()), m_cols(0) {}
|
||||||
inline ei_matrix_storage(int, int, int cols) : m_cols(cols) {}
|
inline ei_matrix_storage(int, int, int cols) : m_cols(cols) {}
|
||||||
inline ~ei_matrix_storage() {}
|
|
||||||
inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
|
inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
|
||||||
inline int rows(void) const {return _Rows;}
|
inline int rows(void) const {return _Rows;}
|
||||||
inline int cols(void) const {return m_cols;}
|
inline int cols(void) const {return m_cols;}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
// for linear algebra.
|
// for linear algebra.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
//
|
//
|
||||||
// Eigen is free software; you can redistribute it and/or
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
@ -54,7 +54,8 @@ struct ei_traits<Minor<MatrixType> >
|
|||||||
MaxColsAtCompileTime = (MatrixType::MaxColsAtCompileTime != Dynamic) ?
|
MaxColsAtCompileTime = (MatrixType::MaxColsAtCompileTime != Dynamic) ?
|
||||||
int(MatrixType::MaxColsAtCompileTime) - 1 : Dynamic,
|
int(MatrixType::MaxColsAtCompileTime) - 1 : Dynamic,
|
||||||
Flags = _MatrixTypeNested::Flags & HereditaryBits,
|
Flags = _MatrixTypeNested::Flags & HereditaryBits,
|
||||||
CoeffReadCost = _MatrixTypeNested::CoeffReadCost
|
CoeffReadCost = _MatrixTypeNested::CoeffReadCost // minor is used typically on tiny matrices,
|
||||||
|
// where loops are unrolled and the 'if' evaluates at compile time
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -102,9 +102,6 @@ template<typename ExpressionType> class NestByValue
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
const ExpressionType m_expression;
|
const ExpressionType m_expression;
|
||||||
|
|
||||||
private:
|
|
||||||
NestByValue& operator=(const NestByValue&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \returns an expression of the temporary version of *this.
|
/** \returns an expression of the temporary version of *this.
|
||||||
|
@ -73,9 +73,6 @@ class NoAlias
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
ExpressionType& m_expression;
|
ExpressionType& m_expression;
|
||||||
|
|
||||||
private:
|
|
||||||
NoAlias& operator=(const NoAlias&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \returns a pseudo expression of \c *this with an operator= assuming
|
/** \returns a pseudo expression of \c *this with an operator= assuming
|
||||||
|
@ -25,18 +25,24 @@
|
|||||||
#ifndef EIGEN_PERMUTATIONMATRIX_H
|
#ifndef EIGEN_PERMUTATIONMATRIX_H
|
||||||
#define EIGEN_PERMUTATIONMATRIX_H
|
#define EIGEN_PERMUTATIONMATRIX_H
|
||||||
|
|
||||||
/** \nonstableyet
|
/** \class PermutationMatrix
|
||||||
* \class PermutationMatrix
|
|
||||||
*
|
*
|
||||||
* \brief Permutation matrix
|
* \brief Permutation matrix
|
||||||
*
|
*
|
||||||
* \param SizeAtCompileTime the number of rows/cols, or Dynamic
|
* \param SizeAtCompileTime the number of rows/cols, or Dynamic
|
||||||
* \param MaxSizeAtCompileTime the maximum number of rows/cols, or Dynamic. This optional parameter defaults to SizeAtCompileTime.
|
* \param MaxSizeAtCompileTime the maximum number of rows/cols, or Dynamic. This optional parameter defaults to SizeAtCompileTime. Most of the time, you should not have to specify it.
|
||||||
*
|
*
|
||||||
* This class represents a permutation matrix, internally stored as a vector of integers.
|
* This class represents a permutation matrix, internally stored as a vector of integers.
|
||||||
* The convention followed here is the same as on <a href="http://en.wikipedia.org/wiki/Permutation_matrix">Wikipedia</a>,
|
* The convention followed here is that if \f$ \sigma \f$ is a permutation, the corresponding permutation matrix
|
||||||
* namely: the matrix of permutation \a p is the matrix such that on each row \a i, the only nonzero coefficient is
|
* \f$ P_\sigma \f$ is such that if \f$ (e_1,\ldots,e_p) \f$ is the canonical basis, we have:
|
||||||
* in column p(i).
|
* \f[ P_\sigma(e_i) = e_{\sigma(i)}. \f]
|
||||||
|
* This convention ensures that for any two permutations \f$ \sigma, \tau \f$, we have:
|
||||||
|
* \f[ P_{\sigma\circ\tau} = P_\sigma P_\tau. \f]
|
||||||
|
*
|
||||||
|
* Permutation matrices are square and invertible.
|
||||||
|
*
|
||||||
|
* Notice that in addition to the member functions and operators listed here, there also are non-member
|
||||||
|
* operator* to multiply a PermutationMatrix with any kind of matrix expression (MatrixBase) on either side.
|
||||||
*
|
*
|
||||||
* \sa class DiagonalMatrix
|
* \sa class DiagonalMatrix
|
||||||
*/
|
*/
|
||||||
@ -53,6 +59,7 @@ class PermutationMatrix : public AnyMatrixBase<PermutationMatrix<SizeAtCompileTi
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
typedef ei_traits<PermutationMatrix> Traits;
|
typedef ei_traits<PermutationMatrix> Traits;
|
||||||
typedef Matrix<int,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime>
|
typedef Matrix<int,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime>
|
||||||
DenseMatrixType;
|
DenseMatrixType;
|
||||||
@ -65,25 +72,37 @@ class PermutationMatrix : public AnyMatrixBase<PermutationMatrix<SizeAtCompileTi
|
|||||||
MaxColsAtCompileTime = Traits::MaxColsAtCompileTime
|
MaxColsAtCompileTime = Traits::MaxColsAtCompileTime
|
||||||
};
|
};
|
||||||
typedef typename Traits::Scalar Scalar;
|
typedef typename Traits::Scalar Scalar;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef Matrix<int, RowsAtCompileTime, 1, 0, MaxRowsAtCompileTime, 1> IndicesType;
|
typedef Matrix<int, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType;
|
||||||
|
|
||||||
inline PermutationMatrix()
|
inline PermutationMatrix()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Copy constructor. */
|
||||||
template<int OtherSize, int OtherMaxSize>
|
template<int OtherSize, int OtherMaxSize>
|
||||||
inline PermutationMatrix(const PermutationMatrix<OtherSize, OtherMaxSize>& other)
|
inline PermutationMatrix(const PermutationMatrix<OtherSize, OtherMaxSize>& other)
|
||||||
: m_indices(other.indices()) {}
|
: m_indices(other.indices()) {}
|
||||||
|
|
||||||
/** copy constructor. prevent a default copy constructor from hiding the other templated constructor */
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
/** Standard copy constructor. Defined only to prevent a default copy constructor
|
||||||
|
* from hiding the other templated constructor */
|
||||||
inline PermutationMatrix(const PermutationMatrix& other) : m_indices(other.indices()) {}
|
inline PermutationMatrix(const PermutationMatrix& other) : m_indices(other.indices()) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
/** generic constructor from expression of the indices */
|
/** Generic constructor from expression of the indices. The indices
|
||||||
|
* array has the meaning that the permutations sends each integer i to indices[i].
|
||||||
|
*
|
||||||
|
* \warning It is your responsibility to check that the indices array that you passes actually
|
||||||
|
* describes a permutation, i.e., each value between 0 and n-1 occurs exactly once, where n is the
|
||||||
|
* array's size.
|
||||||
|
*/
|
||||||
template<typename Other>
|
template<typename Other>
|
||||||
explicit inline PermutationMatrix(const MatrixBase<Other>& other) : m_indices(other)
|
explicit inline PermutationMatrix(const MatrixBase<Other>& indices) : m_indices(indices)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
/** Copies the other permutation into *this */
|
||||||
template<int OtherSize, int OtherMaxSize>
|
template<int OtherSize, int OtherMaxSize>
|
||||||
PermutationMatrix& operator=(const PermutationMatrix<OtherSize, OtherMaxSize>& other)
|
PermutationMatrix& operator=(const PermutationMatrix<OtherSize, OtherMaxSize>& other)
|
||||||
{
|
{
|
||||||
@ -91,42 +110,143 @@ class PermutationMatrix : public AnyMatrixBase<PermutationMatrix<SizeAtCompileTi
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
/** This is a special case of the templated operator=. Its purpose is to
|
/** This is a special case of the templated operator=. Its purpose is to
|
||||||
* prevent a default operator= from hiding the templated operator=.
|
* prevent a default operator= from hiding the templated operator=.
|
||||||
*/
|
*/
|
||||||
PermutationMatrix& operator=(const PermutationMatrix& other)
|
PermutationMatrix& operator=(const PermutationMatrix& other)
|
||||||
{
|
{
|
||||||
m_indices = other.m_indices();
|
m_indices = other.m_indices;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
inline PermutationMatrix(int rows, int cols) : m_indices(rows)
|
/** Constructs an uninitialized permutation matrix of given size.
|
||||||
{
|
*/
|
||||||
ei_assert(rows == cols);
|
inline PermutationMatrix(int size) : m_indices(size)
|
||||||
}
|
{}
|
||||||
|
|
||||||
/** \returns the number of columns */
|
|
||||||
inline int rows() const { return m_indices.size(); }
|
|
||||||
|
|
||||||
/** \returns the number of rows */
|
/** \returns the number of rows */
|
||||||
|
inline int rows() const { return m_indices.size(); }
|
||||||
|
|
||||||
|
/** \returns the number of columns */
|
||||||
inline int cols() const { return m_indices.size(); }
|
inline int cols() const { return m_indices.size(); }
|
||||||
|
|
||||||
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
template<typename DenseDerived>
|
template<typename DenseDerived>
|
||||||
void evalTo(MatrixBase<DenseDerived>& other) const
|
void evalTo(MatrixBase<DenseDerived>& other) const
|
||||||
{
|
{
|
||||||
other.setZero();
|
other.setZero();
|
||||||
for (int i=0; i<rows();++i)
|
for (int i=0; i<rows();++i)
|
||||||
other.coeffRef(i,m_indices.coeff(i)) = typename DenseDerived::Scalar(1);
|
other.coeffRef(m_indices.coeff(i),i) = typename DenseDerived::Scalar(1);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \returns a Matrix object initialized from this permutation matrix. Notice that it
|
||||||
|
* is inefficient to return this Matrix object by value. For efficiency, favor using
|
||||||
|
* the Matrix constructor taking AnyMatrixBase objects.
|
||||||
|
*/
|
||||||
DenseMatrixType toDenseMatrix() const
|
DenseMatrixType toDenseMatrix() const
|
||||||
{
|
{
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** const version of indices(). */
|
||||||
const IndicesType& indices() const { return m_indices; }
|
const IndicesType& indices() const { return m_indices; }
|
||||||
|
/** \returns a reference to the stored array representing the permutation. */
|
||||||
IndicesType& indices() { return m_indices; }
|
IndicesType& indices() { return m_indices; }
|
||||||
|
|
||||||
|
/** Resizes to given size.
|
||||||
|
*/
|
||||||
|
inline void resize(int size)
|
||||||
|
{
|
||||||
|
m_indices.resize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets *this to be the identity permutation matrix */
|
||||||
|
void setIdentity()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < m_indices.size(); ++i)
|
||||||
|
m_indices.coeffRef(i) = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets *this to be the identity permutation matrix of given size.
|
||||||
|
*/
|
||||||
|
void setIdentity(int size)
|
||||||
|
{
|
||||||
|
resize(size);
|
||||||
|
setIdentity();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Multiplies *this by the transposition \f$(ij)\f$ on the left.
|
||||||
|
*
|
||||||
|
* \returns a reference to *this.
|
||||||
|
*
|
||||||
|
* \warning This is much slower than applyTranspositionOnTheRight(int,int):
|
||||||
|
* this has linear complexity and requires a lot of branching.
|
||||||
|
*
|
||||||
|
* \sa applyTranspositionOnTheRight(int,int)
|
||||||
|
*/
|
||||||
|
PermutationMatrix& applyTranspositionOnTheLeft(int i, int j)
|
||||||
|
{
|
||||||
|
ei_assert(i>=0 && j>=0 && i<m_indices.size() && j<m_indices.size());
|
||||||
|
for(int k = 0; k < m_indices.size(); ++k)
|
||||||
|
{
|
||||||
|
if(m_indices.coeff(k) == i) m_indices.coeffRef(k) = j;
|
||||||
|
else if(m_indices.coeff(k) == j) m_indices.coeffRef(k) = i;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Multiplies *this by the transposition \f$(ij)\f$ on the right.
|
||||||
|
*
|
||||||
|
* \returns a reference to *this.
|
||||||
|
*
|
||||||
|
* This is a fast operation, it only consists in swapping two indices.
|
||||||
|
*
|
||||||
|
* \sa applyTranspositionOnTheLeft(int,int)
|
||||||
|
*/
|
||||||
|
PermutationMatrix& applyTranspositionOnTheRight(int i, int j)
|
||||||
|
{
|
||||||
|
ei_assert(i>=0 && j>=0 && i<m_indices.size() && j<m_indices.size());
|
||||||
|
std::swap(m_indices.coeffRef(i), m_indices.coeffRef(j));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**** inversion and multiplication helpers to hopefully get RVO ****/
|
||||||
|
|
||||||
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
protected:
|
||||||
|
enum Inverse_t {Inverse};
|
||||||
|
PermutationMatrix(Inverse_t, const PermutationMatrix& other)
|
||||||
|
: m_indices(other.m_indices.size())
|
||||||
|
{
|
||||||
|
for (int i=0; i<rows();++i) m_indices.coeffRef(other.m_indices.coeff(i)) = i;
|
||||||
|
}
|
||||||
|
enum Product_t {Product};
|
||||||
|
PermutationMatrix(Product_t, const PermutationMatrix& lhs, const PermutationMatrix& rhs)
|
||||||
|
: m_indices(lhs.m_indices.size())
|
||||||
|
{
|
||||||
|
ei_assert(lhs.cols() == rhs.rows());
|
||||||
|
for (int i=0; i<rows();++i) m_indices.coeffRef(i) = lhs.m_indices.coeff(rhs.m_indices.coeff(i));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** \returns the inverse permutation matrix.
|
||||||
|
*
|
||||||
|
* \note \note_try_to_help_rvo
|
||||||
|
*/
|
||||||
|
inline PermutationMatrix inverse() const
|
||||||
|
{ return PermutationMatrix(Inverse, *this); }
|
||||||
|
/** \returns the product permutation matrix.
|
||||||
|
*
|
||||||
|
* \note \note_try_to_help_rvo
|
||||||
|
*/
|
||||||
|
template<int OtherSize, int OtherMaxSize>
|
||||||
|
inline PermutationMatrix operator*(const PermutationMatrix<OtherSize, OtherMaxSize>& other) const
|
||||||
|
{ return PermutationMatrix(Product, *this, other); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
IndicesType m_indices;
|
IndicesType m_indices;
|
||||||
@ -185,7 +305,7 @@ struct ei_permut_matrix_product_retval
|
|||||||
Dest,
|
Dest,
|
||||||
Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime,
|
Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime,
|
||||||
Side==OnTheRight ? 1 : Dest::ColsAtCompileTime
|
Side==OnTheRight ? 1 : Dest::ColsAtCompileTime
|
||||||
>(dst, Side==OnTheRight ? m_permutation.indices().coeff(i) : i)
|
>(dst, Side==OnTheLeft ? m_permutation.indices().coeff(i) : i)
|
||||||
|
|
||||||
=
|
=
|
||||||
|
|
||||||
@ -193,7 +313,7 @@ struct ei_permut_matrix_product_retval
|
|||||||
MatrixTypeNestedCleaned,
|
MatrixTypeNestedCleaned,
|
||||||
Side==OnTheLeft ? 1 : MatrixType::RowsAtCompileTime,
|
Side==OnTheLeft ? 1 : MatrixType::RowsAtCompileTime,
|
||||||
Side==OnTheRight ? 1 : MatrixType::ColsAtCompileTime
|
Side==OnTheRight ? 1 : MatrixType::ColsAtCompileTime
|
||||||
>(m_matrix, Side==OnTheLeft ? m_permutation.indices().coeff(i) : i);
|
>(m_matrix, Side==OnTheRight ? m_permutation.indices().coeff(i) : i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,10 +58,12 @@ enum { OuterProduct, InnerProduct, UnrolledProduct, GemvProduct, GemmProduct };
|
|||||||
|
|
||||||
template<typename Lhs, typename Rhs> struct ei_product_type
|
template<typename Lhs, typename Rhs> struct ei_product_type
|
||||||
{
|
{
|
||||||
|
typedef typename ei_cleantype<Lhs>::type _Lhs;
|
||||||
|
typedef typename ei_cleantype<Rhs>::type _Rhs;
|
||||||
enum {
|
enum {
|
||||||
Rows = Lhs::RowsAtCompileTime,
|
Rows = _Lhs::RowsAtCompileTime,
|
||||||
Cols = Rhs::ColsAtCompileTime,
|
Cols = _Rhs::ColsAtCompileTime,
|
||||||
Depth = EIGEN_ENUM_MIN(Lhs::ColsAtCompileTime,Rhs::RowsAtCompileTime)
|
Depth = EIGEN_ENUM_MIN(_Lhs::ColsAtCompileTime,_Rhs::RowsAtCompileTime)
|
||||||
};
|
};
|
||||||
|
|
||||||
// the splitting into different lines of code here, introducing the _select enums and the typedef below,
|
// the splitting into different lines of code here, introducing the _select enums and the typedef below,
|
||||||
@ -211,9 +213,6 @@ class GeneralProduct<Lhs, Rhs, OuterProduct>
|
|||||||
{
|
{
|
||||||
ei_outer_product_selector<(int(Dest::Flags)&RowMajorBit) ? RowMajor : ColMajor>::run(*this, dest, alpha);
|
ei_outer_product_selector<(int(Dest::Flags)&RowMajorBit) ? RowMajor : ColMajor>::run(*this, dest, alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
GeneralProduct& operator=(const GeneralProduct&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> struct ei_outer_product_selector<ColMajor> {
|
template<> struct ei_outer_product_selector<ColMajor> {
|
||||||
@ -279,9 +278,6 @@ class GeneralProduct<Lhs, Rhs, GemvProduct>
|
|||||||
ei_gemv_selector<Side,(int(MatrixType::Flags)&RowMajorBit) ? RowMajor : ColMajor,
|
ei_gemv_selector<Side,(int(MatrixType::Flags)&RowMajorBit) ? RowMajor : ColMajor,
|
||||||
bool(ei_blas_traits<MatrixType>::ActualAccess)>::run(*this, dst, alpha);
|
bool(ei_blas_traits<MatrixType>::ActualAccess)>::run(*this, dst, alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
GeneralProduct& operator=(const GeneralProduct&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// The vector is on the left => transposition
|
// The vector is on the left => transposition
|
||||||
|
@ -114,14 +114,6 @@ class ProductBase : public MatrixBase<Derived>
|
|||||||
template<typename Dest>
|
template<typename Dest>
|
||||||
inline void scaleAndAddTo(Dest& dst,Scalar alpha) const { derived().scaleAndAddTo(dst,alpha); }
|
inline void scaleAndAddTo(Dest& dst,Scalar alpha) const { derived().scaleAndAddTo(dst,alpha); }
|
||||||
|
|
||||||
PlainMatrixType eval() const
|
|
||||||
{
|
|
||||||
PlainMatrixType res(rows(), cols());
|
|
||||||
res.setZero();
|
|
||||||
derived().evalTo(res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEPRECATED const Flagged<ProductBase, 0, EvalBeforeAssigningBit> lazy() const
|
EIGEN_DEPRECATED const Flagged<ProductBase, 0, EvalBeforeAssigningBit> lazy() const
|
||||||
{ return *this; }
|
{ return *this; }
|
||||||
|
|
||||||
@ -140,8 +132,6 @@ class ProductBase : public MatrixBase<Derived>
|
|||||||
void coeffRef(int,int);
|
void coeffRef(int,int);
|
||||||
void coeff(int) const;
|
void coeff(int) const;
|
||||||
void coeffRef(int);
|
void coeffRef(int);
|
||||||
|
|
||||||
ProductBase& operator=(const ProductBase&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename NestedProduct>
|
template<typename NestedProduct>
|
||||||
|
@ -54,16 +54,16 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
Vectorization = int(MayLinearVectorize) ? int(LinearVectorization)
|
Traversal = int(MayLinearVectorize) ? int(LinearVectorizedTraversal)
|
||||||
: int(MaySliceVectorize) ? int(SliceVectorization)
|
: int(MaySliceVectorize) ? int(SliceVectorizedTraversal)
|
||||||
: int(NoVectorization)
|
: int(DefaultTraversal)
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
Cost = Derived::SizeAtCompileTime * Derived::CoeffReadCost
|
Cost = Derived::SizeAtCompileTime * Derived::CoeffReadCost
|
||||||
+ (Derived::SizeAtCompileTime-1) * NumTraits<typename Derived::Scalar>::AddCost,
|
+ (Derived::SizeAtCompileTime-1) * NumTraits<typename Derived::Scalar>::AddCost,
|
||||||
UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Vectorization) == int(NoVectorization) ? 1 : int(PacketSize))
|
UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Traversal) == int(DefaultTraversal) ? 1 : int(PacketSize))
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -171,13 +171,13 @@ struct ei_redux_vec_unroller<Func, Derived, Start, 1>
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
template<typename Func, typename Derived,
|
template<typename Func, typename Derived,
|
||||||
int Vectorization = ei_redux_traits<Func, Derived>::Vectorization,
|
int Traversal = ei_redux_traits<Func, Derived>::Traversal,
|
||||||
int Unrolling = ei_redux_traits<Func, Derived>::Unrolling
|
int Unrolling = ei_redux_traits<Func, Derived>::Unrolling
|
||||||
>
|
>
|
||||||
struct ei_redux_impl;
|
struct ei_redux_impl;
|
||||||
|
|
||||||
template<typename Func, typename Derived>
|
template<typename Func, typename Derived>
|
||||||
struct ei_redux_impl<Func, Derived, NoVectorization, NoUnrolling>
|
struct ei_redux_impl<Func, Derived, DefaultTraversal, NoUnrolling>
|
||||||
{
|
{
|
||||||
typedef typename Derived::Scalar Scalar;
|
typedef typename Derived::Scalar Scalar;
|
||||||
static Scalar run(const Derived& mat, const Func& func)
|
static Scalar run(const Derived& mat, const Func& func)
|
||||||
@ -195,12 +195,12 @@ struct ei_redux_impl<Func, Derived, NoVectorization, NoUnrolling>
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename Func, typename Derived>
|
template<typename Func, typename Derived>
|
||||||
struct ei_redux_impl<Func,Derived, NoVectorization, CompleteUnrolling>
|
struct ei_redux_impl<Func,Derived, DefaultTraversal, CompleteUnrolling>
|
||||||
: public ei_redux_novec_unroller<Func,Derived, 0, Derived::SizeAtCompileTime>
|
: public ei_redux_novec_unroller<Func,Derived, 0, Derived::SizeAtCompileTime>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
template<typename Func, typename Derived>
|
template<typename Func, typename Derived>
|
||||||
struct ei_redux_impl<Func, Derived, LinearVectorization, NoUnrolling>
|
struct ei_redux_impl<Func, Derived, LinearVectorizedTraversal, NoUnrolling>
|
||||||
{
|
{
|
||||||
typedef typename Derived::Scalar Scalar;
|
typedef typename Derived::Scalar Scalar;
|
||||||
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
|
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
|
||||||
@ -209,10 +209,7 @@ struct ei_redux_impl<Func, Derived, LinearVectorization, NoUnrolling>
|
|||||||
{
|
{
|
||||||
const int size = mat.size();
|
const int size = mat.size();
|
||||||
const int packetSize = ei_packet_traits<Scalar>::size;
|
const int packetSize = ei_packet_traits<Scalar>::size;
|
||||||
const int alignedStart = (Derived::Flags & AlignedBit)
|
const int alignedStart = ei_alignmentOffset(mat,size);
|
||||||
|| !(Derived::Flags & DirectAccessBit)
|
|
||||||
? 0
|
|
||||||
: ei_alignmentOffset(&mat.const_cast_derived().coeffRef(0), size);
|
|
||||||
enum {
|
enum {
|
||||||
alignment = (Derived::Flags & DirectAccessBit) || (Derived::Flags & AlignedBit)
|
alignment = (Derived::Flags & DirectAccessBit) || (Derived::Flags & AlignedBit)
|
||||||
? Aligned : Unaligned
|
? Aligned : Unaligned
|
||||||
@ -246,7 +243,7 @@ struct ei_redux_impl<Func, Derived, LinearVectorization, NoUnrolling>
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename Func, typename Derived>
|
template<typename Func, typename Derived>
|
||||||
struct ei_redux_impl<Func, Derived, SliceVectorization, NoUnrolling>
|
struct ei_redux_impl<Func, Derived, SliceVectorizedTraversal, NoUnrolling>
|
||||||
{
|
{
|
||||||
typedef typename Derived::Scalar Scalar;
|
typedef typename Derived::Scalar Scalar;
|
||||||
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
|
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
|
||||||
@ -277,7 +274,7 @@ struct ei_redux_impl<Func, Derived, SliceVectorization, NoUnrolling>
|
|||||||
else // too small to vectorize anything.
|
else // too small to vectorize anything.
|
||||||
// since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize.
|
// since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize.
|
||||||
{
|
{
|
||||||
res = ei_redux_impl<Func, Derived, NoVectorization, NoUnrolling>::run(mat, func);
|
res = ei_redux_impl<Func, Derived, DefaultTraversal, NoUnrolling>::run(mat, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@ -285,20 +282,20 @@ struct ei_redux_impl<Func, Derived, SliceVectorization, NoUnrolling>
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename Func, typename Derived>
|
template<typename Func, typename Derived>
|
||||||
struct ei_redux_impl<Func, Derived, LinearVectorization, CompleteUnrolling>
|
struct ei_redux_impl<Func, Derived, LinearVectorizedTraversal, CompleteUnrolling>
|
||||||
{
|
{
|
||||||
typedef typename Derived::Scalar Scalar;
|
typedef typename Derived::Scalar Scalar;
|
||||||
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
|
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
|
||||||
enum {
|
enum {
|
||||||
PacketSize = ei_packet_traits<Scalar>::size,
|
PacketSize = ei_packet_traits<Scalar>::size,
|
||||||
Size = Derived::SizeAtCompileTime,
|
Size = Derived::SizeAtCompileTime,
|
||||||
VectorizationSize = (Size / PacketSize) * PacketSize
|
VectorizedSize = (Size / PacketSize) * PacketSize
|
||||||
};
|
};
|
||||||
EIGEN_STRONG_INLINE static Scalar run(const Derived& mat, const Func& func)
|
EIGEN_STRONG_INLINE static Scalar run(const Derived& mat, const Func& func)
|
||||||
{
|
{
|
||||||
Scalar res = func.predux(ei_redux_vec_unroller<Func, Derived, 0, Size / PacketSize>::run(mat,func));
|
Scalar res = func.predux(ei_redux_vec_unroller<Func, Derived, 0, Size / PacketSize>::run(mat,func));
|
||||||
if (VectorizationSize != Size)
|
if (VectorizedSize != Size)
|
||||||
res = func(res,ei_redux_novec_unroller<Func, Derived, VectorizationSize, Size-VectorizationSize>::run(mat,func));
|
res = func(res,ei_redux_novec_unroller<Func, Derived, VectorizedSize, Size-VectorizedSize>::run(mat,func));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -150,7 +150,6 @@ template<typename MatrixType, unsigned int UpLo> class SelfAdjointView
|
|||||||
const LDLT<PlainMatrixType> ldlt() const;
|
const LDLT<PlainMatrixType> ldlt() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
const typename MatrixType::Nested m_matrix;
|
const typename MatrixType::Nested m_matrix;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -106,9 +106,6 @@ template<typename ExpressionType> class SwapWrapper
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
ExpressionType& m_expression;
|
ExpressionType& m_expression;
|
||||||
|
|
||||||
private:
|
|
||||||
SwapWrapper& operator=(const SwapWrapper&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** swaps *this with the expression \a other.
|
/** swaps *this with the expression \a other.
|
||||||
|
@ -215,7 +215,7 @@ template<typename Derived>
|
|||||||
inline const typename MatrixBase<Derived>::AdjointReturnType
|
inline const typename MatrixBase<Derived>::AdjointReturnType
|
||||||
MatrixBase<Derived>::adjoint() const
|
MatrixBase<Derived>::adjoint() const
|
||||||
{
|
{
|
||||||
return this->transpose().nestByValue();
|
return this->transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
@ -297,13 +297,7 @@ inline void MatrixBase<Derived>::adjointInPlace()
|
|||||||
|
|
||||||
#ifndef EIGEN_NO_DEBUG
|
#ifndef EIGEN_NO_DEBUG
|
||||||
|
|
||||||
// The following is to detect aliasing problems in the following common cases:
|
// The following is to detect aliasing problems in most common cases.
|
||||||
// a = a.transpose()
|
|
||||||
// a = a.transpose() + X
|
|
||||||
// a = X + a.transpose()
|
|
||||||
// a = a.adjoint()
|
|
||||||
// a = a.adjoint() + X
|
|
||||||
// a = X + a.adjoint()
|
|
||||||
|
|
||||||
template<typename T, int Access=ei_blas_traits<T>::ActualAccess>
|
template<typename T, int Access=ei_blas_traits<T>::ActualAccess>
|
||||||
struct ei_extract_data_selector {
|
struct ei_extract_data_selector {
|
||||||
@ -323,63 +317,31 @@ template<typename T> typename T::Scalar* ei_extract_data(const T& m)
|
|||||||
return ei_extract_data_selector<T>::run(m);
|
return ei_extract_data_selector<T>::run(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Scalar, bool DestIsTranposed, typename OtherDerived>
|
||||||
|
struct ei_check_transpose_aliasing_selector
|
||||||
|
{
|
||||||
|
static bool run(const Scalar* dest, const OtherDerived& src)
|
||||||
|
{
|
||||||
|
return (ei_blas_traits<OtherDerived>::IsTransposed != DestIsTranposed) && (dest==(Scalar*)ei_extract_data(src));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Scalar, bool DestIsTranposed, typename BinOp, typename DerivedA, typename DerivedB>
|
||||||
|
struct ei_check_transpose_aliasing_selector<Scalar,DestIsTranposed,CwiseBinaryOp<BinOp,DerivedA,DerivedB> >
|
||||||
|
{
|
||||||
|
static bool run(const Scalar* dest, const CwiseBinaryOp<BinOp,DerivedA,DerivedB>& src)
|
||||||
|
{
|
||||||
|
return ((ei_blas_traits<DerivedA>::IsTransposed != DestIsTranposed) && dest==(Scalar*)ei_extract_data(src.lhs()))
|
||||||
|
|| ((ei_blas_traits<DerivedB>::IsTransposed != DestIsTranposed) && dest==(Scalar*)ei_extract_data(src.rhs()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
Derived& DenseBase<Derived>::lazyAssign(const Transpose<OtherDerived>& other)
|
void DenseBase<Derived>::checkTransposeAliasing(const OtherDerived& other) const
|
||||||
{
|
{
|
||||||
ei_assert(ei_extract_data(other) != ei_extract_data(derived())
|
ei_assert((!ei_check_transpose_aliasing_selector<Scalar,ei_blas_traits<Derived>::IsTransposed,OtherDerived>::run(ei_extract_data(derived()), other))
|
||||||
&& "aliasing detected during tranposition, please use transposeInPlace()");
|
&& "aliasing detected during tranposition, use transposeInPlace() or evaluate the rhs into a temporary using .eval()");
|
||||||
return lazyAssign(static_cast<const DenseBase<Transpose<OtherDerived> >& >(other));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename DerivedA, typename DerivedB>
|
|
||||||
Derived& DenseBase<Derived>::
|
|
||||||
lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,Transpose<DerivedA>,DerivedB>& other)
|
|
||||||
{
|
|
||||||
ei_assert(ei_extract_data(derived()) != ei_extract_data(other.lhs())
|
|
||||||
&& "aliasing detected during tranposition, please evaluate your expression");
|
|
||||||
return lazyAssign(static_cast<const DenseBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,Transpose<DerivedA>,DerivedB> >& >(other));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename DerivedA, typename DerivedB>
|
|
||||||
Derived& DenseBase<Derived>::
|
|
||||||
lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,Transpose<DerivedB> >& other)
|
|
||||||
{
|
|
||||||
ei_assert(ei_extract_data(derived()) != ei_extract_data(other.rhs())
|
|
||||||
&& "aliasing detected during tranposition, please evaluate your expression");
|
|
||||||
return lazyAssign(static_cast<const DenseBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,Transpose<DerivedB> > >& >(other));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename OtherDerived> Derived&
|
|
||||||
DenseBase<Derived>::
|
|
||||||
lazyAssign(const CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<OtherDerived> > >& other)
|
|
||||||
{
|
|
||||||
ei_assert(ei_extract_data(other) != ei_extract_data(derived())
|
|
||||||
&& "aliasing detected during tranposition, please use adjointInPlace()");
|
|
||||||
return lazyAssign(static_cast<const DenseBase<CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<OtherDerived> > > >& >(other));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename DerivedA, typename DerivedB>
|
|
||||||
Derived& DenseBase<Derived>::
|
|
||||||
lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedA> > >,DerivedB>& other)
|
|
||||||
{
|
|
||||||
ei_assert(ei_extract_data(derived()) != ei_extract_data(other.lhs())
|
|
||||||
&& "aliasing detected during tranposition, please evaluate your expression");
|
|
||||||
return lazyAssign(static_cast<const DenseBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedA> > >,DerivedB> >& >(other));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename DerivedA, typename DerivedB>
|
|
||||||
Derived& DenseBase<Derived>::
|
|
||||||
lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedB> > > >& other)
|
|
||||||
{
|
|
||||||
ei_assert(ei_extract_data(derived()) != ei_extract_data(other.rhs())
|
|
||||||
&& "aliasing detected during tranposition, please evaluate your expression");
|
|
||||||
return lazyAssign(static_cast<const DenseBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedB> > > > >& >(other));
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -26,22 +26,11 @@
|
|||||||
#ifndef EIGEN_TRIANGULARMATRIX_H
|
#ifndef EIGEN_TRIANGULARMATRIX_H
|
||||||
#define EIGEN_TRIANGULARMATRIX_H
|
#define EIGEN_TRIANGULARMATRIX_H
|
||||||
|
|
||||||
/** \nonstableyet
|
/** \internal
|
||||||
|
*
|
||||||
* \class TriangularBase
|
* \class TriangularBase
|
||||||
*
|
*
|
||||||
* \brief Expression of a triangular matrix extracted from a given 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 Mode the kind of triangular matrix expression to construct. Can be UpperTriangular,
|
|
||||||
* LowerTriangular, UpperSelfadjoint, or LowerSelfadjoint. This is in fact a bit field;
|
|
||||||
* it must have either UpperBit or LowerBit, and additionnaly it may have either
|
|
||||||
* TraingularBit or SelfadjointBit.
|
|
||||||
*
|
|
||||||
* This class represents an expression of the upper or lower triangular part of
|
|
||||||
* a square matrix, possibly with a further assumption on the diagonal. It is the return type
|
|
||||||
* of MatrixBase::part() and most of the time this is the only way it is used.
|
|
||||||
*
|
|
||||||
* \sa MatrixBase::part()
|
|
||||||
*/
|
*/
|
||||||
template<typename Derived> class TriangularBase : public AnyMatrixBase<Derived>
|
template<typename Derived> class TriangularBase : public AnyMatrixBase<Derived>
|
||||||
{
|
{
|
||||||
@ -99,11 +88,11 @@ template<typename Derived> class TriangularBase : public AnyMatrixBase<Derived>
|
|||||||
|
|
||||||
void check_coordinates(int row, int col)
|
void check_coordinates(int row, int col)
|
||||||
{
|
{
|
||||||
ei_assert(col>0 && col<cols() && row>0 && row<rows());
|
ei_assert(col>=0 && col<cols() && row>=0 && row<rows());
|
||||||
ei_assert( (Mode==UpperTriangular && col>=row)
|
ei_assert( (Mode==UpperTriangular && col>=row)
|
||||||
|| (Mode==LowerTriangular && col<=row)
|
|| (Mode==LowerTriangular && col<=row)
|
||||||
|| (Mode==StrictlyUpperTriangular && col>row)
|
|| ((Mode==StrictlyUpperTriangular || Mode==UnitUpperTriangular) && col>row)
|
||||||
|| (Mode==StrictlyLowerTriangular && col<row));
|
|| ((Mode==StrictlyLowerTriangular || Mode==UnitLowerTriangular) && col<row));
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_coordinates_internal(int row, int col)
|
void check_coordinates_internal(int row, int col)
|
||||||
@ -115,19 +104,21 @@ template<typename Derived> class TriangularBase : public AnyMatrixBase<Derived>
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** \class TriangularView
|
/** \class TriangularView
|
||||||
* \nonstableyet
|
|
||||||
*
|
*
|
||||||
* \brief Expression of a triangular part of a dense matrix
|
* \brief Base class for triangular part in a matrix
|
||||||
*
|
*
|
||||||
* \param MatrixType the type of the dense matrix storing the coefficients
|
* \param MatrixType the type of the object in which we are taking the triangular part
|
||||||
|
* \param Mode the kind of triangular matrix expression to construct. Can be UpperTriangular,
|
||||||
|
* LowerTriangular, UpperSelfadjoint, or LowerSelfadjoint. This is in fact a bit field;
|
||||||
|
* it must have either UpperBit or LowerBit, and additionnaly it may have either
|
||||||
|
* TraingularBit or SelfadjointBit.
|
||||||
*
|
*
|
||||||
* This class is an expression of a triangular part of a matrix with given dense
|
* This class represents a triangular part of a matrix, not necessarily square. Strictly speaking, for rectangular
|
||||||
* storage of the coefficients. It is the return type of MatrixBase::triangularPart()
|
* matrices one should speak ok "trapezoid" parts. This class is the return type
|
||||||
* and most of the time this is the only way that it is used.
|
* of MatrixBase::triangularView() and most of the time this is the only way it is used.
|
||||||
*
|
*
|
||||||
* \sa class TriangularBase, MatrixBase::triangularPart(), class DiagonalWrapper
|
* \sa MatrixBase::triangularView()
|
||||||
*/
|
*/
|
||||||
template<typename MatrixType, unsigned int _Mode>
|
template<typename MatrixType, unsigned int _Mode>
|
||||||
struct ei_traits<TriangularView<MatrixType, _Mode> > : ei_traits<MatrixType>
|
struct ei_traits<TriangularView<MatrixType, _Mode> > : ei_traits<MatrixType>
|
||||||
@ -155,7 +146,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
|||||||
typedef TriangularBase<TriangularView> Base;
|
typedef TriangularBase<TriangularView> Base;
|
||||||
typedef typename ei_traits<TriangularView>::Scalar Scalar;
|
typedef typename ei_traits<TriangularView>::Scalar Scalar;
|
||||||
typedef _MatrixType MatrixType;
|
typedef _MatrixType MatrixType;
|
||||||
typedef typename MatrixType::PlainMatrixType PlainMatrixType;
|
typedef typename MatrixType::PlainMatrixType DenseMatrixType;
|
||||||
typedef typename MatrixType::Nested MatrixTypeNested;
|
typedef typename MatrixType::Nested MatrixTypeNested;
|
||||||
typedef typename ei_cleantype<MatrixTypeNested>::type _MatrixTypeNested;
|
typedef typename ei_cleantype<MatrixTypeNested>::type _MatrixTypeNested;
|
||||||
|
|
||||||
@ -231,23 +222,23 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
|||||||
|
|
||||||
|
|
||||||
/** \sa MatrixBase::adjoint() */
|
/** \sa MatrixBase::adjoint() */
|
||||||
inline TriangularView<NestByValue<typename MatrixType::AdjointReturnType>,TransposeMode> adjoint()
|
inline TriangularView<typename MatrixType::AdjointReturnType,TransposeMode> adjoint()
|
||||||
{ return m_matrix.adjoint().nestByValue(); }
|
{ return m_matrix.adjoint(); }
|
||||||
/** \sa MatrixBase::adjoint() const */
|
/** \sa MatrixBase::adjoint() const */
|
||||||
inline const TriangularView<NestByValue<typename MatrixType::AdjointReturnType>,TransposeMode> adjoint() const
|
inline const TriangularView<typename MatrixType::AdjointReturnType,TransposeMode> adjoint() const
|
||||||
{ return m_matrix.adjoint().nestByValue(); }
|
{ return m_matrix.adjoint(); }
|
||||||
|
|
||||||
/** \sa MatrixBase::transpose() */
|
/** \sa MatrixBase::transpose() */
|
||||||
inline TriangularView<NestByValue<Transpose<MatrixType> >,TransposeMode> transpose()
|
inline TriangularView<Transpose<MatrixType>,TransposeMode> transpose()
|
||||||
{ return m_matrix.transpose().nestByValue(); }
|
{ return m_matrix.transpose(); }
|
||||||
/** \sa MatrixBase::transpose() const */
|
/** \sa MatrixBase::transpose() const */
|
||||||
inline const TriangularView<NestByValue<Transpose<MatrixType> >,TransposeMode> transpose() const
|
inline const TriangularView<Transpose<MatrixType>,TransposeMode> transpose() const
|
||||||
{ return m_matrix.transpose().nestByValue(); }
|
{ return m_matrix.transpose(); }
|
||||||
|
|
||||||
PlainMatrixType toDense() const
|
DenseMatrixType toDenseMatrix() const
|
||||||
{
|
{
|
||||||
PlainMatrixType res(rows(), cols());
|
DenseMatrixType res(rows(), cols());
|
||||||
res = *this;
|
evalToLazy(res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,20 +342,7 @@ struct ei_triangular_assignment_selector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename Derived1, typename Derived2, unsigned int Mode, bool ClearOpposite>
|
|
||||||
struct ei_triangular_assignment_selector<Derived1, Derived2, Mode, 1, ClearOpposite>
|
|
||||||
{
|
|
||||||
inline static void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
if(Mode&UnitDiagBit)
|
|
||||||
{
|
|
||||||
if(ClearOpposite)
|
|
||||||
dst.coeffRef(0, 0) = 1;
|
|
||||||
}
|
|
||||||
else if(!(Mode & ZeroDiagBit))
|
|
||||||
dst.copyCoeff(0, 0, src);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// prevent buggy user code from causing an infinite recursion
|
// prevent buggy user code from causing an infinite recursion
|
||||||
template<typename Derived1, typename Derived2, unsigned int Mode, bool ClearOpposite>
|
template<typename Derived1, typename Derived2, unsigned int Mode, bool ClearOpposite>
|
||||||
struct ei_triangular_assignment_selector<Derived1, Derived2, Mode, 0, ClearOpposite>
|
struct ei_triangular_assignment_selector<Derived1, Derived2, Mode, 0, ClearOpposite>
|
||||||
@ -379,14 +357,16 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, UpperTriangular, Dy
|
|||||||
{
|
{
|
||||||
for(int j = 0; j < dst.cols(); ++j)
|
for(int j = 0; j < dst.cols(); ++j)
|
||||||
{
|
{
|
||||||
for(int i = 0; i <= j; ++i)
|
int maxi = std::min(j, dst.rows()-1);
|
||||||
|
for(int i = 0; i <= maxi; ++i)
|
||||||
dst.copyCoeff(i, j, src);
|
dst.copyCoeff(i, j, src);
|
||||||
if (ClearOpposite)
|
if (ClearOpposite)
|
||||||
for(int i = j+1; i < dst.rows(); ++i)
|
for(int i = maxi+1; i < dst.rows(); ++i)
|
||||||
dst.coeffRef(i, j) = 0;
|
dst.coeffRef(i, j) = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
||||||
struct ei_triangular_assignment_selector<Derived1, Derived2, LowerTriangular, Dynamic, ClearOpposite>
|
struct ei_triangular_assignment_selector<Derived1, Derived2, LowerTriangular, Dynamic, ClearOpposite>
|
||||||
{
|
{
|
||||||
@ -396,8 +376,9 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, LowerTriangular, Dy
|
|||||||
{
|
{
|
||||||
for(int i = j; i < dst.rows(); ++i)
|
for(int i = j; i < dst.rows(); ++i)
|
||||||
dst.copyCoeff(i, j, src);
|
dst.copyCoeff(i, j, src);
|
||||||
|
int maxi = std::min(j, dst.rows());
|
||||||
if (ClearOpposite)
|
if (ClearOpposite)
|
||||||
for(int i = 0; i < j; ++i)
|
for(int i = 0; i < maxi; ++i)
|
||||||
dst.coeffRef(i, j) = 0;
|
dst.coeffRef(i, j) = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -410,14 +391,16 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, StrictlyUpperTriang
|
|||||||
{
|
{
|
||||||
for(int j = 0; j < dst.cols(); ++j)
|
for(int j = 0; j < dst.cols(); ++j)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < j; ++i)
|
int maxi = std::min(j, dst.rows());
|
||||||
|
for(int i = 0; i < maxi; ++i)
|
||||||
dst.copyCoeff(i, j, src);
|
dst.copyCoeff(i, j, src);
|
||||||
if (ClearOpposite)
|
if (ClearOpposite)
|
||||||
for(int i = j; i < dst.rows(); ++i)
|
for(int i = maxi; i < dst.rows(); ++i)
|
||||||
dst.coeffRef(i, j) = 0;
|
dst.coeffRef(i, j) = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
||||||
struct ei_triangular_assignment_selector<Derived1, Derived2, StrictlyLowerTriangular, Dynamic, ClearOpposite>
|
struct ei_triangular_assignment_selector<Derived1, Derived2, StrictlyLowerTriangular, Dynamic, ClearOpposite>
|
||||||
{
|
{
|
||||||
@ -427,8 +410,9 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, StrictlyLowerTriang
|
|||||||
{
|
{
|
||||||
for(int i = j+1; i < dst.rows(); ++i)
|
for(int i = j+1; i < dst.rows(); ++i)
|
||||||
dst.copyCoeff(i, j, src);
|
dst.copyCoeff(i, j, src);
|
||||||
|
int maxi = std::min(j, dst.rows()-1);
|
||||||
if (ClearOpposite)
|
if (ClearOpposite)
|
||||||
for(int i = 0; i <= j; ++i)
|
for(int i = 0; i <= maxi; ++i)
|
||||||
dst.coeffRef(i, j) = 0;
|
dst.coeffRef(i, j) = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -441,15 +425,16 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, UnitUpperTriangular
|
|||||||
{
|
{
|
||||||
for(int j = 0; j < dst.cols(); ++j)
|
for(int j = 0; j < dst.cols(); ++j)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < j; ++i)
|
int maxi = std::min(j, dst.rows());
|
||||||
|
for(int i = 0; i < maxi; ++i)
|
||||||
dst.copyCoeff(i, j, src);
|
dst.copyCoeff(i, j, src);
|
||||||
if (ClearOpposite)
|
if (ClearOpposite)
|
||||||
{
|
{
|
||||||
for(int i = j+1; i < dst.rows(); ++i)
|
for(int i = maxi+1; i < dst.rows(); ++i)
|
||||||
dst.coeffRef(i, j) = 0;
|
dst.coeffRef(i, j) = 0;
|
||||||
dst.coeffRef(j, j) = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dst.diagonal().setOnes();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
||||||
@ -459,15 +444,16 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, UnitLowerTriangular
|
|||||||
{
|
{
|
||||||
for(int j = 0; j < dst.cols(); ++j)
|
for(int j = 0; j < dst.cols(); ++j)
|
||||||
{
|
{
|
||||||
for(int i = j+1; i < dst.rows(); ++i)
|
int maxi = std::min(j, dst.rows());
|
||||||
|
for(int i = maxi+1; i < dst.rows(); ++i)
|
||||||
dst.copyCoeff(i, j, src);
|
dst.copyCoeff(i, j, src);
|
||||||
if (ClearOpposite)
|
if (ClearOpposite)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < j; ++i)
|
for(int i = 0; i < maxi; ++i)
|
||||||
dst.coeffRef(i, j) = 0;
|
dst.coeffRef(i, j) = 0;
|
||||||
dst.coeffRef(j, j) = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dst.diagonal().setOnes();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -514,7 +500,7 @@ TriangularView<MatrixType, Mode>::operator=(const TriangularBase<OtherDerived>&
|
|||||||
ei_assert(Mode == OtherDerived::Mode);
|
ei_assert(Mode == OtherDerived::Mode);
|
||||||
if(ei_traits<OtherDerived>::Flags & EvalBeforeAssigningBit)
|
if(ei_traits<OtherDerived>::Flags & EvalBeforeAssigningBit)
|
||||||
{
|
{
|
||||||
typename OtherDerived::PlainMatrixType other_evaluated(other.rows(), other.cols());
|
typename OtherDerived::DenseMatrixType other_evaluated(other.rows(), other.cols());
|
||||||
other_evaluated.template triangularView<Mode>().lazyAssign(other.derived());
|
other_evaluated.template triangularView<Mode>().lazyAssign(other.derived());
|
||||||
lazyAssign(other_evaluated);
|
lazyAssign(other_evaluated);
|
||||||
}
|
}
|
||||||
@ -633,17 +619,20 @@ const TriangularView<Derived, Mode> MatrixBase<Derived>::triangularView() const
|
|||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
bool MatrixBase<Derived>::isUpperTriangular(RealScalar prec) const
|
bool MatrixBase<Derived>::isUpperTriangular(RealScalar prec) const
|
||||||
{
|
{
|
||||||
if(cols() != rows()) return false;
|
|
||||||
RealScalar maxAbsOnUpperTriangularPart = static_cast<RealScalar>(-1);
|
RealScalar maxAbsOnUpperTriangularPart = static_cast<RealScalar>(-1);
|
||||||
for(int j = 0; j < cols(); ++j)
|
for(int j = 0; j < cols(); ++j)
|
||||||
for(int i = 0; i <= j; ++i)
|
{
|
||||||
|
int maxi = std::min(j, rows()-1);
|
||||||
|
for(int i = 0; i <= maxi; ++i)
|
||||||
{
|
{
|
||||||
RealScalar absValue = ei_abs(coeff(i,j));
|
RealScalar absValue = ei_abs(coeff(i,j));
|
||||||
if(absValue > maxAbsOnUpperTriangularPart) maxAbsOnUpperTriangularPart = absValue;
|
if(absValue > maxAbsOnUpperTriangularPart) maxAbsOnUpperTriangularPart = absValue;
|
||||||
}
|
}
|
||||||
for(int j = 0; j < cols()-1; ++j)
|
}
|
||||||
|
RealScalar threshold = maxAbsOnUpperTriangularPart * prec;
|
||||||
|
for(int j = 0; j < cols(); ++j)
|
||||||
for(int i = j+1; i < rows(); ++i)
|
for(int i = j+1; i < rows(); ++i)
|
||||||
if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnUpperTriangularPart, prec)) return false;
|
if(ei_abs(coeff(i, j)) > threshold) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,7 +644,6 @@ bool MatrixBase<Derived>::isUpperTriangular(RealScalar prec) const
|
|||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
bool MatrixBase<Derived>::isLowerTriangular(RealScalar prec) const
|
bool MatrixBase<Derived>::isLowerTriangular(RealScalar prec) const
|
||||||
{
|
{
|
||||||
if(cols() != rows()) return false;
|
|
||||||
RealScalar maxAbsOnLowerTriangularPart = static_cast<RealScalar>(-1);
|
RealScalar maxAbsOnLowerTriangularPart = static_cast<RealScalar>(-1);
|
||||||
for(int j = 0; j < cols(); ++j)
|
for(int j = 0; j < cols(); ++j)
|
||||||
for(int i = j; i < rows(); ++i)
|
for(int i = j; i < rows(); ++i)
|
||||||
@ -663,9 +651,13 @@ bool MatrixBase<Derived>::isLowerTriangular(RealScalar prec) const
|
|||||||
RealScalar absValue = ei_abs(coeff(i,j));
|
RealScalar absValue = ei_abs(coeff(i,j));
|
||||||
if(absValue > maxAbsOnLowerTriangularPart) maxAbsOnLowerTriangularPart = absValue;
|
if(absValue > maxAbsOnLowerTriangularPart) maxAbsOnLowerTriangularPart = absValue;
|
||||||
}
|
}
|
||||||
|
RealScalar threshold = maxAbsOnLowerTriangularPart * prec;
|
||||||
for(int j = 1; j < cols(); ++j)
|
for(int j = 1; j < cols(); ++j)
|
||||||
for(int i = 0; i < j; ++i)
|
{
|
||||||
if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnLowerTriangularPart, prec)) return false;
|
int maxi = std::min(j, rows()-1);
|
||||||
|
for(int i = 0; i < maxi; ++i)
|
||||||
|
if(ei_abs(coeff(i, j)) > threshold) return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,6 +365,8 @@ static EIGEN_DONT_INLINE EIGEN_UNUSED Packet4f ei_pcos(Packet4f x)
|
|||||||
return _mm_xor_ps(y, sign_bit);
|
return _mm_xor_ps(y, sign_bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is Quake3's fast inverse square root.
|
||||||
|
// For detail see here: http://www.beyond3d.com/content/articles/8/
|
||||||
static EIGEN_UNUSED Packet4f ei_psqrt(Packet4f _x)
|
static EIGEN_UNUSED Packet4f ei_psqrt(Packet4f _x)
|
||||||
{
|
{
|
||||||
Packet4f half = ei_pmul(_x, ei_pset1(.5f));
|
Packet4f half = ei_pmul(_x, ei_pset1(.5f));
|
||||||
|
@ -58,8 +58,8 @@ template<> struct ei_packet_traits<float> : ei_default_packet_traits
|
|||||||
{
|
{
|
||||||
typedef Packet4f type; enum {size=4};
|
typedef Packet4f type; enum {size=4};
|
||||||
enum {
|
enum {
|
||||||
HasSin = 1,
|
HasSin = EIGEN_FAST_MATH,
|
||||||
HasCos = 1,
|
HasCos = EIGEN_FAST_MATH,
|
||||||
HasLog = 1,
|
HasLog = 1,
|
||||||
HasExp = 1,
|
HasExp = 1,
|
||||||
HasSqrt = 1
|
HasSqrt = 1
|
||||||
@ -118,6 +118,9 @@ template<> EIGEN_STRONG_INLINE Packet4f ei_pmul<Packet4f>(const Packet4f& a, con
|
|||||||
template<> EIGEN_STRONG_INLINE Packet2d ei_pmul<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_mul_pd(a,b); }
|
template<> EIGEN_STRONG_INLINE Packet2d ei_pmul<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_mul_pd(a,b); }
|
||||||
template<> EIGEN_STRONG_INLINE Packet4i ei_pmul<Packet4i>(const Packet4i& a, const Packet4i& b)
|
template<> EIGEN_STRONG_INLINE Packet4i ei_pmul<Packet4i>(const Packet4i& a, const Packet4i& b)
|
||||||
{
|
{
|
||||||
|
#ifdef __SSE4_1__
|
||||||
|
return _mm_mullo_epi32(a,b);
|
||||||
|
#else
|
||||||
// this version is slightly faster than 4 scalar products
|
// this version is slightly faster than 4 scalar products
|
||||||
return ei_vec4i_swizzle1(
|
return ei_vec4i_swizzle1(
|
||||||
ei_vec4i_swizzle2(
|
ei_vec4i_swizzle2(
|
||||||
@ -126,6 +129,7 @@ template<> EIGEN_STRONG_INLINE Packet4i ei_pmul<Packet4i>(const Packet4i& a, con
|
|||||||
ei_vec4i_swizzle1(b,1,0,3,2)),
|
ei_vec4i_swizzle1(b,1,0,3,2)),
|
||||||
0,2,0,2),
|
0,2,0,2),
|
||||||
0,2,1,3);
|
0,2,1,3);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> EIGEN_STRONG_INLINE Packet4f ei_pdiv<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_div_ps(a,b); }
|
template<> EIGEN_STRONG_INLINE Packet4f ei_pdiv<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_div_ps(a,b); }
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
* Note that here the inner-loops should always be unrolled.
|
* Note that here the inner-loops should always be unrolled.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<int VectorizationMode, int Index, typename Lhs, typename Rhs, typename RetScalar>
|
template<int Traversal, int Index, typename Lhs, typename Rhs, typename RetScalar>
|
||||||
struct ei_product_coeff_impl;
|
struct ei_product_coeff_impl;
|
||||||
|
|
||||||
template<int StorageOrder, int Index, typename Lhs, typename Rhs, typename PacketScalar, int LoadMode>
|
template<int StorageOrder, int Index, typename Lhs, typename Rhs, typename PacketScalar, int LoadMode>
|
||||||
@ -118,7 +118,7 @@ template<typename LhsNested, typename RhsNested> class GeneralProduct<LhsNested,
|
|||||||
CanVectorizeInner = ei_traits<GeneralProduct>::CanVectorizeInner
|
CanVectorizeInner = ei_traits<GeneralProduct>::CanVectorizeInner
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef ei_product_coeff_impl<CanVectorizeInner ? InnerVectorization : NoVectorization,
|
typedef ei_product_coeff_impl<CanVectorizeInner ? InnerVectorizedTraversal : DefaultTraversal,
|
||||||
Unroll ? InnerSize-1 : Dynamic,
|
Unroll ? InnerSize-1 : Dynamic,
|
||||||
_LhsNested, _RhsNested, Scalar> ScalarCoeffImpl;
|
_LhsNested, _RhsNested, Scalar> ScalarCoeffImpl;
|
||||||
|
|
||||||
@ -185,17 +185,17 @@ template<typename LhsNested, typename RhsNested> class GeneralProduct<LhsNested,
|
|||||||
**************************************/
|
**************************************/
|
||||||
|
|
||||||
template<int Index, typename Lhs, typename Rhs, typename RetScalar>
|
template<int Index, typename Lhs, typename Rhs, typename RetScalar>
|
||||||
struct ei_product_coeff_impl<NoVectorization, Index, Lhs, Rhs, RetScalar>
|
struct ei_product_coeff_impl<DefaultTraversal, Index, Lhs, Rhs, RetScalar>
|
||||||
{
|
{
|
||||||
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar &res)
|
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar &res)
|
||||||
{
|
{
|
||||||
ei_product_coeff_impl<NoVectorization, Index-1, Lhs, Rhs, RetScalar>::run(row, col, lhs, rhs, res);
|
ei_product_coeff_impl<DefaultTraversal, Index-1, Lhs, Rhs, RetScalar>::run(row, col, lhs, rhs, res);
|
||||||
res += lhs.coeff(row, Index) * rhs.coeff(Index, col);
|
res += lhs.coeff(row, Index) * rhs.coeff(Index, col);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, typename RetScalar>
|
template<typename Lhs, typename Rhs, typename RetScalar>
|
||||||
struct ei_product_coeff_impl<NoVectorization, 0, Lhs, Rhs, RetScalar>
|
struct ei_product_coeff_impl<DefaultTraversal, 0, Lhs, Rhs, RetScalar>
|
||||||
{
|
{
|
||||||
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar &res)
|
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar &res)
|
||||||
{
|
{
|
||||||
@ -204,7 +204,7 @@ struct ei_product_coeff_impl<NoVectorization, 0, Lhs, Rhs, RetScalar>
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, typename RetScalar>
|
template<typename Lhs, typename Rhs, typename RetScalar>
|
||||||
struct ei_product_coeff_impl<NoVectorization, Dynamic, Lhs, Rhs, RetScalar>
|
struct ei_product_coeff_impl<DefaultTraversal, Dynamic, Lhs, Rhs, RetScalar>
|
||||||
{
|
{
|
||||||
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar& res)
|
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar& res)
|
||||||
{
|
{
|
||||||
@ -217,7 +217,7 @@ struct ei_product_coeff_impl<NoVectorization, Dynamic, Lhs, Rhs, RetScalar>
|
|||||||
|
|
||||||
// prevent buggy user code from causing an infinite recursion
|
// prevent buggy user code from causing an infinite recursion
|
||||||
template<typename Lhs, typename Rhs, typename RetScalar>
|
template<typename Lhs, typename Rhs, typename RetScalar>
|
||||||
struct ei_product_coeff_impl<NoVectorization, -1, Lhs, Rhs, RetScalar>
|
struct ei_product_coeff_impl<DefaultTraversal, -1, Lhs, Rhs, RetScalar>
|
||||||
{
|
{
|
||||||
EIGEN_STRONG_INLINE static void run(int, int, const Lhs&, const Rhs&, RetScalar&) {}
|
EIGEN_STRONG_INLINE static void run(int, int, const Lhs&, const Rhs&, RetScalar&) {}
|
||||||
};
|
};
|
||||||
@ -247,7 +247,7 @@ struct ei_product_coeff_vectorized_unroller<0, Lhs, Rhs, PacketScalar>
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<int Index, typename Lhs, typename Rhs, typename RetScalar>
|
template<int Index, typename Lhs, typename Rhs, typename RetScalar>
|
||||||
struct ei_product_coeff_impl<InnerVectorization, Index, Lhs, Rhs, RetScalar>
|
struct ei_product_coeff_impl<InnerVectorizedTraversal, Index, Lhs, Rhs, RetScalar>
|
||||||
{
|
{
|
||||||
typedef typename Lhs::PacketScalar PacketScalar;
|
typedef typename Lhs::PacketScalar PacketScalar;
|
||||||
enum { PacketSize = ei_packet_traits<typename Lhs::Scalar>::size };
|
enum { PacketSize = ei_packet_traits<typename Lhs::Scalar>::size };
|
||||||
@ -255,7 +255,7 @@ struct ei_product_coeff_impl<InnerVectorization, Index, Lhs, Rhs, RetScalar>
|
|||||||
{
|
{
|
||||||
PacketScalar pres;
|
PacketScalar pres;
|
||||||
ei_product_coeff_vectorized_unroller<Index+1-PacketSize, Lhs, Rhs, PacketScalar>::run(row, col, lhs, rhs, pres);
|
ei_product_coeff_vectorized_unroller<Index+1-PacketSize, Lhs, Rhs, PacketScalar>::run(row, col, lhs, rhs, pres);
|
||||||
ei_product_coeff_impl<NoVectorization,Index,Lhs,Rhs,RetScalar>::run(row, col, lhs, rhs, res);
|
ei_product_coeff_impl<DefaultTraversal,Index,Lhs,Rhs,RetScalar>::run(row, col, lhs, rhs, res);
|
||||||
res = ei_predux(pres);
|
res = ei_predux(pres);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -268,7 +268,7 @@ struct ei_product_coeff_vectorized_dyn_selector
|
|||||||
res = ei_dot_impl<
|
res = ei_dot_impl<
|
||||||
Block<Lhs, 1, ei_traits<Lhs>::ColsAtCompileTime>,
|
Block<Lhs, 1, ei_traits<Lhs>::ColsAtCompileTime>,
|
||||||
Block<Rhs, ei_traits<Rhs>::RowsAtCompileTime, 1>,
|
Block<Rhs, ei_traits<Rhs>::RowsAtCompileTime, 1>,
|
||||||
LinearVectorization, NoUnrolling>::run(lhs.row(row), rhs.col(col));
|
LinearVectorizedTraversal, NoUnrolling>::run(lhs.row(row), rhs.col(col));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -282,7 +282,7 @@ struct ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,RhsCols>
|
|||||||
res = ei_dot_impl<
|
res = ei_dot_impl<
|
||||||
Lhs,
|
Lhs,
|
||||||
Block<Rhs, ei_traits<Rhs>::RowsAtCompileTime, 1>,
|
Block<Rhs, ei_traits<Rhs>::RowsAtCompileTime, 1>,
|
||||||
LinearVectorization, NoUnrolling>::run(lhs, rhs.col(col));
|
LinearVectorizedTraversal, NoUnrolling>::run(lhs, rhs.col(col));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -294,7 +294,7 @@ struct ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs,LhsRows,1>
|
|||||||
res = ei_dot_impl<
|
res = ei_dot_impl<
|
||||||
Block<Lhs, 1, ei_traits<Lhs>::ColsAtCompileTime>,
|
Block<Lhs, 1, ei_traits<Lhs>::ColsAtCompileTime>,
|
||||||
Rhs,
|
Rhs,
|
||||||
LinearVectorization, NoUnrolling>::run(lhs.row(row), rhs);
|
LinearVectorizedTraversal, NoUnrolling>::run(lhs.row(row), rhs);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -306,12 +306,12 @@ struct ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,1>
|
|||||||
res = ei_dot_impl<
|
res = ei_dot_impl<
|
||||||
Lhs,
|
Lhs,
|
||||||
Rhs,
|
Rhs,
|
||||||
LinearVectorization, NoUnrolling>::run(lhs, rhs);
|
LinearVectorizedTraversal, NoUnrolling>::run(lhs, rhs);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, typename RetScalar>
|
template<typename Lhs, typename Rhs, typename RetScalar>
|
||||||
struct ei_product_coeff_impl<InnerVectorization, Dynamic, Lhs, Rhs, RetScalar>
|
struct ei_product_coeff_impl<InnerVectorizedTraversal, Dynamic, Lhs, Rhs, RetScalar>
|
||||||
{
|
{
|
||||||
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
|
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
|
||||||
{
|
{
|
||||||
|
@ -160,6 +160,7 @@ template<typename XprType> struct ei_blas_traits
|
|||||||
typedef XprType _ExtractType;
|
typedef XprType _ExtractType;
|
||||||
enum {
|
enum {
|
||||||
IsComplex = NumTraits<Scalar>::IsComplex,
|
IsComplex = NumTraits<Scalar>::IsComplex,
|
||||||
|
IsTransposed = false,
|
||||||
NeedToConjugate = false,
|
NeedToConjugate = false,
|
||||||
ActualAccess = int(ei_traits<XprType>::Flags)&DirectAccessBit ? HasDirectAccess : NoDirectAccess
|
ActualAccess = int(ei_traits<XprType>::Flags)&DirectAccessBit ? HasDirectAccess : NoDirectAccess
|
||||||
};
|
};
|
||||||
@ -214,20 +215,6 @@ struct ei_blas_traits<CwiseUnaryOp<ei_scalar_opposite_op<Scalar>, NestedXpr> >
|
|||||||
{ return - Base::extractScalarFactor(x._expression()); }
|
{ return - Base::extractScalarFactor(x._expression()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// pop NestByValue
|
|
||||||
template<typename NestedXpr>
|
|
||||||
struct ei_blas_traits<NestByValue<NestedXpr> >
|
|
||||||
: ei_blas_traits<NestedXpr>
|
|
||||||
{
|
|
||||||
typedef typename NestedXpr::Scalar Scalar;
|
|
||||||
typedef ei_blas_traits<NestedXpr> Base;
|
|
||||||
typedef NestByValue<NestedXpr> XprType;
|
|
||||||
typedef typename Base::ExtractType ExtractType;
|
|
||||||
static inline ExtractType extract(const XprType& x) { return Base::extract(static_cast<const NestedXpr&>(x)); }
|
|
||||||
static inline Scalar extractScalarFactor(const XprType& x)
|
|
||||||
{ return Base::extractScalarFactor(static_cast<const NestedXpr&>(x)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// pop/push transpose
|
// pop/push transpose
|
||||||
template<typename NestedXpr>
|
template<typename NestedXpr>
|
||||||
struct ei_blas_traits<Transpose<NestedXpr> >
|
struct ei_blas_traits<Transpose<NestedXpr> >
|
||||||
@ -241,6 +228,9 @@ struct ei_blas_traits<Transpose<NestedXpr> >
|
|||||||
ExtractType,
|
ExtractType,
|
||||||
typename ExtractType::PlainMatrixType
|
typename ExtractType::PlainMatrixType
|
||||||
>::ret DirectLinearAccessType;
|
>::ret DirectLinearAccessType;
|
||||||
|
enum {
|
||||||
|
IsTransposed = Base::IsTransposed ? 0 : 1
|
||||||
|
};
|
||||||
static inline const ExtractType extract(const XprType& x) { return Base::extract(x._expression()); }
|
static inline const ExtractType extract(const XprType& x) { return Base::extract(x._expression()); }
|
||||||
static inline Scalar extractScalarFactor(const XprType& x) { return Base::extractScalarFactor(x._expression()); }
|
static inline Scalar extractScalarFactor(const XprType& x) { return Base::extractScalarFactor(x._expression()); }
|
||||||
};
|
};
|
||||||
|
@ -195,16 +195,19 @@ enum DirectionType { Vertical, Horizontal, BothDirections };
|
|||||||
enum ProductEvaluationMode { NormalProduct, CacheFriendlyProduct };
|
enum ProductEvaluationMode { NormalProduct, CacheFriendlyProduct };
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
/** \internal Default traversal, no vectorization, no index-based access */
|
||||||
|
DefaultTraversal,
|
||||||
|
/** \internal No vectorization, use index-based access to have only one for loop instead of 2 nested loops */
|
||||||
|
LinearTraversal,
|
||||||
/** \internal Equivalent to a slice vectorization for fixed-size matrices having good alignment
|
/** \internal Equivalent to a slice vectorization for fixed-size matrices having good alignment
|
||||||
* and good size */
|
* and good size */
|
||||||
InnerVectorization,
|
InnerVectorizedTraversal,
|
||||||
/** \internal Vectorization path using a single loop plus scalar loops for the
|
/** \internal Vectorization path using a single loop plus scalar loops for the
|
||||||
* unaligned boundaries */
|
* unaligned boundaries */
|
||||||
LinearVectorization,
|
LinearVectorizedTraversal,
|
||||||
/** \internal Generic vectorization path using one vectorized loop per row/column with some
|
/** \internal Generic vectorization path using one vectorized loop per row/column with some
|
||||||
* scalar loops to handle the unaligned boundaries */
|
* scalar loops to handle the unaligned boundaries */
|
||||||
SliceVectorization,
|
SliceVectorizedTraversal
|
||||||
NoVectorization
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -218,8 +221,7 @@ enum {
|
|||||||
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,
|
||||||
/** \internal Don't require alignment for the matrix itself (the array of coefficients, if dynamically allocated, may still be
|
/** \internal Don't require alignment for the matrix itself (the array of coefficients, if dynamically allocated, may still be requested to be aligned) */ // FIXME --- clarify the situation
|
||||||
requested to be aligned) */
|
|
||||||
DontAlign = 0x2
|
DontAlign = 0x2
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -267,19 +269,23 @@ enum TransformTraits {
|
|||||||
Projective = 0x20
|
Projective = 0x20
|
||||||
};
|
};
|
||||||
|
|
||||||
const int EiArch_Generic = 0x0;
|
namespace Architecture
|
||||||
const int EiArch_SSE = 0x1;
|
{
|
||||||
const int EiArch_AltiVec = 0x2;
|
enum Type {
|
||||||
|
Generic = 0x0,
|
||||||
|
SSE = 0x1,
|
||||||
|
AltiVec = 0x2,
|
||||||
|
#if defined EIGEN_VECTORIZE_SSE
|
||||||
|
Target = SSE
|
||||||
|
#elif defined EIGEN_VECTORIZE_ALTIVEC
|
||||||
|
Target = AltiVec
|
||||||
|
#else
|
||||||
|
Target = Generic
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
enum DenseStorageMatrix {};
|
enum DenseStorageMatrix {};
|
||||||
enum DenseStorageArray {};
|
enum DenseStorageArray {};
|
||||||
|
|
||||||
#if defined EIGEN_VECTORIZE_SSE
|
|
||||||
const int EiArch = EiArch_SSE;
|
|
||||||
#elif defined EIGEN_VECTORIZE_ALTIVEC
|
|
||||||
const int EiArch = EiArch_AltiVec;
|
|
||||||
#else
|
|
||||||
const int EiArch = EiArch_Generic;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // EIGEN_CONSTANTS_H
|
#endif // EIGEN_CONSTANTS_H
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
// 4273 - QtAlignedMalloc, inconsistent dll linkage
|
// 4273 - QtAlignedMalloc, inconsistent DLL linkage
|
||||||
|
// 4100 - unreferenced formal parameter (occurred e.g. in aligned_allocator::destroy(pointer p))
|
||||||
|
// 4101 - unreferenced local variable
|
||||||
|
// 4512 - assignment operator could not be generated
|
||||||
#pragma warning( push )
|
#pragma warning( push )
|
||||||
#pragma warning( disable : 4181 4244 4127 4211 4273 4522 4717 )
|
#pragma warning( disable : 4100 4101 4181 4244 4127 4211 4273 4512 4522 4717 )
|
||||||
#endif
|
#endif
|
||||||
|
@ -29,8 +29,8 @@
|
|||||||
#undef minor
|
#undef minor
|
||||||
|
|
||||||
#define EIGEN_WORLD_VERSION 2
|
#define EIGEN_WORLD_VERSION 2
|
||||||
#define EIGEN_MAJOR_VERSION 90
|
#define EIGEN_MAJOR_VERSION 91
|
||||||
#define EIGEN_MINOR_VERSION 1
|
#define EIGEN_MINOR_VERSION 0
|
||||||
|
|
||||||
#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 && \
|
||||||
|
@ -209,16 +209,20 @@ template<typename T, bool Align> inline void ei_conditional_aligned_delete(T *pt
|
|||||||
ei_conditional_aligned_free<Align>(ptr);
|
ei_conditional_aligned_free<Align>(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal \returns the number of elements which have to be skipped such that data are 16 bytes aligned */
|
/** \internal \returns the number of elements which have to be skipped to
|
||||||
template<typename Scalar>
|
* find the first 16-byte aligned element
|
||||||
inline static int ei_alignmentOffset(const Scalar* ptr, int maxOffset)
|
*
|
||||||
|
* There is also the variant ei_alignmentOffset(const MatrixBase&, Integer) defined in Coeffs.h.
|
||||||
|
*/
|
||||||
|
template<typename Scalar, typename Integer>
|
||||||
|
inline static Integer ei_alignmentOffset(const Scalar* ptr, Integer maxOffset)
|
||||||
{
|
{
|
||||||
typedef typename ei_packet_traits<Scalar>::type Packet;
|
typedef typename ei_packet_traits<Scalar>::type Packet;
|
||||||
const int PacketSize = ei_packet_traits<Scalar>::size;
|
const Integer PacketSize = ei_packet_traits<Scalar>::size;
|
||||||
const int PacketAlignedMask = PacketSize-1;
|
const Integer PacketAlignedMask = PacketSize-1;
|
||||||
const bool Vectorized = PacketSize>1;
|
const bool Vectorized = PacketSize>1;
|
||||||
return Vectorized
|
return Vectorized
|
||||||
? std::min<int>( (PacketSize - (int((size_t(ptr)/sizeof(Scalar))) & PacketAlignedMask))
|
? std::min<Integer>( (PacketSize - (Integer((size_t(ptr)/sizeof(Scalar))) & PacketAlignedMask))
|
||||||
& PacketAlignedMask, maxOffset)
|
& PacketAlignedMask, maxOffset)
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
@ -28,10 +28,11 @@
|
|||||||
|
|
||||||
// just a workaround because GCC seems to not really like empty structs
|
// just a workaround because GCC seems to not really like empty structs
|
||||||
#ifdef __GNUG__
|
#ifdef __GNUG__
|
||||||
struct ei_empty_struct{char _ei_dummy_;};
|
#define EIGEN_EMPTY_STRUCT_CTOR(X) \
|
||||||
#define EIGEN_EMPTY_STRUCT : Eigen::ei_empty_struct
|
EIGEN_STRONG_INLINE X() {} \
|
||||||
|
EIGEN_STRONG_INLINE X(const X&) {}
|
||||||
#else
|
#else
|
||||||
#define EIGEN_EMPTY_STRUCT
|
#define EIGEN_EMPTY_STRUCT_CTOR(X)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//classes inheriting ei_no_assignment_operator don't generate a default operator=.
|
//classes inheriting ei_no_assignment_operator don't generate a default operator=.
|
||||||
@ -45,10 +46,10 @@ class ei_no_assignment_operator
|
|||||||
* can be accessed using value() and setValue().
|
* can be accessed using value() and setValue().
|
||||||
* Otherwise, this class is an empty structure and value() just returns the template parameter Value.
|
* Otherwise, this class is an empty structure and value() just returns the template parameter Value.
|
||||||
*/
|
*/
|
||||||
template<int Value> class ei_int_if_dynamic EIGEN_EMPTY_STRUCT
|
template<int Value> class ei_int_if_dynamic
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ei_int_if_dynamic() {}
|
EIGEN_EMPTY_STRUCT_CTOR(ei_int_if_dynamic)
|
||||||
explicit ei_int_if_dynamic(int) {}
|
explicit ei_int_if_dynamic(int) {}
|
||||||
static int value() { return Value; }
|
static int value() { return Value; }
|
||||||
void setValue(int) {}
|
void setValue(int) {}
|
||||||
@ -214,8 +215,35 @@ template<typename T> struct ei_plain_matrix_type_row_major
|
|||||||
> type;
|
> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// we should be able to get rid of this one too
|
||||||
template<typename T> struct ei_must_nest_by_value { enum { ret = false }; };
|
template<typename T> struct ei_must_nest_by_value { enum { ret = false }; };
|
||||||
template<typename T> struct ei_must_nest_by_value<NestByValue<T> > { enum { ret = true }; };
|
|
||||||
|
/**
|
||||||
|
* The reference selector for template expressions. The idea is that we don't
|
||||||
|
* need to use references for expressions since they are light weight proxy
|
||||||
|
* objects which should generate no copying overhead.
|
||||||
|
**/
|
||||||
|
template <typename T>
|
||||||
|
struct ei_ref_selector
|
||||||
|
{
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matrices on the other hand side should only be copied, when it is sure
|
||||||
|
* we gain by copying (see arithmetic cost check and eval before nesting flag).
|
||||||
|
* Note: This is an optimization measure that comprises potential (though little)
|
||||||
|
* to create erroneous code. Any user, utilizing ei_nested outside of
|
||||||
|
* Eigen needs to take care that no references to temporaries are
|
||||||
|
* stored or that this potential danger is at least communicated
|
||||||
|
* to the user.
|
||||||
|
**/
|
||||||
|
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
||||||
|
struct ei_ref_selector< Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
|
||||||
|
{
|
||||||
|
typedef Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> MatrixType;
|
||||||
|
typedef MatrixType const& type;
|
||||||
|
};
|
||||||
|
|
||||||
/** \internal Determines how a given expression should be nested into another one.
|
/** \internal Determines how a given expression should be nested into another one.
|
||||||
* For example, when you do a * (b+c), Eigen will determine how the expression b+c should be
|
* For example, when you do a * (b+c), Eigen will determine how the expression b+c should be
|
||||||
@ -241,15 +269,12 @@ template<typename T, int n=1, typename PlainMatrixType = typename ei_eval<T>::ty
|
|||||||
CostEval = (n+1) * int(NumTraits<typename ei_traits<T>::Scalar>::ReadCost),
|
CostEval = (n+1) * int(NumTraits<typename ei_traits<T>::Scalar>::ReadCost),
|
||||||
CostNoEval = (n-1) * int(ei_traits<T>::CoeffReadCost)
|
CostNoEval = (n-1) * int(ei_traits<T>::CoeffReadCost)
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef typename ei_meta_if<
|
typedef typename ei_meta_if<
|
||||||
ei_must_nest_by_value<T>::ret,
|
( int(ei_traits<T>::Flags) & EvalBeforeNestingBit ) ||
|
||||||
T,
|
( int(CostEval) <= int(CostNoEval) ),
|
||||||
typename ei_meta_if<
|
|
||||||
(int(ei_traits<T>::Flags) & EvalBeforeNestingBit)
|
|
||||||
|| ( int(CostEval) <= int(CostNoEval) ),
|
|
||||||
PlainMatrixType,
|
PlainMatrixType,
|
||||||
const T&
|
typename ei_ref_selector<T>::type
|
||||||
>::ret
|
|
||||||
>::ret type;
|
>::ret type;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -302,7 +327,7 @@ template<typename ExpressionType> struct HNormalizedReturnType {
|
|||||||
ei_traits<ExpressionType>::ColsAtCompileTime==1 ? SizeMinusOne : 1,
|
ei_traits<ExpressionType>::ColsAtCompileTime==1 ? SizeMinusOne : 1,
|
||||||
ei_traits<ExpressionType>::ColsAtCompileTime==1 ? 1 : SizeMinusOne> StartMinusOne;
|
ei_traits<ExpressionType>::ColsAtCompileTime==1 ? 1 : SizeMinusOne> StartMinusOne;
|
||||||
typedef CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<ExpressionType>::Scalar>,
|
typedef CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<ExpressionType>::Scalar>,
|
||||||
NestByValue<StartMinusOne> > Type;
|
StartMinusOne > Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename XprType, typename CastType> struct ei_cast_return_type
|
template<typename XprType, typename CastType> struct ei_cast_return_type
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
* convenient macro to defined the return type of a cwise comparison to a scalar */
|
* convenient macro to defined the return type of a cwise comparison to a scalar */
|
||||||
#define EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(OP) \
|
#define EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(OP) \
|
||||||
CwiseBinaryOp<OP<typename ei_traits<ExpressionType>::Scalar>, ExpressionType, \
|
CwiseBinaryOp<OP<typename ei_traits<ExpressionType>::Scalar>, ExpressionType, \
|
||||||
NestByValue<typename ExpressionType::ConstantReturnType> >
|
typename ExpressionType::ConstantReturnType >
|
||||||
|
|
||||||
/** \class Cwise
|
/** \class Cwise
|
||||||
*
|
*
|
||||||
@ -166,9 +166,6 @@ template<typename ExpressionType> class Cwise
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
ExpressionTypeNested m_matrix;
|
ExpressionTypeNested m_matrix;
|
||||||
|
|
||||||
private:
|
|
||||||
Cwise& operator=(const Cwise&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,10 +58,10 @@ template<typename _MatrixType> class HessenbergDecomposition
|
|||||||
typedef Matrix<RealScalar, Size, 1> DiagonalType;
|
typedef Matrix<RealScalar, Size, 1> DiagonalType;
|
||||||
typedef Matrix<RealScalar, SizeMinusOne, 1> SubDiagonalType;
|
typedef Matrix<RealScalar, SizeMinusOne, 1> SubDiagonalType;
|
||||||
|
|
||||||
typedef typename NestByValue<Diagonal<MatrixType,0> >::RealReturnType DiagonalReturnType;
|
typedef typename Diagonal<MatrixType,0>::RealReturnType DiagonalReturnType;
|
||||||
|
|
||||||
typedef typename NestByValue<Diagonal<
|
typedef typename Diagonal<
|
||||||
NestByValue<Block<MatrixType,SizeMinusOne,SizeMinusOne> >,0 > >::RealReturnType SubDiagonalReturnType;
|
Block<MatrixType,SizeMinusOne,SizeMinusOne>,0 >::RealReturnType SubDiagonalReturnType;
|
||||||
|
|
||||||
/** This constructor initializes a HessenbergDecomposition object for
|
/** This constructor initializes a HessenbergDecomposition object for
|
||||||
* further use with HessenbergDecomposition::compute()
|
* further use with HessenbergDecomposition::compute()
|
||||||
|
@ -61,15 +61,15 @@ template<typename _MatrixType> class Tridiagonalization
|
|||||||
typedef Matrix<RealScalar, SizeMinusOne, 1> SubDiagonalType;
|
typedef Matrix<RealScalar, SizeMinusOne, 1> SubDiagonalType;
|
||||||
|
|
||||||
typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
|
typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
|
||||||
typename NestByValue<Diagonal<MatrixType,0> >::RealReturnType,
|
typename Diagonal<MatrixType,0>::RealReturnType,
|
||||||
Diagonal<MatrixType,0>
|
Diagonal<MatrixType,0>
|
||||||
>::ret DiagonalReturnType;
|
>::ret DiagonalReturnType;
|
||||||
|
|
||||||
typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
|
typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
|
||||||
typename NestByValue<Diagonal<
|
typename Diagonal<
|
||||||
NestByValue<Block<MatrixType,SizeMinusOne,SizeMinusOne> >,0 > >::RealReturnType,
|
Block<MatrixType,SizeMinusOne,SizeMinusOne>,0 >::RealReturnType,
|
||||||
Diagonal<
|
Diagonal<
|
||||||
NestByValue<Block<MatrixType,SizeMinusOne,SizeMinusOne> >,0 >
|
Block<MatrixType,SizeMinusOne,SizeMinusOne>,0 >
|
||||||
>::ret SubDiagonalReturnType;
|
>::ret SubDiagonalReturnType;
|
||||||
|
|
||||||
/** This constructor initializes a Tridiagonalization object for
|
/** This constructor initializes a Tridiagonalization object for
|
||||||
@ -144,7 +144,7 @@ template<typename MatrixType>
|
|||||||
const typename Tridiagonalization<MatrixType>::DiagonalReturnType
|
const typename Tridiagonalization<MatrixType>::DiagonalReturnType
|
||||||
Tridiagonalization<MatrixType>::diagonal(void) const
|
Tridiagonalization<MatrixType>::diagonal(void) const
|
||||||
{
|
{
|
||||||
return m_matrix.diagonal().nestByValue();
|
return m_matrix.diagonal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns an expression of the sub-diagonal vector */
|
/** \returns an expression of the sub-diagonal vector */
|
||||||
@ -153,8 +153,7 @@ const typename Tridiagonalization<MatrixType>::SubDiagonalReturnType
|
|||||||
Tridiagonalization<MatrixType>::subDiagonal(void) const
|
Tridiagonalization<MatrixType>::subDiagonal(void) const
|
||||||
{
|
{
|
||||||
int n = m_matrix.rows();
|
int n = m_matrix.rows();
|
||||||
return Block<MatrixType,SizeMinusOne,SizeMinusOne>(m_matrix, 1, 0, n-1,n-1)
|
return Block<MatrixType,SizeMinusOne,SizeMinusOne>(m_matrix, 1, 0, n-1,n-1).diagonal();
|
||||||
.nestByValue().diagonal().nestByValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** constructs and returns the tridiagonal matrix T.
|
/** constructs and returns the tridiagonal matrix T.
|
||||||
|
@ -171,7 +171,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
|
|||||||
* determined by \a prec.
|
* determined by \a prec.
|
||||||
*
|
*
|
||||||
* \sa MatrixBase::isApprox() */
|
* \sa MatrixBase::isApprox() */
|
||||||
bool isApprox(const AlignedBox& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
|
bool isApprox(const AlignedBox& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const
|
||||||
{ return m_min.isApprox(other.m_min, prec) && m_max.isApprox(other.m_max, prec); }
|
{ return m_min.isApprox(other.m_min, prec) && m_max.isApprox(other.m_max, prec); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -146,7 +146,7 @@ public:
|
|||||||
* determined by \a prec.
|
* determined by \a prec.
|
||||||
*
|
*
|
||||||
* \sa MatrixBase::isApprox() */
|
* \sa MatrixBase::isApprox() */
|
||||||
bool isApprox(const AngleAxis& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
|
bool isApprox(const AngleAxis& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const
|
||||||
{ return m_axis.isApprox(other.m_axis, prec) && ei_isApprox(m_angle,other.m_angle, prec); }
|
{ return m_axis.isApprox(other.m_axis, prec) && ei_isApprox(m_angle,other.m_angle, prec); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ template<typename QuatDerived>
|
|||||||
AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived>& q)
|
AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived>& q)
|
||||||
{
|
{
|
||||||
Scalar n2 = q.vec().squaredNorm();
|
Scalar n2 = q.vec().squaredNorm();
|
||||||
if (n2 < precision<Scalar>()*precision<Scalar>())
|
if (n2 < dummy_precision<Scalar>()*dummy_precision<Scalar>())
|
||||||
{
|
{
|
||||||
m_angle = 0;
|
m_angle = 0;
|
||||||
m_axis << 1, 0, 0;
|
m_axis << 1, 0, 0;
|
||||||
|
@ -50,7 +50,7 @@ MatrixBase<Derived>::eulerAngles(int a0, int a1, int a2) const
|
|||||||
|
|
||||||
Matrix<Scalar,3,1> res;
|
Matrix<Scalar,3,1> res;
|
||||||
typedef Matrix<typename Derived::Scalar,2,1> Vector2;
|
typedef Matrix<typename Derived::Scalar,2,1> Vector2;
|
||||||
const Scalar epsilon = precision<Scalar>();
|
const Scalar epsilon = dummy_precision<Scalar>();
|
||||||
|
|
||||||
const int odd = ((a0+1)%3 == a1) ? 0 : 1;
|
const int odd = ((a0+1)%3 == a1) ? 0 : 1;
|
||||||
const int i = a0;
|
const int i = a0;
|
||||||
|
@ -176,7 +176,7 @@ MatrixBase<Derived>::hnormalized() const
|
|||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
|
||||||
return StartMinusOne(derived(),0,0,
|
return StartMinusOne(derived(),0,0,
|
||||||
ColsAtCompileTime==1?size()-1:1,
|
ColsAtCompileTime==1?size()-1:1,
|
||||||
ColsAtCompileTime==1?1:size()-1).nestByValue() / coeff(size()-1);
|
ColsAtCompileTime==1?1:size()-1) / coeff(size()-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \geometry_module
|
/** \geometry_module
|
||||||
@ -193,8 +193,7 @@ VectorwiseOp<ExpressionType,Direction>::hnormalized() const
|
|||||||
{
|
{
|
||||||
return HNormalized_Block(_expression(),0,0,
|
return HNormalized_Block(_expression(),0,0,
|
||||||
Direction==Vertical ? _expression().rows()-1 : _expression().rows(),
|
Direction==Vertical ? _expression().rows()-1 : _expression().rows(),
|
||||||
Direction==Horizontal ? _expression().cols()-1 : _expression().cols()).nestByValue()
|
Direction==Horizontal ? _expression().cols()-1 : _expression().cols()).cwiseQuotient(
|
||||||
.cwiseQuotient(
|
|
||||||
Replicate<NestByValue<HNormalized_Factors>,
|
Replicate<NestByValue<HNormalized_Factors>,
|
||||||
Direction==Vertical ? HNormalized_SizeMinusOne : 1,
|
Direction==Vertical ? HNormalized_SizeMinusOne : 1,
|
||||||
Direction==Horizontal ? HNormalized_SizeMinusOne : 1>
|
Direction==Horizontal ? HNormalized_SizeMinusOne : 1>
|
||||||
@ -202,9 +201,9 @@ VectorwiseOp<ExpressionType,Direction>::hnormalized() const
|
|||||||
Direction==Vertical ? _expression().rows()-1:0,
|
Direction==Vertical ? _expression().rows()-1:0,
|
||||||
Direction==Horizontal ? _expression().cols()-1:0,
|
Direction==Horizontal ? _expression().cols()-1:0,
|
||||||
Direction==Vertical ? 1 : _expression().rows(),
|
Direction==Vertical ? 1 : _expression().rows(),
|
||||||
Direction==Horizontal ? 1 : _expression().cols()).nestByValue(),
|
Direction==Horizontal ? 1 : _expression().cols()),
|
||||||
Direction==Vertical ? _expression().rows()-1 : 1,
|
Direction==Vertical ? _expression().rows()-1 : 1,
|
||||||
Direction==Horizontal ? _expression().cols()-1 : 1).nestByValue());
|
Direction==Horizontal ? _expression().cols()-1 : 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename MatrixType,typename Lhs>
|
template<typename MatrixType,typename Lhs>
|
||||||
@ -281,7 +280,6 @@ struct ei_homogeneous_right_product_impl<Homogeneous<MatrixType,Horizontal>,Rhs>
|
|||||||
|
|
||||||
const typename MatrixType::Nested m_lhs;
|
const typename MatrixType::Nested m_lhs;
|
||||||
const typename Rhs::Nested m_rhs;
|
const typename Rhs::Nested m_rhs;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EIGEN_HOMOGENEOUS_H
|
#endif // EIGEN_HOMOGENEOUS_H
|
||||||
|
@ -52,9 +52,9 @@ public:
|
|||||||
typedef _Scalar Scalar;
|
typedef _Scalar Scalar;
|
||||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||||
typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType;
|
typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType;
|
||||||
typedef Matrix<Scalar,AmbientDimAtCompileTime==Dynamic
|
typedef Matrix<Scalar,int(AmbientDimAtCompileTime)==Dynamic
|
||||||
? Dynamic
|
? Dynamic
|
||||||
: AmbientDimAtCompileTime+1,1> Coefficients;
|
: int(AmbientDimAtCompileTime)+1,1> Coefficients;
|
||||||
typedef Block<Coefficients,AmbientDimAtCompileTime,1> NormalReturnType;
|
typedef Block<Coefficients,AmbientDimAtCompileTime,1> NormalReturnType;
|
||||||
|
|
||||||
/** Default constructor without initialization */
|
/** Default constructor without initialization */
|
||||||
@ -257,7 +257,7 @@ public:
|
|||||||
* determined by \a prec.
|
* determined by \a prec.
|
||||||
*
|
*
|
||||||
* \sa MatrixBase::isApprox() */
|
* \sa MatrixBase::isApprox() */
|
||||||
bool isApprox(const Hyperplane& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
|
bool isApprox(const Hyperplane& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const
|
||||||
{ return m_coeffs.isApprox(other.m_coeffs, prec); }
|
{ return m_coeffs.isApprox(other.m_coeffs, prec); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -90,7 +90,8 @@ MatrixBase<Derived>::cross3(const MatrixBase<OtherDerived>& other) const
|
|||||||
const DerivedNested lhs(derived());
|
const DerivedNested lhs(derived());
|
||||||
const OtherDerivedNested rhs(other.derived());
|
const OtherDerivedNested rhs(other.derived());
|
||||||
|
|
||||||
return ei_cross3_impl<EiArch,typename ei_cleantype<DerivedNested>::type,
|
return ei_cross3_impl<Architecture::Target,
|
||||||
|
typename ei_cleantype<DerivedNested>::type,
|
||||||
typename ei_cleantype<OtherDerivedNested>::type>::run(lhs,rhs);
|
typename ei_cleantype<OtherDerivedNested>::type>::run(lhs,rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ public:
|
|||||||
* determined by \a prec.
|
* determined by \a prec.
|
||||||
*
|
*
|
||||||
* \sa MatrixBase::isApprox() */
|
* \sa MatrixBase::isApprox() */
|
||||||
bool isApprox(const ParametrizedLine& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
|
bool isApprox(const ParametrizedLine& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const
|
||||||
{ return m_origin.isApprox(other.m_origin, prec) && m_direction.isApprox(other.m_direction, prec); }
|
{ return m_origin.isApprox(other.m_origin, prec) && m_direction.isApprox(other.m_direction, prec); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -163,7 +163,7 @@ public:
|
|||||||
*
|
*
|
||||||
* \sa MatrixBase::isApprox() */
|
* \sa MatrixBase::isApprox() */
|
||||||
template<class OtherDerived>
|
template<class OtherDerived>
|
||||||
bool isApprox(const QuaternionBase<OtherDerived>& other, RealScalar prec = precision<Scalar>()) const
|
bool isApprox(const QuaternionBase<OtherDerived>& other, RealScalar prec = dummy_precision<Scalar>()) const
|
||||||
{ return coeffs().isApprox(other.coeffs(), prec); }
|
{ return coeffs().isApprox(other.coeffs(), prec); }
|
||||||
|
|
||||||
/** return the result vector of \a v through the rotation*/
|
/** return the result vector of \a v through the rotation*/
|
||||||
@ -304,27 +304,20 @@ template<typename _Scalar, int PacketAccess>
|
|||||||
class Map<Quaternion<_Scalar>, PacketAccess >
|
class Map<Quaternion<_Scalar>, PacketAccess >
|
||||||
: public QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> >
|
: public QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> >
|
||||||
{
|
{
|
||||||
|
typedef QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> > Base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef _Scalar Scalar;
|
typedef _Scalar Scalar;
|
||||||
typedef Map<Quaternion<Scalar>, PacketAccess > MapQuat;
|
typedef typename ei_traits<Map>::Coefficients Coefficients;
|
||||||
|
EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Map)
|
||||||
private:
|
|
||||||
Map<Quaternion<Scalar>, PacketAccess >();
|
|
||||||
Map<Quaternion<Scalar>, PacketAccess >(const Map<Quaternion<Scalar>, PacketAccess>&);
|
|
||||||
|
|
||||||
typedef QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> > Base;
|
|
||||||
public:
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(MapQuat)
|
|
||||||
using Base::operator*=;
|
using Base::operator*=;
|
||||||
|
|
||||||
typedef typename ei_traits<Map<Quaternion<Scalar>, PacketAccess> >::Coefficients Coefficients;
|
|
||||||
|
|
||||||
/** Constructs a Mapped Quaternion object from the pointer \a coeffs
|
/** Constructs a Mapped Quaternion object from the pointer \a coeffs
|
||||||
*
|
*
|
||||||
* The pointer \a coeffs must reference the four coeffecients of Quaternion in the following order:
|
* 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 paramter PacketAccess is set to Aligned, then the pointer coeffs must be aligned. */
|
* If the template parameter PacketAccess is set to Aligned, then the pointer coeffs must be aligned. */
|
||||||
EIGEN_STRONG_INLINE Map(const Scalar* coeffs) : m_coeffs(coeffs) {}
|
EIGEN_STRONG_INLINE Map(const Scalar* coeffs) : m_coeffs(coeffs) {}
|
||||||
|
|
||||||
inline Coefficients& coeffs() { return m_coeffs;}
|
inline Coefficients& coeffs() { return m_coeffs;}
|
||||||
@ -374,7 +367,7 @@ QuaternionBase<Derived>::operator* (const QuaternionBase<OtherDerived>& other) c
|
|||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT((ei_is_same_type<typename Derived::Scalar, typename OtherDerived::Scalar>::ret),
|
EIGEN_STATIC_ASSERT((ei_is_same_type<typename Derived::Scalar, typename OtherDerived::Scalar>::ret),
|
||||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||||
return ei_quat_product<EiArch, Derived, OtherDerived,
|
return ei_quat_product<Architecture::Target, Derived, OtherDerived,
|
||||||
typename ei_traits<Derived>::Scalar,
|
typename ei_traits<Derived>::Scalar,
|
||||||
ei_traits<Derived>::PacketAccess && ei_traits<OtherDerived>::PacketAccess>::run(*this, other);
|
ei_traits<Derived>::PacketAccess && ei_traits<OtherDerived>::PacketAccess>::run(*this, other);
|
||||||
}
|
}
|
||||||
@ -514,7 +507,7 @@ inline Derived& QuaternionBase<Derived>::setFromTwoVectors(const MatrixBase<Deri
|
|||||||
// under the constraint:
|
// under the constraint:
|
||||||
// ||x|| = 1
|
// ||x|| = 1
|
||||||
// which yields a singular value problem
|
// which yields a singular value problem
|
||||||
if (c < Scalar(-1)+precision<Scalar>())
|
if (c < Scalar(-1)+dummy_precision<Scalar>())
|
||||||
{
|
{
|
||||||
c = std::max<Scalar>(c,-1);
|
c = std::max<Scalar>(c,-1);
|
||||||
Matrix<Scalar,2,3> m; m << v0.transpose(), v1.transpose();
|
Matrix<Scalar,2,3> m; m << v0.transpose(), v1.transpose();
|
||||||
@ -590,20 +583,29 @@ template <class OtherDerived>
|
|||||||
Quaternion<typename ei_traits<Derived>::Scalar>
|
Quaternion<typename ei_traits<Derived>::Scalar>
|
||||||
QuaternionBase<Derived>::slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const
|
QuaternionBase<Derived>::slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const
|
||||||
{
|
{
|
||||||
static const Scalar one = Scalar(1) - precision<Scalar>();
|
static const Scalar one = Scalar(1) - epsilon<Scalar>();
|
||||||
Scalar d = this->dot(other);
|
Scalar d = this->dot(other);
|
||||||
Scalar absD = ei_abs(d);
|
Scalar absD = ei_abs(d);
|
||||||
if (absD>=one)
|
|
||||||
return Quaternion<Scalar>(derived());
|
|
||||||
|
|
||||||
|
Scalar scale0;
|
||||||
|
Scalar scale1;
|
||||||
|
|
||||||
|
if (absD>=one)
|
||||||
|
{
|
||||||
|
scale0 = Scalar(1) - t;
|
||||||
|
scale1 = t;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// theta is the angle between the 2 quaternions
|
// theta is the angle between the 2 quaternions
|
||||||
Scalar theta = std::acos(absD);
|
Scalar theta = std::acos(absD);
|
||||||
Scalar sinTheta = ei_sin(theta);
|
Scalar sinTheta = ei_sin(theta);
|
||||||
|
|
||||||
Scalar scale0 = ei_sin( ( Scalar(1) - t ) * theta) / sinTheta;
|
scale0 = ei_sin( ( Scalar(1) - t ) * theta) / sinTheta;
|
||||||
Scalar scale1 = ei_sin( ( t * theta) ) / sinTheta;
|
scale1 = ei_sin( ( t * theta) ) / sinTheta;
|
||||||
if (d<0)
|
if (d<0)
|
||||||
scale1 = -scale1;
|
scale1 = -scale1;
|
||||||
|
}
|
||||||
|
|
||||||
return Quaternion<Scalar>(scale0 * coeffs() + scale1 * other.coeffs());
|
return Quaternion<Scalar>(scale0 * coeffs() + scale1 * other.coeffs());
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ public:
|
|||||||
* determined by \a prec.
|
* determined by \a prec.
|
||||||
*
|
*
|
||||||
* \sa MatrixBase::isApprox() */
|
* \sa MatrixBase::isApprox() */
|
||||||
bool isApprox(const Rotation2D& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
|
bool isApprox(const Rotation2D& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const
|
||||||
{ return ei_isApprox(m_angle,other.m_angle, prec); }
|
{ return ei_isApprox(m_angle,other.m_angle, prec); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ public:
|
|||||||
* determined by \a prec.
|
* determined by \a prec.
|
||||||
*
|
*
|
||||||
* \sa MatrixBase::isApprox() */
|
* \sa MatrixBase::isApprox() */
|
||||||
bool isApprox(const UniformScaling& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
|
bool isApprox(const UniformScaling& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const
|
||||||
{ return ei_isApprox(m_factor, other.factor(), prec); }
|
{ return ei_isApprox(m_factor, other.factor(), prec); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -187,7 +187,7 @@ public:
|
|||||||
/** type of read/write reference to the affine part of the transformation */
|
/** type of read/write reference to the affine part of the transformation */
|
||||||
typedef typename ei_meta_if<int(Mode)==int(AffineCompact),
|
typedef typename ei_meta_if<int(Mode)==int(AffineCompact),
|
||||||
MatrixType&,
|
MatrixType&,
|
||||||
NestByValue<Block<MatrixType,Dim,HDim> > >::ret AffinePartNested;
|
Block<MatrixType,Dim,HDim> >::ret AffinePartNested;
|
||||||
/** type of a vector */
|
/** type of a vector */
|
||||||
typedef Matrix<Scalar,Dim,1> VectorType;
|
typedef Matrix<Scalar,Dim,1> VectorType;
|
||||||
/** type of a read/write reference to the translation part of the rotation */
|
/** type of a read/write reference to the translation part of the rotation */
|
||||||
@ -424,7 +424,7 @@ public:
|
|||||||
* determined by \a prec.
|
* determined by \a prec.
|
||||||
*
|
*
|
||||||
* \sa MatrixBase::isApprox() */
|
* \sa MatrixBase::isApprox() */
|
||||||
bool isApprox(const Transform& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
|
bool isApprox(const Transform& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const
|
||||||
{ return m_matrix.isApprox(other.m_matrix, prec); }
|
{ return m_matrix.isApprox(other.m_matrix, prec); }
|
||||||
|
|
||||||
/** Sets the last row to [0 ... 0 1]
|
/** Sets the last row to [0 ... 0 1]
|
||||||
|
@ -154,7 +154,7 @@ public:
|
|||||||
* determined by \a prec.
|
* determined by \a prec.
|
||||||
*
|
*
|
||||||
* \sa MatrixBase::isApprox() */
|
* \sa MatrixBase::isApprox() */
|
||||||
bool isApprox(const Translation& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
|
bool isApprox(const Translation& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const
|
||||||
{ return m_coeffs.isApprox(other.m_coeffs, prec); }
|
{ return m_coeffs.isApprox(other.m_coeffs, prec); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -26,7 +26,8 @@
|
|||||||
#ifndef EIGEN_GEOMETRY_SSE_H
|
#ifndef EIGEN_GEOMETRY_SSE_H
|
||||||
#define EIGEN_GEOMETRY_SSE_H
|
#define EIGEN_GEOMETRY_SSE_H
|
||||||
|
|
||||||
template<class Derived, class OtherDerived> struct ei_quat_product<EiArch_SSE, Derived, OtherDerived, float, Aligned>
|
template<class Derived, class OtherDerived>
|
||||||
|
struct ei_quat_product<Architecture::SSE, Derived, OtherDerived, float, Aligned>
|
||||||
{
|
{
|
||||||
inline static Quaternion<float> run(const QuaternionBase<Derived>& _a, const QuaternionBase<OtherDerived>& _b)
|
inline static Quaternion<float> run(const QuaternionBase<Derived>& _a, const QuaternionBase<OtherDerived>& _b)
|
||||||
{
|
{
|
||||||
@ -48,7 +49,8 @@ template<class Derived, class OtherDerived> struct ei_quat_product<EiArch_SSE, D
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename VectorLhs,typename VectorRhs>
|
template<typename VectorLhs,typename VectorRhs>
|
||||||
struct ei_cross3_impl<EiArch_SSE,VectorLhs,VectorRhs,float,true> {
|
struct ei_cross3_impl<Architecture::SSE,VectorLhs,VectorRhs,float,true>
|
||||||
|
{
|
||||||
inline static typename ei_plain_matrix_type<VectorLhs>::type
|
inline static typename ei_plain_matrix_type<VectorLhs>::type
|
||||||
run(const VectorLhs& lhs, const VectorRhs& rhs)
|
run(const VectorLhs& lhs, const VectorRhs& rhs)
|
||||||
{
|
{
|
||||||
|
@ -73,27 +73,31 @@ template<typename VectorsType, typename CoeffsType> class HouseholderSequence
|
|||||||
CoeffsType>::ret> ConjugateReturnType;
|
CoeffsType>::ret> ConjugateReturnType;
|
||||||
|
|
||||||
HouseholderSequence(const VectorsType& v, const CoeffsType& h, bool trans = false)
|
HouseholderSequence(const VectorsType& v, const CoeffsType& h, bool trans = false)
|
||||||
: m_vectors(v), m_coeffs(h), m_trans(trans)
|
: m_vectors(v), m_coeffs(h), m_trans(trans), m_actualVectors(v.diagonalSize())
|
||||||
|
{}
|
||||||
|
|
||||||
|
HouseholderSequence(const VectorsType& v, const CoeffsType& h, bool trans, int actualVectors)
|
||||||
|
: m_vectors(v), m_coeffs(h), m_trans(trans), m_actualVectors(actualVectors)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
int rows() const { return m_vectors.rows(); }
|
int rows() const { return m_vectors.rows(); }
|
||||||
int cols() const { return m_vectors.rows(); }
|
int cols() const { return m_vectors.rows(); }
|
||||||
|
|
||||||
HouseholderSequence transpose() const
|
HouseholderSequence transpose() const
|
||||||
{ return HouseholderSequence(m_vectors, m_coeffs, !m_trans); }
|
{ return HouseholderSequence(m_vectors, m_coeffs, !m_trans, m_actualVectors); }
|
||||||
|
|
||||||
ConjugateReturnType conjugate() const
|
ConjugateReturnType conjugate() const
|
||||||
{ return ConjugateReturnType(m_vectors, m_coeffs.conjugate(), m_trans); }
|
{ return ConjugateReturnType(m_vectors, m_coeffs.conjugate(), m_trans, m_actualVectors); }
|
||||||
|
|
||||||
ConjugateReturnType adjoint() const
|
ConjugateReturnType adjoint() const
|
||||||
{ return ConjugateReturnType(m_vectors, m_coeffs.conjugate(), !m_trans); }
|
{ return ConjugateReturnType(m_vectors, m_coeffs.conjugate(), !m_trans, m_actualVectors); }
|
||||||
|
|
||||||
ConjugateReturnType inverse() const { return adjoint(); }
|
ConjugateReturnType inverse() const { return adjoint(); }
|
||||||
|
|
||||||
/** \internal */
|
/** \internal */
|
||||||
template<typename DestType> void evalTo(DestType& dst) const
|
template<typename DestType> void evalTo(DestType& dst) const
|
||||||
{
|
{
|
||||||
int vecs = std::min(m_vectors.cols(),m_vectors.rows());
|
int vecs = m_actualVectors;
|
||||||
int length = m_vectors.rows();
|
int length = m_vectors.rows();
|
||||||
dst.setIdentity();
|
dst.setIdentity();
|
||||||
Matrix<Scalar,1,DestType::RowsAtCompileTime> temp(dst.rows());
|
Matrix<Scalar,1,DestType::RowsAtCompileTime> temp(dst.rows());
|
||||||
@ -111,21 +115,21 @@ template<typename VectorsType, typename CoeffsType> class HouseholderSequence
|
|||||||
/** \internal */
|
/** \internal */
|
||||||
template<typename Dest> inline void applyThisOnTheRight(Dest& dst) const
|
template<typename Dest> inline void applyThisOnTheRight(Dest& dst) const
|
||||||
{
|
{
|
||||||
int vecs = std::min(m_vectors.cols(),m_vectors.rows()); // number of householder vectors
|
int vecs = m_actualVectors; // number of householder vectors
|
||||||
int length = m_vectors.rows(); // size of the largest householder vector
|
int length = m_vectors.rows(); // size of the largest householder vector
|
||||||
Matrix<Scalar,1,Dest::ColsAtCompileTime> temp(dst.rows());
|
Matrix<Scalar,1,Dest::RowsAtCompileTime> temp(dst.rows());
|
||||||
for(int k = 0; k < vecs; ++k)
|
for(int k = 0; k < vecs; ++k)
|
||||||
{
|
{
|
||||||
int actual_k = m_trans ? vecs-k-1 : k;
|
int actual_k = m_trans ? vecs-k-1 : k;
|
||||||
dst.corner(BottomRight, dst.rows(), length-k)
|
dst.corner(BottomRight, dst.rows(), length-actual_k)
|
||||||
.applyHouseholderOnTheRight(m_vectors.col(k).end(length-k-1), m_coeffs.coeff(k), &temp.coeffRef(0));
|
.applyHouseholderOnTheRight(m_vectors.col(actual_k).end(length-actual_k-1), m_coeffs.coeff(actual_k), &temp.coeffRef(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal */
|
/** \internal */
|
||||||
template<typename Dest> inline void applyThisOnTheLeft(Dest& dst) const
|
template<typename Dest> inline void applyThisOnTheLeft(Dest& dst) const
|
||||||
{
|
{
|
||||||
int vecs = std::min(m_vectors.cols(),m_vectors.rows()); // number of householder vectors
|
int vecs = m_actualVectors; // number of householder vectors
|
||||||
int length = m_vectors.rows(); // size of the largest householder vector
|
int length = m_vectors.rows(); // size of the largest householder vector
|
||||||
Matrix<Scalar,1,Dest::ColsAtCompileTime> temp(dst.cols());
|
Matrix<Scalar,1,Dest::ColsAtCompileTime> temp(dst.cols());
|
||||||
for(int k = 0; k < vecs; ++k)
|
for(int k = 0; k < vecs; ++k)
|
||||||
@ -156,9 +160,7 @@ template<typename VectorsType, typename CoeffsType> class HouseholderSequence
|
|||||||
typename VectorsType::Nested m_vectors;
|
typename VectorsType::Nested m_vectors;
|
||||||
typename CoeffsType::Nested m_coeffs;
|
typename CoeffsType::Nested m_coeffs;
|
||||||
bool m_trans;
|
bool m_trans;
|
||||||
|
int m_actualVectors;
|
||||||
private:
|
|
||||||
HouseholderSequence& operator=(const HouseholderSequence&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename VectorsType, typename CoeffsType>
|
template<typename VectorsType, typename CoeffsType>
|
||||||
@ -167,4 +169,10 @@ HouseholderSequence<VectorsType,CoeffsType> householderSequence(const VectorsTyp
|
|||||||
return HouseholderSequence<VectorsType,CoeffsType>(v, h, trans);
|
return HouseholderSequence<VectorsType,CoeffsType>(v, h, trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename VectorsType, typename CoeffsType>
|
||||||
|
HouseholderSequence<VectorsType,CoeffsType> householderSequence(const VectorsType& v, const CoeffsType& h, bool trans, int actualVectors)
|
||||||
|
{
|
||||||
|
return HouseholderSequence<VectorsType,CoeffsType>(v, h, trans, actualVectors);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // EIGEN_HOUSEHOLDER_SEQUENCE_H
|
#endif // EIGEN_HOUSEHOLDER_SEQUENCE_H
|
||||||
|
@ -4,3 +4,5 @@ INSTALL(FILES
|
|||||||
${Eigen_LU_SRCS}
|
${Eigen_LU_SRCS}
|
||||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/LU COMPONENT Devel
|
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/LU COMPONENT Devel
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ADD_SUBDIRECTORY(arch)
|
||||||
|
@ -118,7 +118,9 @@ template<typename Derived>
|
|||||||
inline typename ei_traits<Derived>::Scalar MatrixBase<Derived>::determinant() const
|
inline typename ei_traits<Derived>::Scalar MatrixBase<Derived>::determinant() const
|
||||||
{
|
{
|
||||||
assert(rows() == cols());
|
assert(rows() == cols());
|
||||||
return ei_determinant_impl<Derived>::run(derived());
|
typedef typename ei_nested<Derived,RowsAtCompileTime>::type Nested;
|
||||||
|
Nested nested(derived());
|
||||||
|
return ei_determinant_impl<typename ei_cleantype<Nested>::type>::run(nested);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // EIGEN_DETERMINANT_H
|
#endif // EIGEN_DETERMINANT_H
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// the License, or (at your option) any later version.
|
// the License, or (at your option) any later version.
|
||||||
//
|
//
|
||||||
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
// // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
@ -63,8 +63,8 @@ template<typename _MatrixType> class FullPivLU
|
|||||||
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
|
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
|
||||||
typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
|
typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
|
||||||
typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
|
typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
|
||||||
typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;
|
typedef PermutationMatrix<MatrixType::ColsAtCompileTime> PermutationQType;
|
||||||
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType;
|
typedef PermutationMatrix<MatrixType::RowsAtCompileTime> PermutationPType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Default Constructor.
|
* \brief Default Constructor.
|
||||||
@ -120,25 +120,21 @@ template<typename _MatrixType> class FullPivLU
|
|||||||
*/
|
*/
|
||||||
RealScalar maxPivot() const { return m_maxpivot; }
|
RealScalar maxPivot() const { return m_maxpivot; }
|
||||||
|
|
||||||
/** \returns a vector of integers, whose size is the number of rows of the matrix being decomposed,
|
/** \returns the permutation matrix P
|
||||||
* representing the P permutation i.e. the permutation of the rows. For its precise meaning,
|
|
||||||
* see the examples given in the documentation of class FullPivLU.
|
|
||||||
*
|
*
|
||||||
* \sa permutationQ()
|
* \sa permutationQ()
|
||||||
*/
|
*/
|
||||||
inline const IntColVectorType& permutationP() const
|
inline const PermutationPType& permutationP() const
|
||||||
{
|
{
|
||||||
ei_assert(m_isInitialized && "LU is not initialized.");
|
ei_assert(m_isInitialized && "LU is not initialized.");
|
||||||
return m_p;
|
return m_p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns a vector of integers, whose size is the number of columns of the matrix being
|
/** \returns the permutation matrix Q
|
||||||
* decomposed, representing the Q permutation i.e. the permutation of the columns.
|
|
||||||
* For its precise meaning, see the examples given in the documentation of class FullPivLU.
|
|
||||||
*
|
*
|
||||||
* \sa permutationP()
|
* \sa permutationP()
|
||||||
*/
|
*/
|
||||||
inline const IntRowVectorType& permutationQ() const
|
inline const PermutationQType& permutationQ() const
|
||||||
{
|
{
|
||||||
ei_assert(m_isInitialized && "LU is not initialized.");
|
ei_assert(m_isInitialized && "LU is not initialized.");
|
||||||
return m_q;
|
return m_q;
|
||||||
@ -238,8 +234,9 @@ template<typename _MatrixType> class FullPivLU
|
|||||||
* who need to determine when pivots are to be considered nonzero. This is not used for the
|
* who need to determine when pivots are to be considered nonzero. This is not used for the
|
||||||
* LU decomposition itself.
|
* LU decomposition itself.
|
||||||
*
|
*
|
||||||
* When it needs to get the threshold value, Eigen calls threshold(). By default, this calls
|
* When it needs to get the threshold value, Eigen calls threshold(). By default, this
|
||||||
* defaultThreshold(). Once you have called the present method setThreshold(const RealScalar&),
|
* uses a formula to automatically determine a reasonable threshold.
|
||||||
|
* Once you have called the present method setThreshold(const RealScalar&),
|
||||||
* your value is used instead.
|
* your value is used instead.
|
||||||
*
|
*
|
||||||
* \param threshold The new value to use as the threshold.
|
* \param threshold The new value to use as the threshold.
|
||||||
@ -307,7 +304,7 @@ template<typename _MatrixType> class FullPivLU
|
|||||||
inline int dimensionOfKernel() const
|
inline int dimensionOfKernel() const
|
||||||
{
|
{
|
||||||
ei_assert(m_isInitialized && "LU is not initialized.");
|
ei_assert(m_isInitialized && "LU is not initialized.");
|
||||||
return m_lu.cols() - rank();
|
return cols() - rank();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns true if the matrix of which *this is the LU decomposition represents an injective
|
/** \returns true if the matrix of which *this is the LU decomposition represents an injective
|
||||||
@ -320,7 +317,7 @@ template<typename _MatrixType> class FullPivLU
|
|||||||
inline bool isInjective() const
|
inline bool isInjective() const
|
||||||
{
|
{
|
||||||
ei_assert(m_isInitialized && "LU is not initialized.");
|
ei_assert(m_isInitialized && "LU is not initialized.");
|
||||||
return rank() == m_lu.cols();
|
return rank() == cols();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns true if the matrix of which *this is the LU decomposition represents a surjective
|
/** \returns true if the matrix of which *this is the LU decomposition represents a surjective
|
||||||
@ -333,7 +330,7 @@ template<typename _MatrixType> class FullPivLU
|
|||||||
inline bool isSurjective() const
|
inline bool isSurjective() const
|
||||||
{
|
{
|
||||||
ei_assert(m_isInitialized && "LU is not initialized.");
|
ei_assert(m_isInitialized && "LU is not initialized.");
|
||||||
return rank() == m_lu.rows();
|
return rank() == rows();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns true if the matrix of which *this is the LU decomposition is invertible.
|
/** \returns true if the matrix of which *this is the LU decomposition is invertible.
|
||||||
@ -355,12 +352,12 @@ template<typename _MatrixType> class FullPivLU
|
|||||||
*
|
*
|
||||||
* \sa MatrixBase::inverse()
|
* \sa MatrixBase::inverse()
|
||||||
*/
|
*/
|
||||||
inline const ei_solve_retval<FullPivLU,NestByValue<typename MatrixType::IdentityReturnType> > inverse() const
|
inline const ei_solve_retval<FullPivLU,typename MatrixType::IdentityReturnType> inverse() const
|
||||||
{
|
{
|
||||||
ei_assert(m_isInitialized && "LU is not initialized.");
|
ei_assert(m_isInitialized && "LU is not initialized.");
|
||||||
ei_assert(m_lu.rows() == m_lu.cols() && "You can't take the inverse of a non-square matrix!");
|
ei_assert(m_lu.rows() == m_lu.cols() && "You can't take the inverse of a non-square matrix!");
|
||||||
return ei_solve_retval<FullPivLU,NestByValue<typename MatrixType::IdentityReturnType> >
|
return ei_solve_retval<FullPivLU,typename MatrixType::IdentityReturnType>
|
||||||
(*this, MatrixType::Identity(m_lu.rows(), m_lu.cols()).nestByValue());
|
(*this, MatrixType::Identity(m_lu.rows(), m_lu.cols()));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int rows() const { return m_lu.rows(); }
|
inline int rows() const { return m_lu.rows(); }
|
||||||
@ -368,8 +365,8 @@ template<typename _MatrixType> class FullPivLU
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
MatrixType m_lu;
|
MatrixType m_lu;
|
||||||
IntColVectorType m_p;
|
PermutationPType m_p;
|
||||||
IntRowVectorType m_q;
|
PermutationQType m_q;
|
||||||
int m_det_pq, m_nonzero_pivots;
|
int m_det_pq, m_nonzero_pivots;
|
||||||
RealScalar m_maxpivot, m_prescribedThreshold;
|
RealScalar m_maxpivot, m_prescribedThreshold;
|
||||||
bool m_isInitialized, m_usePrescribedThreshold;
|
bool m_isInitialized, m_usePrescribedThreshold;
|
||||||
@ -393,8 +390,6 @@ FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix)
|
|||||||
{
|
{
|
||||||
m_isInitialized = true;
|
m_isInitialized = true;
|
||||||
m_lu = matrix;
|
m_lu = matrix;
|
||||||
m_p.resize(matrix.rows());
|
|
||||||
m_q.resize(matrix.cols());
|
|
||||||
|
|
||||||
const int size = matrix.diagonalSize();
|
const int size = matrix.diagonalSize();
|
||||||
const int rows = matrix.rows();
|
const int rows = matrix.rows();
|
||||||
@ -408,6 +403,7 @@ FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix)
|
|||||||
|
|
||||||
m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
|
m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
|
||||||
m_maxpivot = RealScalar(0);
|
m_maxpivot = RealScalar(0);
|
||||||
|
|
||||||
for(int k = 0; k < size; ++k)
|
for(int k = 0; k < size; ++k)
|
||||||
{
|
{
|
||||||
// First, we need to find the pivot.
|
// First, we need to find the pivot.
|
||||||
@ -424,10 +420,10 @@ FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix)
|
|||||||
// if the pivot (hence the corner) is exactly zero, terminate to avoid generating nan/inf values
|
// if the pivot (hence the corner) is exactly zero, terminate to avoid generating nan/inf values
|
||||||
if(biggest_in_corner == RealScalar(0))
|
if(biggest_in_corner == RealScalar(0))
|
||||||
{
|
{
|
||||||
// before exiting, make sure to initialize the still uninitialized row_transpositions
|
// before exiting, make sure to initialize the still uninitialized transpositions
|
||||||
// in a sane state without destroying what we already have.
|
// in a sane state without destroying what we already have.
|
||||||
m_nonzero_pivots = k;
|
m_nonzero_pivots = k;
|
||||||
for(int i = k; i < size; i++)
|
for(int i = k; i < size; ++i)
|
||||||
{
|
{
|
||||||
rows_transpositions.coeffRef(i) = i;
|
rows_transpositions.coeffRef(i) = i;
|
||||||
cols_transpositions.coeffRef(i) = i;
|
cols_transpositions.coeffRef(i) = i;
|
||||||
@ -463,13 +459,13 @@ FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix)
|
|||||||
// the main loop is over, we still have to accumulate the transpositions to find the
|
// the main loop is over, we still have to accumulate the transpositions to find the
|
||||||
// permutations P and Q
|
// permutations P and Q
|
||||||
|
|
||||||
for(int k = 0; k < matrix.rows(); ++k) m_p.coeffRef(k) = k;
|
m_p.setIdentity(rows);
|
||||||
for(int k = size-1; k >= 0; --k)
|
for(int k = size-1; k >= 0; --k)
|
||||||
std::swap(m_p.coeffRef(k), m_p.coeffRef(rows_transpositions.coeff(k)));
|
m_p.applyTranspositionOnTheRight(k, rows_transpositions.coeff(k));
|
||||||
|
|
||||||
for(int k = 0; k < matrix.cols(); ++k) m_q.coeffRef(k) = k;
|
m_q.setIdentity(cols);
|
||||||
for(int k = 0; k < size; ++k)
|
for(int k = 0; k < size; ++k)
|
||||||
std::swap(m_q.coeffRef(k), m_q.coeffRef(cols_transpositions.coeff(k)));
|
m_q.applyTranspositionOnTheRight(k, cols_transpositions.coeff(k));
|
||||||
|
|
||||||
m_det_pq = (number_of_transpositions%2) ? -1 : 1;
|
m_det_pq = (number_of_transpositions%2) ? -1 : 1;
|
||||||
return *this;
|
return *this;
|
||||||
@ -562,9 +558,9 @@ struct ei_kernel_retval<FullPivLU<_MatrixType> >
|
|||||||
m.col(i).swap(m.col(pivots.coeff(i)));
|
m.col(i).swap(m.col(pivots.coeff(i)));
|
||||||
|
|
||||||
// see the negative sign in the next line, that's what we were talking about above.
|
// see the negative sign in the next line, that's what we were talking about above.
|
||||||
for(int i = 0; i < rank(); ++i) dst.row(dec().permutationQ().coeff(i)) = -m.row(i).end(dimker);
|
for(int i = 0; i < rank(); ++i) dst.row(dec().permutationQ().indices().coeff(i)) = -m.row(i).end(dimker);
|
||||||
for(int i = rank(); i < cols; ++i) dst.row(dec().permutationQ().coeff(i)).setZero();
|
for(int i = rank(); i < cols; ++i) dst.row(dec().permutationQ().indices().coeff(i)).setZero();
|
||||||
for(int k = 0; k < dimker; ++k) dst.coeffRef(dec().permutationQ().coeff(rank()+k), k) = Scalar(1);
|
for(int k = 0; k < dimker; ++k) dst.coeffRef(dec().permutationQ().indices().coeff(rank()+k), k) = Scalar(1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -601,7 +597,7 @@ struct ei_image_retval<FullPivLU<_MatrixType> >
|
|||||||
ei_internal_assert(p == rank());
|
ei_internal_assert(p == rank());
|
||||||
|
|
||||||
for(int i = 0; i < rank(); ++i)
|
for(int i = 0; i < rank(); ++i)
|
||||||
dst.col(i) = originalMatrix().col(dec().permutationQ().coeff(pivots.coeff(i)));
|
dst.col(i) = originalMatrix().col(dec().permutationQ().indices().coeff(pivots.coeff(i)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -623,7 +619,7 @@ struct ei_solve_retval<FullPivLU<_MatrixType>, Rhs>
|
|||||||
* Step 4: result = Q * c;
|
* Step 4: result = Q * c;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const int rows = dec().matrixLU().rows(), cols = dec().matrixLU().cols(),
|
const int rows = dec().rows(), cols = dec().cols(),
|
||||||
nonzero_pivots = dec().nonzeroPivots();
|
nonzero_pivots = dec().nonzeroPivots();
|
||||||
ei_assert(rhs().rows() == rows);
|
ei_assert(rhs().rows() == rows);
|
||||||
const int smalldim = std::min(rows, cols);
|
const int smalldim = std::min(rows, cols);
|
||||||
@ -637,8 +633,7 @@ struct ei_solve_retval<FullPivLU<_MatrixType>, Rhs>
|
|||||||
typename Rhs::PlainMatrixType c(rhs().rows(), rhs().cols());
|
typename Rhs::PlainMatrixType c(rhs().rows(), rhs().cols());
|
||||||
|
|
||||||
// Step 1
|
// Step 1
|
||||||
for(int i = 0; i < rows; ++i)
|
c = dec().permutationP() * rhs();
|
||||||
c.row(dec().permutationP().coeff(i)) = rhs().row(i);
|
|
||||||
|
|
||||||
// Step 2
|
// Step 2
|
||||||
dec().matrixLU()
|
dec().matrixLU()
|
||||||
@ -660,9 +655,9 @@ struct ei_solve_retval<FullPivLU<_MatrixType>, Rhs>
|
|||||||
|
|
||||||
// Step 4
|
// Step 4
|
||||||
for(int i = 0; i < nonzero_pivots; ++i)
|
for(int i = 0; i < nonzero_pivots; ++i)
|
||||||
dst.row(dec().permutationQ().coeff(i)) = c.row(i);
|
dst.row(dec().permutationQ().indices().coeff(i)) = c.row(i);
|
||||||
for(int i = nonzero_pivots; i < dec().matrixLU().cols(); ++i)
|
for(int i = nonzero_pivots; i < dec().matrixLU().cols(); ++i)
|
||||||
dst.row(dec().permutationQ().coeff(i)).setZero();
|
dst.row(dec().permutationQ().indices().coeff(i)).setZero();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -182,91 +182,37 @@ struct ei_compute_inverse_and_det_with_check<MatrixType, ResultType, 3>
|
|||||||
*** Size 4 implementation ***
|
*** Size 4 implementation ***
|
||||||
****************************/
|
****************************/
|
||||||
|
|
||||||
template<typename MatrixType, typename ResultType>
|
template<int Arch, typename Scalar, typename MatrixType, typename ResultType>
|
||||||
void ei_compute_inverse_size4_helper(const MatrixType& matrix, ResultType& result)
|
struct ei_compute_inverse_size4
|
||||||
{
|
{
|
||||||
/* Let's split M into four 2x2 blocks:
|
static void run(const MatrixType& matrix, ResultType& result)
|
||||||
* (P Q)
|
{
|
||||||
* (R S)
|
result.coeffRef(0,0) = matrix.minor(0,0).determinant();
|
||||||
* If P is invertible, with inverse denoted by P_inverse, and if
|
result.coeffRef(1,0) = -matrix.minor(0,1).determinant();
|
||||||
* (S - R*P_inverse*Q) is also invertible, then the inverse of M is
|
result.coeffRef(2,0) = matrix.minor(0,2).determinant();
|
||||||
* (P' Q')
|
result.coeffRef(3,0) = -matrix.minor(0,3).determinant();
|
||||||
* (R' S')
|
result.coeffRef(0,2) = matrix.minor(2,0).determinant();
|
||||||
* where
|
result.coeffRef(1,2) = -matrix.minor(2,1).determinant();
|
||||||
* S' = (S - R*P_inverse*Q)^(-1)
|
result.coeffRef(2,2) = matrix.minor(2,2).determinant();
|
||||||
* P' = P1 + (P1*Q) * S' *(R*P_inverse)
|
result.coeffRef(3,2) = -matrix.minor(2,3).determinant();
|
||||||
* Q' = -(P_inverse*Q) * S'
|
result.coeffRef(0,1) = -matrix.minor(1,0).determinant();
|
||||||
* R' = -S' * (R*P_inverse)
|
result.coeffRef(1,1) = matrix.minor(1,1).determinant();
|
||||||
*/
|
result.coeffRef(2,1) = -matrix.minor(1,2).determinant();
|
||||||
typedef Block<ResultType,2,2> XprBlock22;
|
result.coeffRef(3,1) = matrix.minor(1,3).determinant();
|
||||||
typedef typename MatrixBase<XprBlock22>::PlainMatrixType Block22;
|
result.coeffRef(0,3) = -matrix.minor(3,0).determinant();
|
||||||
Block22 P_inverse;
|
result.coeffRef(1,3) = matrix.minor(3,1).determinant();
|
||||||
ei_compute_inverse<XprBlock22, Block22>::run(matrix.template block<2,2>(0,0), P_inverse);
|
result.coeffRef(2,3) = -matrix.minor(3,2).determinant();
|
||||||
const Block22 Q = matrix.template block<2,2>(0,2);
|
result.coeffRef(3,3) = matrix.minor(3,3).determinant();
|
||||||
const Block22 P_inverse_times_Q = P_inverse * Q;
|
result /= (matrix.col(0).cwise()*result.row(0).transpose()).sum();
|
||||||
const XprBlock22 R = matrix.template block<2,2>(2,0);
|
}
|
||||||
const Block22 R_times_P_inverse = R * P_inverse;
|
};
|
||||||
const Block22 R_times_P_inverse_times_Q = R_times_P_inverse * Q;
|
|
||||||
const XprBlock22 S = matrix.template block<2,2>(2,2);
|
|
||||||
const Block22 X = S - R_times_P_inverse_times_Q;
|
|
||||||
Block22 Y;
|
|
||||||
ei_compute_inverse<Block22, Block22>::run(X, Y);
|
|
||||||
result.template block<2,2>(2,2) = Y;
|
|
||||||
result.template block<2,2>(2,0) = - Y * R_times_P_inverse;
|
|
||||||
const Block22 Z = P_inverse_times_Q * Y;
|
|
||||||
result.template block<2,2>(0,2) = - Z;
|
|
||||||
result.template block<2,2>(0,0) = P_inverse + Z * R_times_P_inverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename MatrixType, typename ResultType>
|
template<typename MatrixType, typename ResultType>
|
||||||
struct ei_compute_inverse<MatrixType, ResultType, 4>
|
struct ei_compute_inverse<MatrixType, ResultType, 4>
|
||||||
|
: ei_compute_inverse_size4<Architecture::Target, typename MatrixType::Scalar,
|
||||||
|
MatrixType, ResultType>
|
||||||
{
|
{
|
||||||
static inline void run(const MatrixType& _matrix, ResultType& result)
|
// FIXME empty?
|
||||||
{
|
|
||||||
typedef typename ResultType::Scalar Scalar;
|
|
||||||
typedef typename MatrixType::RealScalar RealScalar;
|
|
||||||
|
|
||||||
// we will do row permutations on the matrix. This copy should have negligible cost.
|
|
||||||
// if not, consider working in-place on the matrix (const-cast it, but then undo the permutations
|
|
||||||
// to nevertheless honor constness)
|
|
||||||
typename MatrixType::PlainMatrixType matrix(_matrix);
|
|
||||||
|
|
||||||
// let's extract from the 2 first colums a 2x2 block whose determinant is as big as possible.
|
|
||||||
int good_row0, good_row1, good_i;
|
|
||||||
Matrix<RealScalar,6,1> absdet;
|
|
||||||
|
|
||||||
// any 2x2 block with determinant above this threshold will be considered good enough
|
|
||||||
RealScalar d = (matrix.col(0).squaredNorm()+matrix.col(1).squaredNorm()) * RealScalar(1e-2);
|
|
||||||
#define ei_inv_size4_helper_macro(i,row0,row1) \
|
|
||||||
absdet[i] = ei_abs(matrix.coeff(row0,0)*matrix.coeff(row1,1) \
|
|
||||||
- matrix.coeff(row0,1)*matrix.coeff(row1,0)); \
|
|
||||||
if(absdet[i] > d) { good_row0=row0; good_row1=row1; goto good; }
|
|
||||||
ei_inv_size4_helper_macro(0,0,1)
|
|
||||||
ei_inv_size4_helper_macro(1,0,2)
|
|
||||||
ei_inv_size4_helper_macro(2,0,3)
|
|
||||||
ei_inv_size4_helper_macro(3,1,2)
|
|
||||||
ei_inv_size4_helper_macro(4,1,3)
|
|
||||||
ei_inv_size4_helper_macro(5,2,3)
|
|
||||||
|
|
||||||
// no 2x2 block has determinant bigger than the threshold. So just take the one that
|
|
||||||
// has the biggest determinant
|
|
||||||
absdet.maxCoeff(&good_i);
|
|
||||||
good_row0 = good_i <= 2 ? 0 : good_i <= 4 ? 1 : 2;
|
|
||||||
good_row1 = good_i <= 2 ? good_i+1 : good_i <= 4 ? good_i-1 : 3;
|
|
||||||
|
|
||||||
// now good_row0 and good_row1 are correctly set
|
|
||||||
good:
|
|
||||||
|
|
||||||
// do row permutations to move this 2x2 block to the top
|
|
||||||
matrix.row(0).swap(matrix.row(good_row0));
|
|
||||||
matrix.row(1).swap(matrix.row(good_row1));
|
|
||||||
// now applying our helper function is numerically stable
|
|
||||||
ei_compute_inverse_size4_helper(matrix, result);
|
|
||||||
// Since we did row permutations on the original matrix, we need to do column permutations
|
|
||||||
// in the reverse order on the inverse
|
|
||||||
result.col(1).swap(result.col(good_row1));
|
|
||||||
result.col(0).swap(result.col(good_row0));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename MatrixType, typename ResultType>
|
template<typename MatrixType, typename ResultType>
|
||||||
@ -300,7 +246,8 @@ template<typename MatrixType>
|
|||||||
struct ei_inverse_impl : public ReturnByValue<ei_inverse_impl<MatrixType> >
|
struct ei_inverse_impl : public ReturnByValue<ei_inverse_impl<MatrixType> >
|
||||||
{
|
{
|
||||||
// for 2x2, it's worth giving a chance to avoid evaluating.
|
// for 2x2, it's worth giving a chance to avoid evaluating.
|
||||||
// for larger sizes, evaluating has negligible cost and limits code size.
|
// for larger sizes, evaluating has negligible cost, limits code size,
|
||||||
|
// and allows for vectorized paths.
|
||||||
typedef typename ei_meta_if<
|
typedef typename ei_meta_if<
|
||||||
MatrixType::RowsAtCompileTime == 2,
|
MatrixType::RowsAtCompileTime == 2,
|
||||||
typename ei_nested<MatrixType,2>::type,
|
typename ei_nested<MatrixType,2>::type,
|
||||||
@ -326,7 +273,7 @@ struct ei_inverse_impl : public ReturnByValue<ei_inverse_impl<MatrixType> >
|
|||||||
*
|
*
|
||||||
* \returns the matrix inverse of this matrix.
|
* \returns the matrix inverse of this matrix.
|
||||||
*
|
*
|
||||||
* For small fixed sizes up to 4x4, this method uses ad-hoc methods (cofactors up to 3x3, Euler's trick for 4x4).
|
* For small fixed sizes up to 4x4, this method uses cofactors.
|
||||||
* In the general case, this method uses class PartialPivLU.
|
* In the general case, this method uses class PartialPivLU.
|
||||||
*
|
*
|
||||||
* \note This matrix must be invertible, otherwise the result is undefined. If you need an
|
* \note This matrix must be invertible, otherwise the result is undefined. If you need an
|
||||||
|
@ -64,10 +64,8 @@ template<typename _MatrixType> class PartialPivLU
|
|||||||
typedef _MatrixType MatrixType;
|
typedef _MatrixType MatrixType;
|
||||||
typedef typename MatrixType::Scalar Scalar;
|
typedef typename MatrixType::Scalar Scalar;
|
||||||
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
|
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
|
||||||
typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
|
typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> PermutationVectorType;
|
||||||
typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
|
typedef PermutationMatrix<MatrixType::RowsAtCompileTime> PermutationType;
|
||||||
typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;
|
|
||||||
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType;
|
|
||||||
|
|
||||||
enum { MaxSmallDimAtCompileTime = EIGEN_ENUM_MIN(
|
enum { MaxSmallDimAtCompileTime = EIGEN_ENUM_MIN(
|
||||||
MatrixType::MaxColsAtCompileTime,
|
MatrixType::MaxColsAtCompileTime,
|
||||||
@ -105,11 +103,9 @@ template<typename _MatrixType> class PartialPivLU
|
|||||||
return m_lu;
|
return m_lu;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns a vector of integers, whose size is the number of rows of the matrix being decomposed,
|
/** \returns the permutation matrix P.
|
||||||
* representing the P permutation i.e. the permutation of the rows. For its precise meaning,
|
|
||||||
* see the examples given in the documentation of class FullPivLU.
|
|
||||||
*/
|
*/
|
||||||
inline const IntColVectorType& permutationP() const
|
inline const PermutationType& permutationP() const
|
||||||
{
|
{
|
||||||
ei_assert(m_isInitialized && "PartialPivLU is not initialized.");
|
ei_assert(m_isInitialized && "PartialPivLU is not initialized.");
|
||||||
return m_p;
|
return m_p;
|
||||||
@ -147,11 +143,11 @@ template<typename _MatrixType> class PartialPivLU
|
|||||||
*
|
*
|
||||||
* \sa MatrixBase::inverse(), LU::inverse()
|
* \sa MatrixBase::inverse(), LU::inverse()
|
||||||
*/
|
*/
|
||||||
inline const ei_solve_retval<PartialPivLU,NestByValue<typename MatrixType::IdentityReturnType> > inverse() const
|
inline const ei_solve_retval<PartialPivLU,typename MatrixType::IdentityReturnType> inverse() const
|
||||||
{
|
{
|
||||||
ei_assert(m_isInitialized && "PartialPivLU is not initialized.");
|
ei_assert(m_isInitialized && "PartialPivLU is not initialized.");
|
||||||
return ei_solve_retval<PartialPivLU,NestByValue<typename MatrixType::IdentityReturnType> >
|
return ei_solve_retval<PartialPivLU,typename MatrixType::IdentityReturnType>
|
||||||
(*this, MatrixType::Identity(m_lu.rows(), m_lu.cols()).nestByValue());
|
(*this, MatrixType::Identity(m_lu.rows(), m_lu.cols()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the determinant of the matrix of which
|
/** \returns the determinant of the matrix of which
|
||||||
@ -174,7 +170,7 @@ template<typename _MatrixType> class PartialPivLU
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
MatrixType m_lu;
|
MatrixType m_lu;
|
||||||
IntColVectorType m_p;
|
PermutationType m_p;
|
||||||
int m_det_p;
|
int m_det_p;
|
||||||
bool m_isInitialized;
|
bool m_isInitialized;
|
||||||
};
|
};
|
||||||
@ -379,20 +375,19 @@ template<typename MatrixType>
|
|||||||
PartialPivLU<MatrixType>& PartialPivLU<MatrixType>::compute(const MatrixType& matrix)
|
PartialPivLU<MatrixType>& PartialPivLU<MatrixType>::compute(const MatrixType& matrix)
|
||||||
{
|
{
|
||||||
m_lu = matrix;
|
m_lu = matrix;
|
||||||
m_p.resize(matrix.rows());
|
|
||||||
|
|
||||||
ei_assert(matrix.rows() == matrix.cols() && "PartialPivLU is only for square (and moreover invertible) matrices");
|
ei_assert(matrix.rows() == matrix.cols() && "PartialPivLU is only for square (and moreover invertible) matrices");
|
||||||
const int size = matrix.rows();
|
const int size = matrix.rows();
|
||||||
|
|
||||||
IntColVectorType rows_transpositions(size);
|
PermutationVectorType rows_transpositions(size);
|
||||||
|
|
||||||
int nb_transpositions;
|
int nb_transpositions;
|
||||||
ei_partial_lu_inplace(m_lu, rows_transpositions, nb_transpositions);
|
ei_partial_lu_inplace(m_lu, rows_transpositions, nb_transpositions);
|
||||||
m_det_p = (nb_transpositions%2) ? -1 : 1;
|
m_det_p = (nb_transpositions%2) ? -1 : 1;
|
||||||
|
|
||||||
for(int k = 0; k < size; ++k) m_p.coeffRef(k) = k;
|
m_p.setIdentity(size);
|
||||||
for(int k = size-1; k >= 0; --k)
|
for(int k = size-1; k >= 0; --k)
|
||||||
std::swap(m_p.coeffRef(k), m_p.coeffRef(rows_transpositions.coeff(k)));
|
m_p.applyTranspositionOnTheRight(k, rows_transpositions.coeff(k));
|
||||||
|
|
||||||
m_isInitialized = true;
|
m_isInitialized = true;
|
||||||
return *this;
|
return *this;
|
||||||
@ -428,7 +423,7 @@ struct ei_solve_retval<PartialPivLU<_MatrixType>, Rhs>
|
|||||||
dst.resize(size, rhs().cols());
|
dst.resize(size, rhs().cols());
|
||||||
|
|
||||||
// Step 1
|
// Step 1
|
||||||
for(int i = 0; i < size; ++i) dst.row(dec().permutationP().coeff(i)) = rhs().row(i);
|
dst = dec().permutationP() * rhs();
|
||||||
|
|
||||||
// Step 2
|
// Step 2
|
||||||
dec().matrixLU().template triangularView<UnitLowerTriangular>().solveInPlace(dst);
|
dec().matrixLU().template triangularView<UnitLowerTriangular>().solveInPlace(dst);
|
||||||
|
6
Eigen/src/LU/arch/CMakeLists.txt
Normal file
6
Eigen/src/LU/arch/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
FILE(GLOB Eigen_LU_arch_SRCS "*.h")
|
||||||
|
|
||||||
|
INSTALL(FILES
|
||||||
|
${Eigen_LU_arch_SRCS}
|
||||||
|
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/LU/arch COMPONENT Devel
|
||||||
|
)
|
151
Eigen/src/LU/arch/Inverse_SSE.h
Normal file
151
Eigen/src/LU/arch/Inverse_SSE.h
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
|
// for linear algebra.
|
||||||
|
//
|
||||||
|
// Copyright (C) 1999 Intel Corporation
|
||||||
|
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
|
//
|
||||||
|
// Eigen is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// The SSE code for the 4x4 float matrix inverse in this file comes from the file
|
||||||
|
// ftp://download.intel.com/design/PentiumIII/sml/24504301.pdf
|
||||||
|
// See page ii of that document for legal stuff. Not being lawyers, we just assume
|
||||||
|
// here that if Intel makes this document publically available, with source code
|
||||||
|
// and detailed explanations, it's because they want their CPUs to be fed with
|
||||||
|
// good code, and therefore they presumably don't mind us using it in Eigen.
|
||||||
|
|
||||||
|
#ifndef EIGEN_INVERSE_SSE_H
|
||||||
|
#define EIGEN_INVERSE_SSE_H
|
||||||
|
|
||||||
|
template<typename MatrixType, typename ResultType>
|
||||||
|
struct ei_compute_inverse_size4<Architecture::SSE, float, MatrixType, ResultType>
|
||||||
|
{
|
||||||
|
static void run(const MatrixType& matrix, ResultType& result)
|
||||||
|
{
|
||||||
|
// Variables (Streaming SIMD Extensions registers) which will contain cofactors and, later, the
|
||||||
|
// lines of the inverted matrix.
|
||||||
|
__m128 minor0, minor1, minor2, minor3;
|
||||||
|
|
||||||
|
// Variables which will contain the lines of the reference matrix and, later (after the transposition),
|
||||||
|
// the columns of the original matrix.
|
||||||
|
__m128 row0, row1, row2, row3;
|
||||||
|
|
||||||
|
// Temporary variables and the variable that will contain the matrix determinant.
|
||||||
|
__m128 det, tmp1;
|
||||||
|
|
||||||
|
// Matrix transposition
|
||||||
|
const float *src = matrix.data();
|
||||||
|
tmp1 = _mm_loadh_pi(_mm_castpd_ps(_mm_load_sd((double*)src)), (__m64*)(src+ 4));
|
||||||
|
row1 = _mm_loadh_pi(_mm_castpd_ps(_mm_load_sd((double*)(src+8))), (__m64*)(src+12));
|
||||||
|
row0 = _mm_shuffle_ps(tmp1, row1, 0x88);
|
||||||
|
row1 = _mm_shuffle_ps(row1, tmp1, 0xDD);
|
||||||
|
tmp1 = _mm_loadh_pi(_mm_castpd_ps(_mm_load_sd((double*)(src+ 2))), (__m64*)(src+ 6));
|
||||||
|
row3 = _mm_loadh_pi(_mm_castpd_ps(_mm_load_sd((double*)(src+10))), (__m64*)(src+14));
|
||||||
|
row2 = _mm_shuffle_ps(tmp1, row3, 0x88);
|
||||||
|
row3 = _mm_shuffle_ps(row3, tmp1, 0xDD);
|
||||||
|
|
||||||
|
|
||||||
|
// Cofactors calculation. Because in the process of cofactor computation some pairs in three-
|
||||||
|
// element products are repeated, it is not reasonable to load these pairs anew every time. The
|
||||||
|
// values in the registers with these pairs are formed using shuffle instruction. Cofactors are
|
||||||
|
// calculated row by row (4 elements are placed in 1 SP FP SIMD floating point register).
|
||||||
|
|
||||||
|
tmp1 = _mm_mul_ps(row2, row3);
|
||||||
|
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
|
||||||
|
minor0 = _mm_mul_ps(row1, tmp1);
|
||||||
|
minor1 = _mm_mul_ps(row0, tmp1);
|
||||||
|
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
|
||||||
|
minor0 = _mm_sub_ps(_mm_mul_ps(row1, tmp1), minor0);
|
||||||
|
minor1 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor1);
|
||||||
|
minor1 = _mm_shuffle_ps(minor1, minor1, 0x4E);
|
||||||
|
// -----------------------------------------------
|
||||||
|
tmp1 = _mm_mul_ps(row1, row2);
|
||||||
|
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
|
||||||
|
minor0 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor0);
|
||||||
|
minor3 = _mm_mul_ps(row0, tmp1);
|
||||||
|
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
|
||||||
|
minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row3, tmp1));
|
||||||
|
minor3 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor3);
|
||||||
|
minor3 = _mm_shuffle_ps(minor3, minor3, 0x4E);
|
||||||
|
// -----------------------------------------------
|
||||||
|
tmp1 = _mm_mul_ps(_mm_shuffle_ps(row1, row1, 0x4E), row3);
|
||||||
|
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
|
||||||
|
row2 = _mm_shuffle_ps(row2, row2, 0x4E);
|
||||||
|
minor0 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor0);
|
||||||
|
minor2 = _mm_mul_ps(row0, tmp1);
|
||||||
|
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
|
||||||
|
minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row2, tmp1));
|
||||||
|
minor2 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor2);
|
||||||
|
minor2 = _mm_shuffle_ps(minor2, minor2, 0x4E);
|
||||||
|
// -----------------------------------------------
|
||||||
|
tmp1 = _mm_mul_ps(row0, row1);
|
||||||
|
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
|
||||||
|
minor2 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor2);
|
||||||
|
minor3 = _mm_sub_ps(_mm_mul_ps(row2, tmp1), minor3);
|
||||||
|
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
|
||||||
|
minor2 = _mm_sub_ps(_mm_mul_ps(row3, tmp1), minor2);
|
||||||
|
minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row2, tmp1));
|
||||||
|
// -----------------------------------------------
|
||||||
|
tmp1 = _mm_mul_ps(row0, row3);
|
||||||
|
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
|
||||||
|
minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row2, tmp1));
|
||||||
|
minor2 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor2);
|
||||||
|
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
|
||||||
|
minor1 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor1);
|
||||||
|
minor2 = _mm_sub_ps(minor2, _mm_mul_ps(row1, tmp1));
|
||||||
|
// -----------------------------------------------
|
||||||
|
tmp1 = _mm_mul_ps(row0, row2);
|
||||||
|
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
|
||||||
|
minor1 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor1);
|
||||||
|
minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row1, tmp1));
|
||||||
|
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
|
||||||
|
minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row3, tmp1));
|
||||||
|
minor3 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor3);
|
||||||
|
|
||||||
|
// Evaluation of determinant and its reciprocal value. In the original Intel document,
|
||||||
|
// 1/det was evaluated using a fast rcpps command with subsequent approximation using
|
||||||
|
// the Newton-Raphson algorithm. Here, we go for a IEEE-compliant division instead,
|
||||||
|
// so as to not compromise precision at all.
|
||||||
|
det = _mm_mul_ps(row0, minor0);
|
||||||
|
det = _mm_add_ps(_mm_shuffle_ps(det, det, 0x4E), det);
|
||||||
|
det = _mm_add_ss(_mm_shuffle_ps(det, det, 0xB1), det);
|
||||||
|
// tmp1= _mm_rcp_ss(det);
|
||||||
|
// det= _mm_sub_ss(_mm_add_ss(tmp1, tmp1), _mm_mul_ss(det, _mm_mul_ss(tmp1, tmp1)));
|
||||||
|
det = _mm_div_ss(_mm_set_ss(1.0f), det); // <--- yay, one original line not copied from Intel
|
||||||
|
det = _mm_shuffle_ps(det, det, 0x00);
|
||||||
|
// warning, Intel's variable naming is very confusing: now 'det' is 1/det !
|
||||||
|
|
||||||
|
// Multiplication of cofactors by 1/det. Storing the inverse matrix to the address in pointer src.
|
||||||
|
minor0 = _mm_mul_ps(det, minor0);
|
||||||
|
float *dst = result.data();
|
||||||
|
_mm_storel_pi((__m64*)(dst), minor0);
|
||||||
|
_mm_storeh_pi((__m64*)(dst+2), minor0);
|
||||||
|
minor1 = _mm_mul_ps(det, minor1);
|
||||||
|
_mm_storel_pi((__m64*)(dst+4), minor1);
|
||||||
|
_mm_storeh_pi((__m64*)(dst+6), minor1);
|
||||||
|
minor2 = _mm_mul_ps(det, minor2);
|
||||||
|
_mm_storel_pi((__m64*)(dst+ 8), minor2);
|
||||||
|
_mm_storeh_pi((__m64*)(dst+10), minor2);
|
||||||
|
minor3 = _mm_mul_ps(det, minor3);
|
||||||
|
_mm_storel_pi((__m64*)(dst+12), minor3);
|
||||||
|
_mm_storeh_pi((__m64*)(dst+14), minor3);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EIGEN_INVERSE_SSE_H
|
@ -57,10 +57,9 @@ template<typename _MatrixType> class ColPivHouseholderQR
|
|||||||
typedef typename MatrixType::RealScalar RealScalar;
|
typedef typename MatrixType::RealScalar RealScalar;
|
||||||
typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime> MatrixQType;
|
typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime> MatrixQType;
|
||||||
typedef Matrix<Scalar, DiagSizeAtCompileTime, 1> HCoeffsType;
|
typedef Matrix<Scalar, DiagSizeAtCompileTime, 1> HCoeffsType;
|
||||||
|
typedef PermutationMatrix<ColsAtCompileTime> PermutationType;
|
||||||
typedef Matrix<int, 1, ColsAtCompileTime> IntRowVectorType;
|
typedef Matrix<int, 1, ColsAtCompileTime> IntRowVectorType;
|
||||||
typedef Matrix<int, RowsAtCompileTime, 1> IntColVectorType;
|
|
||||||
typedef Matrix<Scalar, 1, ColsAtCompileTime> RowVectorType;
|
typedef Matrix<Scalar, 1, ColsAtCompileTime> RowVectorType;
|
||||||
typedef Matrix<Scalar, RowsAtCompileTime, 1> ColVectorType;
|
|
||||||
typedef Matrix<RealScalar, 1, ColsAtCompileTime> RealRowVectorType;
|
typedef Matrix<RealScalar, 1, ColsAtCompileTime> RealRowVectorType;
|
||||||
typedef typename HouseholderSequence<MatrixType,HCoeffsType>::ConjugateReturnType HouseholderSequenceType;
|
typedef typename HouseholderSequence<MatrixType,HCoeffsType>::ConjugateReturnType HouseholderSequenceType;
|
||||||
|
|
||||||
@ -75,7 +74,8 @@ 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_isInitialized(false)
|
m_isInitialized(false),
|
||||||
|
m_usePrescribedThreshold(false)
|
||||||
{
|
{
|
||||||
compute(matrix);
|
compute(matrix);
|
||||||
}
|
}
|
||||||
@ -105,7 +105,7 @@ template<typename _MatrixType> class ColPivHouseholderQR
|
|||||||
return ei_solve_retval<ColPivHouseholderQR, Rhs>(*this, b.derived());
|
return ei_solve_retval<ColPivHouseholderQR, Rhs>(*this, b.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
HouseholderSequenceType matrixQ(void) const;
|
HouseholderSequenceType householderQ(void) const;
|
||||||
|
|
||||||
/** \returns a reference to the matrix where the Householder QR decomposition is stored
|
/** \returns a reference to the matrix where the Householder QR decomposition is stored
|
||||||
*/
|
*/
|
||||||
@ -117,7 +117,7 @@ template<typename _MatrixType> class ColPivHouseholderQR
|
|||||||
|
|
||||||
ColPivHouseholderQR& compute(const MatrixType& matrix);
|
ColPivHouseholderQR& compute(const MatrixType& matrix);
|
||||||
|
|
||||||
const IntRowVectorType& colsPermutation() const
|
const PermutationType& colsPermutation() const
|
||||||
{
|
{
|
||||||
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
||||||
return m_cols_permutation;
|
return m_cols_permutation;
|
||||||
@ -154,54 +154,63 @@ template<typename _MatrixType> class ColPivHouseholderQR
|
|||||||
|
|
||||||
/** \returns the rank of the matrix of which *this is the QR decomposition.
|
/** \returns the rank of the matrix of which *this is the QR decomposition.
|
||||||
*
|
*
|
||||||
* \note This is computed at the time of the construction of the QR decomposition. This
|
* \note This method has to determine which pivots should be considered nonzero.
|
||||||
* method does not perform any further computation.
|
* For that, it uses the threshold value that you can control by calling
|
||||||
|
* setThreshold(const RealScalar&).
|
||||||
*/
|
*/
|
||||||
inline int rank() const
|
inline int rank() const
|
||||||
{
|
{
|
||||||
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
||||||
return m_rank;
|
RealScalar premultiplied_threshold = ei_abs(m_maxpivot) * threshold();
|
||||||
|
int result = 0;
|
||||||
|
for(int i = 0; i < m_nonzero_pivots; ++i)
|
||||||
|
result += (ei_abs(m_qr.coeff(i,i)) > premultiplied_threshold);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the dimension of the kernel of the matrix of which *this is the QR decomposition.
|
/** \returns the dimension of the kernel of the matrix of which *this is the QR decomposition.
|
||||||
*
|
*
|
||||||
* \note Since the rank is computed at the time of the construction of the QR decomposition, this
|
* \note This method has to determine which pivots should be considered nonzero.
|
||||||
* method almost does not perform any further computation.
|
* For that, it uses the threshold value that you can control by calling
|
||||||
|
* setThreshold(const RealScalar&).
|
||||||
*/
|
*/
|
||||||
inline int dimensionOfKernel() const
|
inline int dimensionOfKernel() const
|
||||||
{
|
{
|
||||||
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
||||||
return m_qr.cols() - m_rank;
|
return cols() - rank();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns true if the matrix of which *this is the QR decomposition represents an injective
|
/** \returns true if the matrix of which *this is the QR decomposition represents an injective
|
||||||
* linear map, i.e. has trivial kernel; false otherwise.
|
* linear map, i.e. has trivial kernel; false otherwise.
|
||||||
*
|
*
|
||||||
* \note Since the rank is computed at the time of the construction of the QR decomposition, this
|
* \note This method has to determine which pivots should be considered nonzero.
|
||||||
* method almost does not perform any further computation.
|
* For that, it uses the threshold value that you can control by calling
|
||||||
|
* setThreshold(const RealScalar&).
|
||||||
*/
|
*/
|
||||||
inline bool isInjective() const
|
inline bool isInjective() const
|
||||||
{
|
{
|
||||||
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
||||||
return m_rank == m_qr.cols();
|
return rank() == cols();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns true if the matrix of which *this is the QR decomposition represents a surjective
|
/** \returns true if the matrix of which *this is the QR decomposition represents a surjective
|
||||||
* linear map; false otherwise.
|
* linear map; false otherwise.
|
||||||
*
|
*
|
||||||
* \note Since the rank is computed at the time of the construction of the QR decomposition, this
|
* \note This method has to determine which pivots should be considered nonzero.
|
||||||
* method almost does not perform any further computation.
|
* For that, it uses the threshold value that you can control by calling
|
||||||
|
* setThreshold(const RealScalar&).
|
||||||
*/
|
*/
|
||||||
inline bool isSurjective() const
|
inline bool isSurjective() const
|
||||||
{
|
{
|
||||||
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
||||||
return m_rank == m_qr.rows();
|
return rank() == rows();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns true if the matrix of which *this is the QR decomposition is invertible.
|
/** \returns true if the matrix of which *this is the QR decomposition is invertible.
|
||||||
*
|
*
|
||||||
* \note Since the rank is computed at the time of the construction of the QR decomposition, this
|
* \note This method has to determine which pivots should be considered nonzero.
|
||||||
* method almost does not perform any further computation.
|
* For that, it uses the threshold value that you can control by calling
|
||||||
|
* setThreshold(const RealScalar&).
|
||||||
*/
|
*/
|
||||||
inline bool isInvertible() const
|
inline bool isInvertible() const
|
||||||
{
|
{
|
||||||
@ -215,25 +224,92 @@ template<typename _MatrixType> class ColPivHouseholderQR
|
|||||||
* Use isInvertible() to first determine whether this matrix is invertible.
|
* Use isInvertible() to first determine whether this matrix is invertible.
|
||||||
*/
|
*/
|
||||||
inline const
|
inline const
|
||||||
ei_solve_retval<ColPivHouseholderQR, NestByValue<typename MatrixType::IdentityReturnType> >
|
ei_solve_retval<ColPivHouseholderQR, typename MatrixType::IdentityReturnType>
|
||||||
inverse() const
|
inverse() const
|
||||||
{
|
{
|
||||||
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
||||||
return ei_solve_retval<ColPivHouseholderQR,NestByValue<typename MatrixType::IdentityReturnType> >
|
return ei_solve_retval<ColPivHouseholderQR,typename MatrixType::IdentityReturnType>
|
||||||
(*this, MatrixType::Identity(m_qr.rows(), m_qr.cols()).nestByValue());
|
(*this, MatrixType::Identity(m_qr.rows(), m_qr.cols()));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int rows() const { return m_qr.rows(); }
|
inline int rows() const { return m_qr.rows(); }
|
||||||
inline int cols() const { return m_qr.cols(); }
|
inline int cols() const { return m_qr.cols(); }
|
||||||
const HCoeffsType& hCoeffs() const { return m_hCoeffs; }
|
const HCoeffsType& hCoeffs() const { return m_hCoeffs; }
|
||||||
|
|
||||||
|
/** Allows to prescribe a threshold to be used by certain methods, such as rank(),
|
||||||
|
* who need to determine when pivots are to be considered nonzero. This is not used for the
|
||||||
|
* QR decomposition itself.
|
||||||
|
*
|
||||||
|
* When it needs to get the threshold value, Eigen calls threshold(). By default, this
|
||||||
|
* uses a formula to automatically determine a reasonable threshold.
|
||||||
|
* Once you have called the present method setThreshold(const RealScalar&),
|
||||||
|
* your value is used instead.
|
||||||
|
*
|
||||||
|
* \param threshold The new value to use as the threshold.
|
||||||
|
*
|
||||||
|
* A pivot will be considered nonzero if its absolute value is strictly greater than
|
||||||
|
* \f$ \vert pivot \vert \leqslant threshold \times \vert maxpivot \vert \f$
|
||||||
|
* where maxpivot is the biggest pivot.
|
||||||
|
*
|
||||||
|
* If you want to come back to the default behavior, call setThreshold(Default_t)
|
||||||
|
*/
|
||||||
|
ColPivHouseholderQR& setThreshold(const RealScalar& threshold)
|
||||||
|
{
|
||||||
|
m_usePrescribedThreshold = true;
|
||||||
|
m_prescribedThreshold = threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Allows to come back to the default behavior, letting Eigen use its default formula for
|
||||||
|
* determining the threshold.
|
||||||
|
*
|
||||||
|
* You should pass the special object Eigen::Default as parameter here.
|
||||||
|
* \code qr.setThreshold(Eigen::Default); \endcode
|
||||||
|
*
|
||||||
|
* See the documentation of setThreshold(const RealScalar&).
|
||||||
|
*/
|
||||||
|
ColPivHouseholderQR& setThreshold(Default_t)
|
||||||
|
{
|
||||||
|
m_usePrescribedThreshold = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the threshold that will be used by certain methods such as rank().
|
||||||
|
*
|
||||||
|
* See the documentation of setThreshold(const RealScalar&).
|
||||||
|
*/
|
||||||
|
RealScalar threshold() const
|
||||||
|
{
|
||||||
|
ei_assert(m_isInitialized || m_usePrescribedThreshold);
|
||||||
|
return m_usePrescribedThreshold ? m_prescribedThreshold
|
||||||
|
// this formula comes from experimenting (see "LU precision tuning" thread on the list)
|
||||||
|
// and turns out to be identical to Higham's formula used already in LDLt.
|
||||||
|
: epsilon<Scalar>() * m_qr.diagonalSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \returns the number of nonzero pivots in the QR decomposition.
|
||||||
|
* Here nonzero is meant in the exact sense, not in a fuzzy sense.
|
||||||
|
* So that notion isn't really intrinsically interesting, but it is
|
||||||
|
* still useful when implementing algorithms.
|
||||||
|
*
|
||||||
|
* \sa rank()
|
||||||
|
*/
|
||||||
|
inline int nonzeroPivots() const
|
||||||
|
{
|
||||||
|
ei_assert(m_isInitialized && "LU is not initialized.");
|
||||||
|
return m_nonzero_pivots;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \returns the absolute value of the biggest pivot, i.e. the biggest
|
||||||
|
* diagonal coefficient of U.
|
||||||
|
*/
|
||||||
|
RealScalar maxPivot() const { return m_maxpivot; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MatrixType m_qr;
|
MatrixType m_qr;
|
||||||
HCoeffsType m_hCoeffs;
|
HCoeffsType m_hCoeffs;
|
||||||
IntRowVectorType m_cols_permutation;
|
PermutationType m_cols_permutation;
|
||||||
bool m_isInitialized;
|
bool m_isInitialized, m_usePrescribedThreshold;
|
||||||
RealScalar m_precision;
|
RealScalar m_prescribedThreshold, m_maxpivot;
|
||||||
int m_rank;
|
int m_nonzero_pivots;
|
||||||
int m_det_pq;
|
int m_det_pq;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -260,63 +336,85 @@ ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const
|
|||||||
{
|
{
|
||||||
int rows = matrix.rows();
|
int rows = matrix.rows();
|
||||||
int cols = matrix.cols();
|
int cols = matrix.cols();
|
||||||
int size = std::min(rows,cols);
|
int size = matrix.diagonalSize();
|
||||||
m_rank = size;
|
|
||||||
|
|
||||||
m_qr = matrix;
|
m_qr = matrix;
|
||||||
m_hCoeffs.resize(size);
|
m_hCoeffs.resize(size);
|
||||||
|
|
||||||
RowVectorType temp(cols);
|
RowVectorType temp(cols);
|
||||||
|
|
||||||
m_precision = epsilon<Scalar>() * size;
|
|
||||||
|
|
||||||
IntRowVectorType cols_transpositions(matrix.cols());
|
IntRowVectorType cols_transpositions(matrix.cols());
|
||||||
m_cols_permutation.resize(matrix.cols());
|
|
||||||
int number_of_transpositions = 0;
|
int number_of_transpositions = 0;
|
||||||
|
|
||||||
RealRowVectorType colSqNorms(cols);
|
RealRowVectorType colSqNorms(cols);
|
||||||
for(int k = 0; k < cols; ++k)
|
for(int k = 0; k < cols; ++k)
|
||||||
colSqNorms.coeffRef(k) = m_qr.col(k).squaredNorm();
|
colSqNorms.coeffRef(k) = m_qr.col(k).squaredNorm();
|
||||||
RealScalar biggestColSqNorm = colSqNorms.maxCoeff();
|
|
||||||
|
|
||||||
for (int k = 0; k < size; ++k)
|
RealScalar threshold_helper = colSqNorms.maxCoeff() * ei_abs2(epsilon<Scalar>()) / rows;
|
||||||
{
|
|
||||||
int biggest_col_in_corner;
|
|
||||||
RealScalar biggestColSqNormInCorner = colSqNorms.end(cols-k).maxCoeff(&biggest_col_in_corner);
|
|
||||||
biggest_col_in_corner += k;
|
|
||||||
|
|
||||||
// if the corner is negligible, then we have less than full rank, and we can finish early
|
m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
|
||||||
if(ei_isMuchSmallerThan(biggestColSqNormInCorner, biggestColSqNorm, m_precision))
|
m_maxpivot = RealScalar(0);
|
||||||
|
|
||||||
|
for(int k = 0; k < size; ++k)
|
||||||
{
|
{
|
||||||
m_rank = k;
|
// first, we look up in our table colSqNorms which column has the biggest squared norm
|
||||||
for(int i = k; i < size; i++)
|
int biggest_col_index;
|
||||||
|
RealScalar biggest_col_sq_norm = colSqNorms.end(cols-k).maxCoeff(&biggest_col_index);
|
||||||
|
biggest_col_index += k;
|
||||||
|
|
||||||
|
// since our table colSqNorms accumulates imprecision at every step, we must now recompute
|
||||||
|
// the actual squared norm of the selected column.
|
||||||
|
// Note that not doing so does result in solve() sometimes returning inf/nan values
|
||||||
|
// when running the unit test with 1000 repetitions.
|
||||||
|
biggest_col_sq_norm = m_qr.col(biggest_col_index).end(rows-k).squaredNorm();
|
||||||
|
|
||||||
|
// we store that back into our table: it can't hurt to correct our table.
|
||||||
|
colSqNorms.coeffRef(biggest_col_index) = biggest_col_sq_norm;
|
||||||
|
|
||||||
|
// if the current biggest column is smaller than epsilon times the initial biggest column,
|
||||||
|
// terminate to avoid generating nan/inf values.
|
||||||
|
// Note that here, if we test instead for "biggest == 0", we get a failure every 1000 (or so)
|
||||||
|
// repetitions of the unit test, with the result of solve() filled with large values of the order
|
||||||
|
// of 1/(size*epsilon).
|
||||||
|
if(biggest_col_sq_norm < threshold_helper * (rows-k))
|
||||||
{
|
{
|
||||||
cols_transpositions.coeffRef(i) = i;
|
m_nonzero_pivots = k;
|
||||||
m_hCoeffs.coeffRef(i) = Scalar(0);
|
m_hCoeffs.end(size-k).setZero();
|
||||||
}
|
m_qr.corner(BottomRight,rows-k,cols-k)
|
||||||
|
.template triangularView<StrictlyLowerTriangular>()
|
||||||
|
.setZero();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
cols_transpositions.coeffRef(k) = biggest_col_in_corner;
|
// apply the transposition to the columns
|
||||||
if(k != biggest_col_in_corner) {
|
cols_transpositions.coeffRef(k) = biggest_col_index;
|
||||||
m_qr.col(k).swap(m_qr.col(biggest_col_in_corner));
|
if(k != biggest_col_index) {
|
||||||
std::swap(colSqNorms.coeffRef(k), colSqNorms.coeffRef(biggest_col_in_corner));
|
m_qr.col(k).swap(m_qr.col(biggest_col_index));
|
||||||
|
std::swap(colSqNorms.coeffRef(k), colSqNorms.coeffRef(biggest_col_index));
|
||||||
++number_of_transpositions;
|
++number_of_transpositions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// generate the householder vector, store it below the diagonal
|
||||||
RealScalar beta;
|
RealScalar beta;
|
||||||
m_qr.col(k).end(rows-k).makeHouseholderInPlace(m_hCoeffs.coeffRef(k), beta);
|
m_qr.col(k).end(rows-k).makeHouseholderInPlace(m_hCoeffs.coeffRef(k), beta);
|
||||||
|
|
||||||
|
// apply the householder transformation to the diagonal coefficient
|
||||||
m_qr.coeffRef(k,k) = beta;
|
m_qr.coeffRef(k,k) = beta;
|
||||||
|
|
||||||
|
// remember the maximum absolute value of diagonal coefficients
|
||||||
|
if(ei_abs(beta) > m_maxpivot) m_maxpivot = ei_abs(beta);
|
||||||
|
|
||||||
|
// apply the householder transformation
|
||||||
m_qr.corner(BottomRight, rows-k, cols-k-1)
|
m_qr.corner(BottomRight, rows-k, cols-k-1)
|
||||||
.applyHouseholderOnTheLeft(m_qr.col(k).end(rows-k-1), m_hCoeffs.coeffRef(k), &temp.coeffRef(k+1));
|
.applyHouseholderOnTheLeft(m_qr.col(k).end(rows-k-1), m_hCoeffs.coeffRef(k), &temp.coeffRef(k+1));
|
||||||
|
|
||||||
|
// update our table of squared norms of the columns
|
||||||
colSqNorms.end(cols-k-1) -= m_qr.row(k).end(cols-k-1).cwiseAbs2();
|
colSqNorms.end(cols-k-1) -= m_qr.row(k).end(cols-k-1).cwiseAbs2();
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int k = 0; k < matrix.cols(); ++k) m_cols_permutation.coeffRef(k) = k;
|
m_cols_permutation.setIdentity(cols);
|
||||||
for(int k = 0; k < size; ++k)
|
for(int k = 0; k < m_nonzero_pivots; ++k)
|
||||||
std::swap(m_cols_permutation.coeffRef(k), m_cols_permutation.coeffRef(cols_transpositions.coeff(k)));
|
m_cols_permutation.applyTranspositionOnTheRight(k, cols_transpositions.coeff(k));
|
||||||
|
|
||||||
m_det_pq = (number_of_transpositions%2) ? -1 : 1;
|
m_det_pq = (number_of_transpositions%2) ? -1 : 1;
|
||||||
m_isInitialized = true;
|
m_isInitialized = true;
|
||||||
@ -332,13 +430,12 @@ struct ei_solve_retval<ColPivHouseholderQR<_MatrixType>, Rhs>
|
|||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
template<typename Dest> void evalTo(Dest& dst) const
|
||||||
{
|
{
|
||||||
const int rows = dec().rows(), cols = dec().cols();
|
const int rows = dec().rows(), cols = dec().cols(),
|
||||||
|
nonzero_pivots = dec().nonzeroPivots();
|
||||||
dst.resize(cols, rhs().cols());
|
dst.resize(cols, rhs().cols());
|
||||||
ei_assert(rhs().rows() == rows);
|
ei_assert(rhs().rows() == rows);
|
||||||
|
|
||||||
// FIXME introduce nonzeroPivots() and use it here. and more generally,
|
if(nonzero_pivots == 0)
|
||||||
// make the same improvements in this dec as in FullPivLU.
|
|
||||||
if(dec().rank()==0)
|
|
||||||
{
|
{
|
||||||
dst.setZero();
|
dst.setZero();
|
||||||
return;
|
return;
|
||||||
@ -348,37 +445,37 @@ struct ei_solve_retval<ColPivHouseholderQR<_MatrixType>, Rhs>
|
|||||||
|
|
||||||
// Note that the matrix Q = H_0^* H_1^*... so its inverse is Q^* = (H_0 H_1 ...)^T
|
// Note that the matrix Q = H_0^* H_1^*... so its inverse is Q^* = (H_0 H_1 ...)^T
|
||||||
c.applyOnTheLeft(householderSequence(
|
c.applyOnTheLeft(householderSequence(
|
||||||
dec().matrixQR().corner(TopLeft,rows,dec().rank()),
|
dec().matrixQR(),
|
||||||
dec().hCoeffs().start(dec().rank())).transpose()
|
dec().hCoeffs(),
|
||||||
);
|
true,
|
||||||
|
dec().nonzeroPivots()
|
||||||
if(!dec().isSurjective())
|
));
|
||||||
{
|
|
||||||
// is c is in the image of R ?
|
|
||||||
RealScalar biggest_in_upper_part_of_c = c.corner(TopLeft, dec().rank(), c.cols()).cwiseAbs().maxCoeff();
|
|
||||||
RealScalar biggest_in_lower_part_of_c = c.corner(BottomLeft, rows-dec().rank(), c.cols()).cwiseAbs().maxCoeff();
|
|
||||||
// FIXME brain dead
|
|
||||||
const RealScalar m_precision = epsilon<Scalar>() * std::min(rows,cols);
|
|
||||||
if(!ei_isMuchSmallerThan(biggest_in_lower_part_of_c, biggest_in_upper_part_of_c, m_precision*4))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dec().matrixQR()
|
dec().matrixQR()
|
||||||
.corner(TopLeft, dec().rank(), dec().rank())
|
.corner(TopLeft, nonzero_pivots, nonzero_pivots)
|
||||||
.template triangularView<UpperTriangular>()
|
.template triangularView<UpperTriangular>()
|
||||||
.solveInPlace(c.corner(TopLeft, dec().rank(), c.cols()));
|
.solveInPlace(c.corner(TopLeft, nonzero_pivots, c.cols()));
|
||||||
|
|
||||||
for(int i = 0; i < dec().rank(); ++i) dst.row(dec().colsPermutation().coeff(i)) = c.row(i);
|
|
||||||
for(int i = dec().rank(); i < cols; ++i) dst.row(dec().colsPermutation().coeff(i)).setZero();
|
typename Rhs::PlainMatrixType d(c);
|
||||||
|
d.corner(TopLeft, nonzero_pivots, c.cols())
|
||||||
|
= dec().matrixQR()
|
||||||
|
.corner(TopLeft, nonzero_pivots, nonzero_pivots)
|
||||||
|
.template triangularView<UpperTriangular>()
|
||||||
|
* c.corner(TopLeft, nonzero_pivots, c.cols());
|
||||||
|
|
||||||
|
for(int i = 0; i < nonzero_pivots; ++i) dst.row(dec().colsPermutation().indices().coeff(i)) = c.row(i);
|
||||||
|
for(int i = nonzero_pivots; i < cols; ++i) dst.row(dec().colsPermutation().indices().coeff(i)).setZero();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \returns the matrix Q as a sequence of householder transformations */
|
/** \returns the matrix Q as a sequence of householder transformations */
|
||||||
template<typename MatrixType>
|
template<typename MatrixType>
|
||||||
typename ColPivHouseholderQR<MatrixType>::HouseholderSequenceType ColPivHouseholderQR<MatrixType>::matrixQ() const
|
typename ColPivHouseholderQR<MatrixType>::HouseholderSequenceType ColPivHouseholderQR<MatrixType>
|
||||||
|
::householderQ() const
|
||||||
{
|
{
|
||||||
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
||||||
return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate());
|
return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate(), false, m_nonzero_pivots);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // EIGEN_HIDE_HEAVY_CODE
|
#endif // EIGEN_HIDE_HEAVY_CODE
|
||||||
|
@ -58,6 +58,7 @@ template<typename _MatrixType> class FullPivHouseholderQR
|
|||||||
typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime> MatrixQType;
|
typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime> MatrixQType;
|
||||||
typedef Matrix<Scalar, DiagSizeAtCompileTime, 1> HCoeffsType;
|
typedef Matrix<Scalar, DiagSizeAtCompileTime, 1> HCoeffsType;
|
||||||
typedef Matrix<int, 1, ColsAtCompileTime> IntRowVectorType;
|
typedef Matrix<int, 1, ColsAtCompileTime> IntRowVectorType;
|
||||||
|
typedef PermutationMatrix<ColsAtCompileTime> PermutationType;
|
||||||
typedef Matrix<int, RowsAtCompileTime, 1> IntColVectorType;
|
typedef Matrix<int, RowsAtCompileTime, 1> IntColVectorType;
|
||||||
typedef Matrix<Scalar, 1, ColsAtCompileTime> RowVectorType;
|
typedef Matrix<Scalar, 1, ColsAtCompileTime> RowVectorType;
|
||||||
typedef Matrix<Scalar, RowsAtCompileTime, 1> ColVectorType;
|
typedef Matrix<Scalar, RowsAtCompileTime, 1> ColVectorType;
|
||||||
@ -112,7 +113,7 @@ template<typename _MatrixType> class FullPivHouseholderQR
|
|||||||
|
|
||||||
FullPivHouseholderQR& compute(const MatrixType& matrix);
|
FullPivHouseholderQR& compute(const MatrixType& matrix);
|
||||||
|
|
||||||
const IntRowVectorType& colsPermutation() const
|
const PermutationType& colsPermutation() const
|
||||||
{
|
{
|
||||||
ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
|
ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
|
||||||
return m_cols_permutation;
|
return m_cols_permutation;
|
||||||
@ -215,12 +216,12 @@ template<typename _MatrixType> class FullPivHouseholderQR
|
|||||||
* \note If this matrix is not invertible, the returned matrix has undefined coefficients.
|
* \note If this matrix is not invertible, the returned matrix has undefined coefficients.
|
||||||
* Use isInvertible() to first determine whether this matrix is invertible.
|
* Use isInvertible() to first determine whether this matrix is invertible.
|
||||||
*/ inline const
|
*/ inline const
|
||||||
ei_solve_retval<FullPivHouseholderQR, NestByValue<typename MatrixType::IdentityReturnType> >
|
ei_solve_retval<FullPivHouseholderQR, typename MatrixType::IdentityReturnType>
|
||||||
inverse() const
|
inverse() const
|
||||||
{
|
{
|
||||||
ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
|
ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
|
||||||
return ei_solve_retval<FullPivHouseholderQR,NestByValue<typename MatrixType::IdentityReturnType> >
|
return ei_solve_retval<FullPivHouseholderQR,typename MatrixType::IdentityReturnType>
|
||||||
(*this, MatrixType::Identity(m_qr.rows(), m_qr.cols()).nestByValue());
|
(*this, MatrixType::Identity(m_qr.rows(), m_qr.cols()));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int rows() const { return m_qr.rows(); }
|
inline int rows() const { return m_qr.rows(); }
|
||||||
@ -231,7 +232,7 @@ template<typename _MatrixType> class FullPivHouseholderQR
|
|||||||
MatrixType m_qr;
|
MatrixType m_qr;
|
||||||
HCoeffsType m_hCoeffs;
|
HCoeffsType m_hCoeffs;
|
||||||
IntColVectorType m_rows_transpositions;
|
IntColVectorType m_rows_transpositions;
|
||||||
IntRowVectorType m_cols_permutation;
|
PermutationType m_cols_permutation;
|
||||||
bool m_isInitialized;
|
bool m_isInitialized;
|
||||||
RealScalar m_precision;
|
RealScalar m_precision;
|
||||||
int m_rank;
|
int m_rank;
|
||||||
@ -273,7 +274,6 @@ FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(cons
|
|||||||
|
|
||||||
m_rows_transpositions.resize(matrix.rows());
|
m_rows_transpositions.resize(matrix.rows());
|
||||||
IntRowVectorType cols_transpositions(matrix.cols());
|
IntRowVectorType cols_transpositions(matrix.cols());
|
||||||
m_cols_permutation.resize(matrix.cols());
|
|
||||||
int number_of_transpositions = 0;
|
int number_of_transpositions = 0;
|
||||||
|
|
||||||
RealScalar biggest(0);
|
RealScalar biggest(0);
|
||||||
@ -322,9 +322,9 @@ FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(cons
|
|||||||
.applyHouseholderOnTheLeft(m_qr.col(k).end(rows-k-1), m_hCoeffs.coeffRef(k), &temp.coeffRef(k+1));
|
.applyHouseholderOnTheLeft(m_qr.col(k).end(rows-k-1), m_hCoeffs.coeffRef(k), &temp.coeffRef(k+1));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int k = 0; k < matrix.cols(); ++k) m_cols_permutation.coeffRef(k) = k;
|
m_cols_permutation.setIdentity(cols);
|
||||||
for(int k = 0; k < size; ++k)
|
for(int k = 0; k < size; ++k)
|
||||||
std::swap(m_cols_permutation.coeffRef(k), m_cols_permutation.coeffRef(cols_transpositions.coeff(k)));
|
m_cols_permutation.applyTranspositionOnTheRight(k, cols_transpositions.coeff(k));
|
||||||
|
|
||||||
m_det_pq = (number_of_transpositions%2) ? -1 : 1;
|
m_det_pq = (number_of_transpositions%2) ? -1 : 1;
|
||||||
m_isInitialized = true;
|
m_isInitialized = true;
|
||||||
@ -379,8 +379,8 @@ struct ei_solve_retval<FullPivHouseholderQR<_MatrixType>, Rhs>
|
|||||||
.template triangularView<UpperTriangular>()
|
.template triangularView<UpperTriangular>()
|
||||||
.solveInPlace(c.corner(TopLeft, dec().rank(), c.cols()));
|
.solveInPlace(c.corner(TopLeft, dec().rank(), c.cols()));
|
||||||
|
|
||||||
for(int i = 0; i < dec().rank(); ++i) dst.row(dec().colsPermutation().coeff(i)) = c.row(i);
|
for(int i = 0; i < dec().rank(); ++i) dst.row(dec().colsPermutation().indices().coeff(i)) = c.row(i);
|
||||||
for(int i = dec().rank(); i < cols; ++i) dst.row(dec().colsPermutation().coeff(i)).setZero();
|
for(int i = dec().rank(); i < cols; ++i) dst.row(dec().colsPermutation().indices().coeff(i)).setZero();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -105,10 +105,9 @@ template<typename _MatrixType> class HouseholderQR
|
|||||||
return ei_solve_retval<HouseholderQR, Rhs>(*this, b.derived());
|
return ei_solve_retval<HouseholderQR, Rhs>(*this, b.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
MatrixQType matrixQ() const;
|
HouseholderSequenceType householderQ() const
|
||||||
|
|
||||||
HouseholderSequenceType matrixQAsHouseholderSequence() const
|
|
||||||
{
|
{
|
||||||
|
ei_assert(m_isInitialized && "HouseholderQR is not initialized.");
|
||||||
return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate());
|
return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,14 +239,6 @@ struct ei_solve_retval<HouseholderQR<_MatrixType>, Rhs>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \returns the matrix Q */
|
|
||||||
template<typename MatrixType>
|
|
||||||
typename HouseholderQR<MatrixType>::MatrixQType HouseholderQR<MatrixType>::matrixQ() const
|
|
||||||
{
|
|
||||||
ei_assert(m_isInitialized && "HouseholderQR is not initialized.");
|
|
||||||
return matrixQAsHouseholderSequence();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // EIGEN_HIDE_HEAVY_CODE
|
#endif // EIGEN_HIDE_HEAVY_CODE
|
||||||
|
|
||||||
/** \return the Householder QR decomposition of \c *this.
|
/** \return the Householder QR decomposition of \c *this.
|
||||||
|
@ -236,9 +236,8 @@ struct ei_svd_precondition_if_more_rows_than_cols<MatrixType, Options, true>
|
|||||||
FullPivHouseholderQR<MatrixType> qr(matrix);
|
FullPivHouseholderQR<MatrixType> qr(matrix);
|
||||||
work_matrix = qr.matrixQR().block(0,0,diagSize,diagSize).template triangularView<UpperTriangular>();
|
work_matrix = qr.matrixQR().block(0,0,diagSize,diagSize).template triangularView<UpperTriangular>();
|
||||||
if(ComputeU) svd.m_matrixU = qr.matrixQ();
|
if(ComputeU) svd.m_matrixU = qr.matrixQ();
|
||||||
if(ComputeV)
|
if(ComputeV) svd.m_matrixV = qr.colsPermutation();
|
||||||
for(int i = 0; i < cols; i++)
|
|
||||||
svd.m_matrixV.coeffRef(qr.colsPermutation().coeff(i),i) = Scalar(1);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else return false;
|
else return false;
|
||||||
@ -281,9 +280,7 @@ struct ei_svd_precondition_if_more_cols_than_rows<MatrixType, Options, true>
|
|||||||
FullPivHouseholderQR<TransposeTypeWithSameStorageOrder> qr(matrix.adjoint());
|
FullPivHouseholderQR<TransposeTypeWithSameStorageOrder> qr(matrix.adjoint());
|
||||||
work_matrix = qr.matrixQR().block(0,0,diagSize,diagSize).template triangularView<UpperTriangular>().adjoint();
|
work_matrix = qr.matrixQR().block(0,0,diagSize,diagSize).template triangularView<UpperTriangular>().adjoint();
|
||||||
if(ComputeV) svd.m_matrixV = qr.matrixQ();
|
if(ComputeV) svd.m_matrixV = qr.matrixQ();
|
||||||
if(ComputeU)
|
if(ComputeU) svd.m_matrixU = qr.colsPermutation();
|
||||||
for(int i = 0; i < rows; i++)
|
|
||||||
svd.m_matrixU.coeffRef(qr.colsPermutation().coeff(i),i) = Scalar(1);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else return false;
|
else return false;
|
||||||
@ -297,8 +294,6 @@ JacobiSVD<MatrixType, Options>& JacobiSVD<MatrixType, Options>::compute(const Ma
|
|||||||
int rows = matrix.rows();
|
int rows = matrix.rows();
|
||||||
int cols = matrix.cols();
|
int cols = matrix.cols();
|
||||||
int diagSize = std::min(rows, cols);
|
int diagSize = std::min(rows, cols);
|
||||||
if(ComputeU) m_matrixU = MatrixUType::Zero(rows,rows);
|
|
||||||
if(ComputeV) m_matrixV = MatrixVType::Zero(cols,cols);
|
|
||||||
m_singularValues.resize(diagSize);
|
m_singularValues.resize(diagSize);
|
||||||
const RealScalar precision = 2 * epsilon<Scalar>();
|
const RealScalar precision = 2 * epsilon<Scalar>();
|
||||||
|
|
||||||
@ -306,8 +301,8 @@ JacobiSVD<MatrixType, Options>& JacobiSVD<MatrixType, Options>::compute(const Ma
|
|||||||
&& !ei_svd_precondition_if_more_cols_than_rows<MatrixType, Options>::run(matrix, work_matrix, *this))
|
&& !ei_svd_precondition_if_more_cols_than_rows<MatrixType, Options>::run(matrix, work_matrix, *this))
|
||||||
{
|
{
|
||||||
work_matrix = matrix.block(0,0,diagSize,diagSize);
|
work_matrix = matrix.block(0,0,diagSize,diagSize);
|
||||||
if(ComputeU) m_matrixU.diagonal().setOnes();
|
if(ComputeU) m_matrixU.setIdentity(rows,rows);
|
||||||
if(ComputeV) m_matrixV.diagonal().setOnes();
|
if(ComputeV) m_matrixV.setIdentity(cols,cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool finished = false;
|
bool finished = false;
|
||||||
|
@ -190,11 +190,10 @@ SVD<MatrixType>& SVD<MatrixType>::compute(const MatrixType& matrix)
|
|||||||
SingularValuesType& W = m_sigma;
|
SingularValuesType& W = m_sigma;
|
||||||
|
|
||||||
bool flag;
|
bool flag;
|
||||||
int i,its,j,k,nm;
|
int i=0,its=0,j=0,k=0,l=0,nm=0;
|
||||||
int l=0;
|
|
||||||
Scalar anorm, c, f, g, h, s, scale, x, y, z;
|
Scalar anorm, c, f, g, h, s, scale, x, y, z;
|
||||||
bool convergence = true;
|
bool convergence = true;
|
||||||
Scalar eps = precision<Scalar>();
|
Scalar eps = dummy_precision<Scalar>();
|
||||||
|
|
||||||
Matrix<Scalar,Dynamic,1> rv1(n);
|
Matrix<Scalar,Dynamic,1> rv1(n);
|
||||||
g = scale = anorm = 0;
|
g = scale = anorm = 0;
|
||||||
|
@ -126,10 +126,6 @@ template<typename _Scalar> class AmbiVector
|
|||||||
int m_llStart;
|
int m_llStart;
|
||||||
int m_llCurrent;
|
int m_llCurrent;
|
||||||
int m_llSize;
|
int m_llSize;
|
||||||
|
|
||||||
private:
|
|
||||||
AmbiVector(const AmbiVector&);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \returns the number of non zeros in the current sub vector */
|
/** \returns the number of non zeros in the current sub vector */
|
||||||
@ -300,7 +296,7 @@ class AmbiVector<_Scalar>::Iterator
|
|||||||
* In practice, all coefficients having a magnitude smaller than \a epsilon
|
* In practice, all coefficients having a magnitude smaller than \a epsilon
|
||||||
* are skipped.
|
* are skipped.
|
||||||
*/
|
*/
|
||||||
Iterator(const AmbiVector& vec, RealScalar epsilon = RealScalar(0.1)*precision<RealScalar>())
|
Iterator(const AmbiVector& vec, RealScalar epsilon = RealScalar(0.1)*dummy_precision<RealScalar>())
|
||||||
: m_vector(vec)
|
: m_vector(vec)
|
||||||
{
|
{
|
||||||
m_epsilon = epsilon;
|
m_epsilon = epsilon;
|
||||||
|
@ -93,7 +93,7 @@ class CompressedStorage
|
|||||||
|
|
||||||
void append(const Scalar& v, int i)
|
void append(const Scalar& v, int i)
|
||||||
{
|
{
|
||||||
int id = m_size;
|
int id = static_cast<int>(m_size);
|
||||||
resize(m_size+1, 1);
|
resize(m_size+1, 1);
|
||||||
m_values[id] = v;
|
m_values[id] = v;
|
||||||
m_indices[id] = i;
|
m_indices[id] = i;
|
||||||
@ -135,7 +135,7 @@ class CompressedStorage
|
|||||||
else
|
else
|
||||||
end = mid;
|
end = mid;
|
||||||
}
|
}
|
||||||
return start;
|
return static_cast<int>(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the stored value at index \a key
|
/** \returns the stored value at index \a key
|
||||||
@ -185,7 +185,7 @@ class CompressedStorage
|
|||||||
return m_values[id];
|
return m_values[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
void prune(Scalar reference, RealScalar epsilon = precision<RealScalar>())
|
void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar>())
|
||||||
{
|
{
|
||||||
size_t k = 0;
|
size_t k = 0;
|
||||||
size_t n = size();
|
size_t n = size();
|
||||||
|
@ -58,6 +58,13 @@ struct ei_traits<DynamicSparseMatrix<_Scalar, _Flags> >
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename _Scalar, int _Options>
|
||||||
|
struct ei_ref_selector< DynamicSparseMatrix<_Scalar, _Options> >
|
||||||
|
{
|
||||||
|
typedef DynamicSparseMatrix<_Scalar, _Options> MatrixType;
|
||||||
|
typedef MatrixType const& type;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename _Scalar, int _Flags>
|
template<typename _Scalar, int _Flags>
|
||||||
class DynamicSparseMatrix
|
class DynamicSparseMatrix
|
||||||
: public SparseMatrixBase<DynamicSparseMatrix<_Scalar, _Flags> >
|
: public SparseMatrixBase<DynamicSparseMatrix<_Scalar, _Flags> >
|
||||||
@ -82,7 +89,7 @@ class DynamicSparseMatrix
|
|||||||
inline int rows() const { return IsRowMajor ? outerSize() : m_innerSize; }
|
inline int rows() const { return IsRowMajor ? outerSize() : m_innerSize; }
|
||||||
inline int cols() const { return IsRowMajor ? m_innerSize : outerSize(); }
|
inline int cols() const { return IsRowMajor ? m_innerSize : outerSize(); }
|
||||||
inline int innerSize() const { return m_innerSize; }
|
inline int innerSize() const { return m_innerSize; }
|
||||||
inline int outerSize() const { return m_data.size(); }
|
inline int outerSize() const { return static_cast<int>(m_data.size()); }
|
||||||
inline int innerNonZeros(int j) const { return m_data[j].size(); }
|
inline int innerNonZeros(int j) const { return m_data[j].size(); }
|
||||||
|
|
||||||
std::vector<CompressedStorage<Scalar> >& _data() { return m_data; }
|
std::vector<CompressedStorage<Scalar> >& _data() { return m_data; }
|
||||||
@ -122,7 +129,7 @@ class DynamicSparseMatrix
|
|||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
for (int j=0; j<outerSize(); ++j)
|
for (int j=0; j<outerSize(); ++j)
|
||||||
res += m_data[j].size();
|
res += static_cast<int>(m_data[j].size());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +196,7 @@ class DynamicSparseMatrix
|
|||||||
const int inner = IsRowMajor ? col : row;
|
const int inner = IsRowMajor ? col : row;
|
||||||
|
|
||||||
int startId = 0;
|
int startId = 0;
|
||||||
int id = m_data[outer].size() - 1;
|
int id = static_cast<int>(m_data[outer].size()) - 1;
|
||||||
m_data[outer].resize(id+2,1);
|
m_data[outer].resize(id+2,1);
|
||||||
|
|
||||||
while ( (id >= startId) && (m_data[outer].index(id) > inner) )
|
while ( (id >= startId) && (m_data[outer].index(id) > inner) )
|
||||||
@ -209,7 +216,7 @@ class DynamicSparseMatrix
|
|||||||
|
|
||||||
inline void finalize() {}
|
inline void finalize() {}
|
||||||
|
|
||||||
void prune(Scalar reference, RealScalar epsilon = precision<RealScalar>())
|
void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar>())
|
||||||
{
|
{
|
||||||
for (int j=0; j<outerSize(); ++j)
|
for (int j=0; j<outerSize(); ++j)
|
||||||
m_data[j].prune(reference,epsilon);
|
m_data[j].prune(reference,epsilon);
|
||||||
@ -314,7 +321,6 @@ class DynamicSparseMatrix<Scalar,_Flags>::InnerIterator : public SparseVector<Sc
|
|||||||
inline int row() const { return IsRowMajor ? m_outer : Base::index(); }
|
inline int row() const { return IsRowMajor ? m_outer : Base::index(); }
|
||||||
inline int col() const { return IsRowMajor ? Base::index() : m_outer; }
|
inline int col() const { return IsRowMajor ? Base::index() : m_outer; }
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const int m_outer;
|
const int m_outer;
|
||||||
};
|
};
|
||||||
|
@ -322,7 +322,7 @@ class RandomSetter
|
|||||||
{
|
{
|
||||||
int nz = 0;
|
int nz = 0;
|
||||||
for (int k=0; k<m_outerPackets; ++k)
|
for (int k=0; k<m_outerPackets; ++k)
|
||||||
nz += m_hashmaps[k].size();
|
nz += static_cast<int>(m_hashmaps[k].size());
|
||||||
return nz;
|
return nz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,8 +86,7 @@ class SparseDiagonalProduct
|
|||||||
typedef ei_sparse_diagonal_product_inner_iterator_selector
|
typedef ei_sparse_diagonal_product_inner_iterator_selector
|
||||||
<_LhsNested,_RhsNested,SparseDiagonalProduct,LhsMode,RhsMode> InnerIterator;
|
<_LhsNested,_RhsNested,SparseDiagonalProduct,LhsMode,RhsMode> InnerIterator;
|
||||||
|
|
||||||
template<typename _Lhs, typename _Rhs>
|
EIGEN_STRONG_INLINE SparseDiagonalProduct(const Lhs& lhs, const Rhs& rhs)
|
||||||
EIGEN_STRONG_INLINE SparseDiagonalProduct(const _Lhs& lhs, const _Rhs& rhs)
|
|
||||||
: m_lhs(lhs), m_rhs(rhs)
|
: m_lhs(lhs), m_rhs(rhs)
|
||||||
{
|
{
|
||||||
ei_assert(lhs.cols() == rhs.rows() && "invalid sparse matrix * diagonal matrix product");
|
ei_assert(lhs.cols() == rhs.rows() && "invalid sparse matrix * diagonal matrix product");
|
||||||
@ -156,16 +155,16 @@ class ei_sparse_diagonal_product_inner_iterator_selector
|
|||||||
: public CwiseBinaryOp<
|
: public CwiseBinaryOp<
|
||||||
ei_scalar_product_op<typename Rhs::Scalar>,
|
ei_scalar_product_op<typename Rhs::Scalar>,
|
||||||
SparseInnerVectorSet<Lhs,1>,
|
SparseInnerVectorSet<Lhs,1>,
|
||||||
NestByValue<Transpose<typename Rhs::DiagonalVectorType> > >::InnerIterator
|
Transpose<typename Rhs::DiagonalVectorType> >::InnerIterator
|
||||||
{
|
{
|
||||||
typedef typename CwiseBinaryOp<
|
typedef typename CwiseBinaryOp<
|
||||||
ei_scalar_product_op<typename Rhs::Scalar>,
|
ei_scalar_product_op<typename Rhs::Scalar>,
|
||||||
SparseInnerVectorSet<Lhs,1>,
|
SparseInnerVectorSet<Lhs,1>,
|
||||||
NestByValue<Transpose<typename Rhs::DiagonalVectorType> > >::InnerIterator Base;
|
Transpose<typename Rhs::DiagonalVectorType> >::InnerIterator Base;
|
||||||
public:
|
public:
|
||||||
inline ei_sparse_diagonal_product_inner_iterator_selector(
|
inline ei_sparse_diagonal_product_inner_iterator_selector(
|
||||||
const SparseDiagonalProductType& expr, int outer)
|
const SparseDiagonalProductType& expr, int outer)
|
||||||
: Base(expr.lhs().innerVector(outer) .cwiseProduct(expr.rhs().diagonal().transpose().nestByValue()), 0)
|
: Base(expr.lhs().innerVector(outer) .cwiseProduct(expr.rhs().diagonal().transpose()), 0)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
42
Eigen/src/Sparse/SparseExpressionMaker.h
Normal file
42
Eigen/src/Sparse/SparseExpressionMaker.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
|
// for linear algebra.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr>
|
||||||
|
//
|
||||||
|
// Eigen is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Alternatively, you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License and a copy of the GNU General Public License along with
|
||||||
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef EIGEN_SPARSE_EXPRESSIONMAKER_H
|
||||||
|
#define EIGEN_SPARSE_EXPRESSIONMAKER_H
|
||||||
|
|
||||||
|
template<typename Func, typename XprType>
|
||||||
|
struct MakeCwiseUnaryOp<Func,XprType,IsSparse>
|
||||||
|
{
|
||||||
|
typedef SparseCwiseUnaryOp<Func,XprType> Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Func, typename A, typename B>
|
||||||
|
struct MakeCwiseBinaryOp<Func,A,B,IsSparse>
|
||||||
|
{
|
||||||
|
typedef SparseCwiseBinaryOp<Func,A,B> Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO complete the list
|
||||||
|
|
||||||
|
#endif // EIGEN_SPARSE_EXPRESSIONMAKER_H
|
@ -94,7 +94,7 @@ class SparseLDLT
|
|||||||
: m_flags(flags), m_status(0)
|
: m_flags(flags), m_status(0)
|
||||||
{
|
{
|
||||||
ei_assert((MatrixType::Flags&RowMajorBit)==0);
|
ei_assert((MatrixType::Flags&RowMajorBit)==0);
|
||||||
m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
|
m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates a LDLT object and compute the respective factorization of \a matrix using
|
/** Creates a LDLT object and compute the respective factorization of \a matrix using
|
||||||
@ -103,7 +103,7 @@ class SparseLDLT
|
|||||||
: m_matrix(matrix.rows(), matrix.cols()), m_flags(flags), m_status(0)
|
: m_matrix(matrix.rows(), matrix.cols()), m_flags(flags), m_status(0)
|
||||||
{
|
{
|
||||||
ei_assert((MatrixType::Flags&RowMajorBit)==0);
|
ei_assert((MatrixType::Flags&RowMajorBit)==0);
|
||||||
m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
|
m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar>();
|
||||||
compute(matrix);
|
compute(matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ class SparseLLT
|
|||||||
SparseLLT(int flags = 0)
|
SparseLLT(int flags = 0)
|
||||||
: m_flags(flags), m_status(0)
|
: m_flags(flags), m_status(0)
|
||||||
{
|
{
|
||||||
m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
|
m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates a LLT object and compute the respective factorization of \a matrix using
|
/** Creates a LLT object and compute the respective factorization of \a matrix using
|
||||||
@ -62,7 +62,7 @@ class SparseLLT
|
|||||||
SparseLLT(const MatrixType& matrix, int flags = 0)
|
SparseLLT(const MatrixType& matrix, int flags = 0)
|
||||||
: m_matrix(matrix.rows(), matrix.cols()), m_flags(flags), m_status(0)
|
: m_matrix(matrix.rows(), matrix.cols()), m_flags(flags), m_status(0)
|
||||||
{
|
{
|
||||||
m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
|
m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar>();
|
||||||
compute(matrix);
|
compute(matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ class SparseLU
|
|||||||
SparseLU(int flags = 0)
|
SparseLU(int flags = 0)
|
||||||
: m_flags(flags), m_status(0)
|
: m_flags(flags), m_status(0)
|
||||||
{
|
{
|
||||||
m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
|
m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates a LU object and compute the respective factorization of \a matrix using
|
/** Creates a LU object and compute the respective factorization of \a matrix using
|
||||||
@ -67,7 +67,7 @@ class SparseLU
|
|||||||
SparseLU(const MatrixType& matrix, int flags = 0)
|
SparseLU(const MatrixType& matrix, int flags = 0)
|
||||||
: /*m_matrix(matrix.rows(), matrix.cols()),*/ m_flags(flags), m_status(0)
|
: /*m_matrix(matrix.rows(), matrix.cols()),*/ m_flags(flags), m_status(0)
|
||||||
{
|
{
|
||||||
m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
|
m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar>();
|
||||||
compute(matrix);
|
compute(matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +57,13 @@ struct ei_traits<SparseMatrix<_Scalar, _Options> >
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename _Scalar, int _Options>
|
||||||
|
struct ei_ref_selector<SparseMatrix<_Scalar, _Options> >
|
||||||
|
{
|
||||||
|
typedef SparseMatrix<_Scalar, _Options> MatrixType;
|
||||||
|
typedef MatrixType const& type;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename _Scalar, int _Options>
|
template<typename _Scalar, int _Options>
|
||||||
class SparseMatrix
|
class SparseMatrix
|
||||||
: public SparseMatrixBase<SparseMatrix<_Scalar, _Options> >
|
: public SparseMatrixBase<SparseMatrix<_Scalar, _Options> >
|
||||||
@ -132,7 +139,7 @@ class SparseMatrix
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the number of non zero coefficients */
|
/** \returns the number of non zero coefficients */
|
||||||
inline int nonZeros() const { return m_data.size(); }
|
inline int nonZeros() const { return static_cast<int>(m_data.size()); }
|
||||||
|
|
||||||
/** \deprecated use setZero() and reserve()
|
/** \deprecated use setZero() and reserve()
|
||||||
* Initializes the filling process of \c *this.
|
* Initializes the filling process of \c *this.
|
||||||
@ -230,7 +237,7 @@ class SparseMatrix
|
|||||||
// we start a new inner vector
|
// we start a new inner vector
|
||||||
while (previousOuter>=0 && m_outerIndex[previousOuter]==0)
|
while (previousOuter>=0 && m_outerIndex[previousOuter]==0)
|
||||||
{
|
{
|
||||||
m_outerIndex[previousOuter] = m_data.size();
|
m_outerIndex[previousOuter] = static_cast<int>(m_data.size());
|
||||||
--previousOuter;
|
--previousOuter;
|
||||||
}
|
}
|
||||||
m_outerIndex[outer+1] = m_outerIndex[outer];
|
m_outerIndex[outer+1] = m_outerIndex[outer];
|
||||||
@ -329,7 +336,7 @@ class SparseMatrix
|
|||||||
*/
|
*/
|
||||||
inline void finalize()
|
inline void finalize()
|
||||||
{
|
{
|
||||||
int size = m_data.size();
|
int size = static_cast<int>(m_data.size());
|
||||||
int i = m_outerSize;
|
int i = m_outerSize;
|
||||||
// find the last filled column
|
// find the last filled column
|
||||||
while (i>=0 && m_outerIndex[i]==0)
|
while (i>=0 && m_outerIndex[i]==0)
|
||||||
@ -342,7 +349,7 @@ class SparseMatrix
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void prune(Scalar reference, RealScalar epsilon = precision<RealScalar>())
|
void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar>())
|
||||||
{
|
{
|
||||||
int k = 0;
|
int k = 0;
|
||||||
for (int j=0; j<m_outerSize; ++j)
|
for (int j=0; j<m_outerSize; ++j)
|
||||||
|
@ -105,7 +105,7 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived
|
|||||||
// typedef SparseCwiseUnaryOp<ei_scalar_imag_op<Scalar>, Derived> ImagReturnType;
|
// typedef SparseCwiseUnaryOp<ei_scalar_imag_op<Scalar>, Derived> ImagReturnType;
|
||||||
/** \internal the return type of MatrixBase::adjoint() */
|
/** \internal the return type of MatrixBase::adjoint() */
|
||||||
typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
|
typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
|
||||||
CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, SparseNestByValue<Eigen::Transpose<Derived> > >,
|
CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::Transpose<Derived> >,
|
||||||
Transpose<Derived>
|
Transpose<Derived>
|
||||||
>::ret AdjointReturnType;
|
>::ret AdjointReturnType;
|
||||||
|
|
||||||
@ -399,7 +399,7 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived
|
|||||||
Transpose<Derived> transpose() { return derived(); }
|
Transpose<Derived> transpose() { return derived(); }
|
||||||
const Transpose<Derived> transpose() const { return derived(); }
|
const Transpose<Derived> transpose() const { return derived(); }
|
||||||
// void transposeInPlace();
|
// void transposeInPlace();
|
||||||
const AdjointReturnType adjoint() const { return transpose().nestByValue(); }
|
const AdjointReturnType adjoint() const { return transpose(); }
|
||||||
|
|
||||||
// sub-vector
|
// sub-vector
|
||||||
SparseInnerVectorSet<Derived,1> row(int i);
|
SparseInnerVectorSet<Derived,1> row(int i);
|
||||||
@ -510,32 +510,32 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived
|
|||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
bool isApprox(const SparseMatrixBase<OtherDerived>& other,
|
bool isApprox(const SparseMatrixBase<OtherDerived>& other,
|
||||||
RealScalar prec = precision<Scalar>()) const
|
RealScalar prec = dummy_precision<Scalar>()) const
|
||||||
{ return toDense().isApprox(other.toDense(),prec); }
|
{ return toDense().isApprox(other.toDense(),prec); }
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
bool isApprox(const MatrixBase<OtherDerived>& other,
|
bool isApprox(const MatrixBase<OtherDerived>& other,
|
||||||
RealScalar prec = precision<Scalar>()) const
|
RealScalar prec = dummy_precision<Scalar>()) const
|
||||||
{ return toDense().isApprox(other,prec); }
|
{ return toDense().isApprox(other,prec); }
|
||||||
// bool isMuchSmallerThan(const RealScalar& other,
|
// bool isMuchSmallerThan(const RealScalar& other,
|
||||||
// RealScalar prec = precision<Scalar>()) const;
|
// RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
// template<typename OtherDerived>
|
// template<typename OtherDerived>
|
||||||
// bool isMuchSmallerThan(const MatrixBase<OtherDerived>& other,
|
// bool isMuchSmallerThan(const MatrixBase<OtherDerived>& other,
|
||||||
// RealScalar prec = precision<Scalar>()) const;
|
// RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
|
|
||||||
// bool isApproxToConstant(const Scalar& value, RealScalar prec = precision<Scalar>()) const;
|
// bool isApproxToConstant(const Scalar& value, RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
// bool isZero(RealScalar prec = precision<Scalar>()) const;
|
// bool isZero(RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
// bool isOnes(RealScalar prec = precision<Scalar>()) const;
|
// bool isOnes(RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
// bool isIdentity(RealScalar prec = precision<Scalar>()) const;
|
// bool isIdentity(RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
// bool isDiagonal(RealScalar prec = precision<Scalar>()) const;
|
// bool isDiagonal(RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
|
|
||||||
// bool isUpperTriangular(RealScalar prec = precision<Scalar>()) const;
|
// bool isUpperTriangular(RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
// bool isLowerTriangular(RealScalar prec = precision<Scalar>()) const;
|
// bool isLowerTriangular(RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
|
|
||||||
// template<typename OtherDerived>
|
// template<typename OtherDerived>
|
||||||
// bool isOrthogonal(const MatrixBase<OtherDerived>& other,
|
// bool isOrthogonal(const MatrixBase<OtherDerived>& other,
|
||||||
// RealScalar prec = precision<Scalar>()) const;
|
// RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
// bool isUnitary(RealScalar prec = precision<Scalar>()) const;
|
// bool isUnitary(RealScalar prec = dummy_precision<Scalar>()) const;
|
||||||
|
|
||||||
// template<typename OtherDerived>
|
// template<typename OtherDerived>
|
||||||
// inline bool operator==(const MatrixBase<OtherDerived>& other) const
|
// inline bool operator==(const MatrixBase<OtherDerived>& other) const
|
||||||
@ -571,9 +571,7 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived
|
|||||||
*/
|
*/
|
||||||
// inline int stride(void) const { return derived().stride(); }
|
// inline int stride(void) const { return derived().stride(); }
|
||||||
|
|
||||||
inline const SparseNestByValue<Derived> nestByValue() const;
|
// FIXME
|
||||||
|
|
||||||
|
|
||||||
// ConjugateReturnType conjugate() const;
|
// ConjugateReturnType conjugate() const;
|
||||||
// const RealReturnType real() const;
|
// const RealReturnType real() const;
|
||||||
// const ImagReturnType imag() const;
|
// const ImagReturnType imag() const;
|
||||||
@ -626,11 +624,11 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived
|
|||||||
const MatrixBase<ElseDerived>& elseMatrix) const;
|
const MatrixBase<ElseDerived>& elseMatrix) const;
|
||||||
|
|
||||||
template<typename ThenDerived>
|
template<typename ThenDerived>
|
||||||
inline const Select<Derived,ThenDerived, NestByValue<typename ThenDerived::ConstantReturnType> >
|
inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
|
||||||
select(const MatrixBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const;
|
select(const MatrixBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const;
|
||||||
|
|
||||||
template<typename ElseDerived>
|
template<typename ElseDerived>
|
||||||
inline const Select<Derived, NestByValue<typename ElseDerived::ConstantReturnType>, ElseDerived >
|
inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
|
||||||
select(typename ElseDerived::Scalar thenScalar, const MatrixBase<ElseDerived>& elseMatrix) const;
|
select(typename ElseDerived::Scalar thenScalar, const MatrixBase<ElseDerived>& elseMatrix) const;
|
||||||
|
|
||||||
template<int p> RealScalar lpNorm() const;
|
template<int p> RealScalar lpNorm() const;
|
||||||
|
@ -1,84 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>
|
|
||||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
|
||||||
//
|
|
||||||
// Eigen is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
|
||||||
// License as published by the Free Software Foundation; either
|
|
||||||
// version 3 of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Alternatively, you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public
|
|
||||||
// License and a copy of the GNU General Public License along with
|
|
||||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#ifndef EIGEN_SPARSENESTBYVALUE_H
|
|
||||||
#define EIGEN_SPARSENESTBYVALUE_H
|
|
||||||
|
|
||||||
/** \class SparseNestByValue
|
|
||||||
*
|
|
||||||
* \brief Expression which must be nested by value
|
|
||||||
*
|
|
||||||
* \param ExpressionType the type of the object of which we are requiring nesting-by-value
|
|
||||||
*
|
|
||||||
* This class is the return type of MatrixBase::nestByValue()
|
|
||||||
* and most of the time this is the only way it is used.
|
|
||||||
*
|
|
||||||
* \sa SparseMatrixBase::nestByValue(), class NestByValue
|
|
||||||
*/
|
|
||||||
template<typename ExpressionType>
|
|
||||||
struct ei_traits<SparseNestByValue<ExpressionType> > : public ei_traits<ExpressionType>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<typename ExpressionType> class SparseNestByValue
|
|
||||||
: public SparseMatrixBase<SparseNestByValue<ExpressionType> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef typename ExpressionType::InnerIterator InnerIterator;
|
|
||||||
|
|
||||||
EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseNestByValue)
|
|
||||||
|
|
||||||
inline SparseNestByValue(const ExpressionType& matrix) : m_expression(matrix) {}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE int rows() const { return m_expression.rows(); }
|
|
||||||
EIGEN_STRONG_INLINE int cols() const { return m_expression.cols(); }
|
|
||||||
|
|
||||||
operator const ExpressionType&() const { return m_expression; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const ExpressionType m_expression;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \returns an expression of the temporary version of *this.
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
inline const SparseNestByValue<Derived>
|
|
||||||
SparseMatrixBase<Derived>::nestByValue() const
|
|
||||||
{
|
|
||||||
return SparseNestByValue<Derived>(derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
// template<typename MatrixType>
|
|
||||||
// class SparseNestByValue<MatrixType>::InnerIterator : public MatrixType::InnerIterator
|
|
||||||
// {
|
|
||||||
// typedef typename MatrixType::InnerIterator Base;
|
|
||||||
// public:
|
|
||||||
//
|
|
||||||
// EIGEN_STRONG_INLINE InnerIterator(const SparseNestByValue& expr, int outer)
|
|
||||||
// : Base(expr.m_expression, outer)
|
|
||||||
// {}
|
|
||||||
// };
|
|
||||||
|
|
||||||
#endif // EIGEN_SPARSENESTBYVALUE_H
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user