mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Compare commits
59 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06773276cd | ||
|
|
c8271df0ec | ||
|
|
9e84d135db | ||
|
|
8d2f7ae94b | ||
|
|
a1a0cccd4e | ||
|
|
45e1bb5ea5 | ||
|
|
d0c374f1ed | ||
|
|
f231560ec2 | ||
|
|
cea814b90d | ||
|
|
15b1558483 | ||
|
|
bfe9b35152 | ||
|
|
6d4f7f76ce | ||
|
|
b4c4490587 | ||
|
|
6af80a23a5 | ||
|
|
f1f70ceb84 | ||
|
|
ea1ac035ce | ||
|
|
360a79d6f8 | ||
|
|
057254381d | ||
|
|
cafd34fa91 | ||
|
|
deeffdb245 | ||
|
|
10295de37b | ||
|
|
c31b70fcfd | ||
|
|
b55585a93d | ||
|
|
ae32b89b12 | ||
|
|
0007cc3dd7 | ||
|
|
2bde6013c9 | ||
|
|
7b9d54ba58 | ||
|
|
457e4b2493 | ||
|
|
f54cc2284e | ||
|
|
503cf43556 | ||
|
|
b9e2b4f6f5 | ||
|
|
2c2b7f4173 | ||
|
|
fd52daae87 | ||
|
|
61ad84fd4d | ||
|
|
0fa2b394ce | ||
|
|
bc0fc5d21e | ||
|
|
45bcad41b4 | ||
|
|
28bbc4bf47 | ||
|
|
05f45cfecd | ||
|
|
01e13a273e | ||
|
|
5437ab95fd | ||
|
|
a45de92246 | ||
|
|
1d68e47a23 | ||
|
|
41b0fd733f | ||
|
|
228920fad7 | ||
|
|
dcb36e3d49 | ||
|
|
11a31f2eba | ||
|
|
874d4e9f30 | ||
|
|
99d8e5de2b | ||
|
|
a52ab9c089 | ||
|
|
9ed342a30e | ||
|
|
0ef41ec958 | ||
|
|
7438c2d3ce | ||
|
|
7764885d04 | ||
|
|
6021b5c467 | ||
|
|
1ab1f7b125 | ||
|
|
411b4a1b1d | ||
|
|
8f7fb19907 | ||
|
|
074755a27c |
@@ -283,11 +283,17 @@ if(EIGEN_BUILD_PKGCONFIG)
|
||||
STRING(REPLACE ${path_separator} ";" pkg_config_libdir_search "$ENV{PKG_CONFIG_LIBDIR}")
|
||||
message(STATUS "searching for 'pkgconfig' directory in PKG_CONFIG_LIBDIR ( $ENV{PKG_CONFIG_LIBDIR} ), ${CMAKE_INSTALL_PREFIX}/share, and ${CMAKE_INSTALL_PREFIX}/lib")
|
||||
FIND_PATH(pkg_config_libdir pkgconfig ${pkg_config_libdir_search} ${CMAKE_INSTALL_PREFIX}/share ${CMAKE_INSTALL_PREFIX}/lib ${pkg_config_libdir_search})
|
||||
message(STATUS "found ${pkg_config_libdir}/pkgconfig" )
|
||||
if(pkg_config_libdir)
|
||||
SET(pkg_config_install_dir ${pkg_config_libdir})
|
||||
message(STATUS "found ${pkg_config_libdir}/pkgconfig" )
|
||||
else(pkg_config_libdir)
|
||||
SET(pkg_config_install_dir ${CMAKE_INSTALL_PREFIX}/share)
|
||||
message(STATUS "pkgconfig not found; installing in ${pkg_config_install_dir}" )
|
||||
endif(pkg_config_libdir)
|
||||
|
||||
configure_file(eigen3.pc.in eigen3.pc)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/eigen3.pc
|
||||
DESTINATION ${pkg_config_libdir}/pkgconfig
|
||||
DESTINATION ${pkg_config_install_dir}/pkgconfig
|
||||
)
|
||||
endif(EIGEN_BUILD_PKGCONFIG)
|
||||
|
||||
|
||||
@@ -8,6 +8,6 @@ set(CTEST_PROJECT_NAME "Eigen")
|
||||
set(CTEST_NIGHTLY_START_TIME "00:00:00 UTC")
|
||||
|
||||
set(CTEST_DROP_METHOD "http")
|
||||
set(CTEST_DROP_SITE "eigen.tuxfamily.org")
|
||||
set(CTEST_DROP_SITE "manao.inria.fr")
|
||||
set(CTEST_DROP_LOCATION "/CDash/submit.php?project=Eigen")
|
||||
set(CTEST_DROP_SITE_CDASH TRUE)
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
#endif
|
||||
|
||||
// MSVC for windows mobile does not have the errno.h file
|
||||
#if !(defined(_MSC_VER) && defined(_WIN32_WCE))
|
||||
#if !(defined(_MSC_VER) && defined(_WIN32_WCE)) && !defined(__ARMCC_VERSION)
|
||||
#define EIGEN_HAS_ERRNO
|
||||
#endif
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#if (defined(_CPPUNWIND) || defined(__EXCEPTIONS)) && !defined(EIGEN_NO_EXCEPTIONS)
|
||||
#if defined(_CPPUNWIND) || defined(__EXCEPTIONS)
|
||||
#define EIGEN_EXCEPTIONS
|
||||
#endif
|
||||
|
||||
|
||||
@@ -13,9 +13,9 @@ namespace Eigen {
|
||||
*
|
||||
*
|
||||
*
|
||||
* This module provides SVD decomposition for (currently) real matrices.
|
||||
* This module provides SVD decomposition for matrices (both real and complex).
|
||||
* This decomposition is accessible via the following MatrixBase method:
|
||||
* - MatrixBase::svd()
|
||||
* - MatrixBase::jacobiSvd()
|
||||
*
|
||||
* \code
|
||||
* #include <Eigen/SVD>
|
||||
|
||||
@@ -331,16 +331,16 @@ template<> struct ldlt_inplace<Upper>
|
||||
|
||||
template<typename MatrixType> struct LDLT_Traits<MatrixType,Lower>
|
||||
{
|
||||
typedef TriangularView<MatrixType, UnitLower> MatrixL;
|
||||
typedef TriangularView<typename MatrixType::AdjointReturnType, UnitUpper> MatrixU;
|
||||
typedef const TriangularView<const MatrixType, UnitLower> MatrixL;
|
||||
typedef const TriangularView<const typename MatrixType::AdjointReturnType, UnitUpper> MatrixU;
|
||||
inline static MatrixL getL(const MatrixType& m) { return m; }
|
||||
inline static MatrixU getU(const MatrixType& m) { return m.adjoint(); }
|
||||
};
|
||||
|
||||
template<typename MatrixType> struct LDLT_Traits<MatrixType,Upper>
|
||||
{
|
||||
typedef TriangularView<typename MatrixType::AdjointReturnType, UnitLower> MatrixL;
|
||||
typedef TriangularView<MatrixType, UnitUpper> MatrixU;
|
||||
typedef const TriangularView<const typename MatrixType::AdjointReturnType, UnitLower> MatrixL;
|
||||
typedef const TriangularView<const MatrixType, UnitUpper> MatrixU;
|
||||
inline static MatrixL getL(const MatrixType& m) { return m.adjoint(); }
|
||||
inline static MatrixU getU(const MatrixType& m) { return m; }
|
||||
};
|
||||
|
||||
@@ -274,8 +274,8 @@ template<> struct llt_inplace<Upper>
|
||||
|
||||
template<typename MatrixType> struct LLT_Traits<MatrixType,Lower>
|
||||
{
|
||||
typedef TriangularView<MatrixType, Lower> MatrixL;
|
||||
typedef TriangularView<typename MatrixType::AdjointReturnType, Upper> MatrixU;
|
||||
typedef const TriangularView<const MatrixType, Lower> MatrixL;
|
||||
typedef const TriangularView<const typename MatrixType::AdjointReturnType, Upper> MatrixU;
|
||||
inline static MatrixL getL(const MatrixType& m) { return m; }
|
||||
inline static MatrixU getU(const MatrixType& m) { return m.adjoint(); }
|
||||
static bool inplace_decomposition(MatrixType& m)
|
||||
@@ -284,8 +284,8 @@ template<typename MatrixType> struct LLT_Traits<MatrixType,Lower>
|
||||
|
||||
template<typename MatrixType> struct LLT_Traits<MatrixType,Upper>
|
||||
{
|
||||
typedef TriangularView<typename MatrixType::AdjointReturnType, Lower> MatrixL;
|
||||
typedef TriangularView<MatrixType, Upper> MatrixU;
|
||||
typedef const TriangularView<const typename MatrixType::AdjointReturnType, Lower> MatrixL;
|
||||
typedef const TriangularView<const MatrixType, Upper> MatrixU;
|
||||
inline static MatrixL getL(const MatrixType& m) { return m.adjoint(); }
|
||||
inline static MatrixU getU(const MatrixType& m) { return m; }
|
||||
static bool inplace_decomposition(MatrixType& m)
|
||||
|
||||
@@ -68,10 +68,8 @@ class Array
|
||||
friend struct internal::conservative_resize_like_impl;
|
||||
|
||||
using Base::m_storage;
|
||||
|
||||
public:
|
||||
enum { NeedsToAlign = (!(Options&DontAlign))
|
||||
&& SizeAtCompileTime!=Dynamic && ((static_cast<int>(sizeof(Scalar))*SizeAtCompileTime)%16)==0 };
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
|
||||
|
||||
using Base::base;
|
||||
using Base::coeff;
|
||||
|
||||
@@ -94,7 +94,7 @@ struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel, HasDirectAccess>
|
||||
MaskPacketAccessBit = (InnerSize == Dynamic || (InnerSize % packet_traits<Scalar>::size) == 0)
|
||||
&& (InnerStrideAtCompileTime == 1)
|
||||
? PacketAccessBit : 0,
|
||||
MaskAlignedBit = (InnerPanel && (OuterStrideAtCompileTime!=Dynamic) && ((OuterStrideAtCompileTime % packet_traits<Scalar>::size) == 0)) ? AlignedBit : 0,
|
||||
MaskAlignedBit = (InnerPanel && (OuterStrideAtCompileTime!=Dynamic) && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % 16) == 0)) ? AlignedBit : 0,
|
||||
FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
|
||||
FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
|
||||
FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
|
||||
@@ -342,7 +342,7 @@ class Block<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||
}
|
||||
|
||||
const typename XprType::Nested m_xpr;
|
||||
int m_outerStride;
|
||||
Index m_outerStride;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -169,8 +169,8 @@ template<typename Derived> class DenseBase
|
||||
|
||||
IsRowMajor = int(Flags) & RowMajorBit, /**< True if this expression has row-major storage order. */
|
||||
|
||||
InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? SizeAtCompileTime
|
||||
: int(IsRowMajor) ? ColsAtCompileTime : RowsAtCompileTime,
|
||||
InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
|
||||
: int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
|
||||
|
||||
CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
|
||||
/**< This is a rough measure of how expensive it is to read one coefficient from
|
||||
|
||||
@@ -249,7 +249,7 @@ struct functor_traits<scalar_opposite_op<Scalar> >
|
||||
template<typename Scalar> struct scalar_abs_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_abs_op)
|
||||
typedef typename NumTraits<Scalar>::Real result_type;
|
||||
EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return abs(a); }
|
||||
EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return internal::abs(a); }
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
|
||||
{ return internal::pabs(a); }
|
||||
@@ -271,7 +271,7 @@ struct functor_traits<scalar_abs_op<Scalar> >
|
||||
template<typename Scalar> struct scalar_abs2_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_abs2_op)
|
||||
typedef typename NumTraits<Scalar>::Real result_type;
|
||||
EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return abs2(a); }
|
||||
EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return internal::abs2(a); }
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
|
||||
{ return internal::pmul(a,a); }
|
||||
@@ -287,7 +287,7 @@ struct functor_traits<scalar_abs2_op<Scalar> >
|
||||
*/
|
||||
template<typename Scalar> struct scalar_conjugate_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_conjugate_op)
|
||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return conj(a); }
|
||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return internal::conj(a); }
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pconj(a); }
|
||||
};
|
||||
@@ -324,7 +324,7 @@ template<typename Scalar>
|
||||
struct scalar_real_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_real_op)
|
||||
typedef typename NumTraits<Scalar>::Real result_type;
|
||||
EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return real(a); }
|
||||
EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return internal::real(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_real_op<Scalar> >
|
||||
@@ -339,7 +339,7 @@ template<typename Scalar>
|
||||
struct scalar_imag_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_op)
|
||||
typedef typename NumTraits<Scalar>::Real result_type;
|
||||
EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return imag(a); }
|
||||
EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return internal::imag(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_imag_op<Scalar> >
|
||||
@@ -354,7 +354,7 @@ template<typename Scalar>
|
||||
struct scalar_real_ref_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_real_ref_op)
|
||||
typedef typename NumTraits<Scalar>::Real result_type;
|
||||
EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return real_ref(*const_cast<Scalar*>(&a)); }
|
||||
EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return internal::real_ref(*const_cast<Scalar*>(&a)); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_real_ref_op<Scalar> >
|
||||
@@ -369,7 +369,7 @@ template<typename Scalar>
|
||||
struct scalar_imag_ref_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_ref_op)
|
||||
typedef typename NumTraits<Scalar>::Real result_type;
|
||||
EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return imag_ref(*const_cast<Scalar*>(&a)); }
|
||||
EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return internal::imag_ref(*const_cast<Scalar*>(&a)); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_imag_ref_op<Scalar> >
|
||||
@@ -383,7 +383,7 @@ struct functor_traits<scalar_imag_ref_op<Scalar> >
|
||||
*/
|
||||
template<typename Scalar> struct scalar_exp_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_exp_op)
|
||||
inline const Scalar operator() (const Scalar& a) const { return exp(a); }
|
||||
inline const Scalar operator() (const Scalar& a) const { return internal::exp(a); }
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
inline Packet packetOp(const Packet& a) const { return internal::pexp(a); }
|
||||
};
|
||||
@@ -399,7 +399,7 @@ struct functor_traits<scalar_exp_op<Scalar> >
|
||||
*/
|
||||
template<typename Scalar> struct scalar_log_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_log_op)
|
||||
inline const Scalar operator() (const Scalar& a) const { return log(a); }
|
||||
inline const Scalar operator() (const Scalar& a) const { return internal::log(a); }
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
inline Packet packetOp(const Packet& a) const { return internal::plog(a); }
|
||||
};
|
||||
@@ -657,7 +657,7 @@ struct functor_traits<scalar_add_op<Scalar> >
|
||||
*/
|
||||
template<typename Scalar> struct scalar_sqrt_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op)
|
||||
inline const Scalar operator() (const Scalar& a) const { return sqrt(a); }
|
||||
inline const Scalar operator() (const Scalar& a) const { return internal::sqrt(a); }
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
inline Packet packetOp(const Packet& a) const { return internal::psqrt(a); }
|
||||
};
|
||||
@@ -675,7 +675,7 @@ struct functor_traits<scalar_sqrt_op<Scalar> >
|
||||
*/
|
||||
template<typename Scalar> struct scalar_cos_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op)
|
||||
inline Scalar operator() (const Scalar& a) const { return cos(a); }
|
||||
inline Scalar operator() (const Scalar& a) const { return internal::cos(a); }
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
inline Packet packetOp(const Packet& a) const { return internal::pcos(a); }
|
||||
};
|
||||
@@ -694,7 +694,7 @@ struct functor_traits<scalar_cos_op<Scalar> >
|
||||
*/
|
||||
template<typename Scalar> struct scalar_sin_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op)
|
||||
inline const Scalar operator() (const Scalar& a) const { return sin(a); }
|
||||
inline const Scalar operator() (const Scalar& a) const { return internal::sin(a); }
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
inline Packet packetOp(const Packet& a) const { return internal::psin(a); }
|
||||
};
|
||||
@@ -714,7 +714,7 @@ struct functor_traits<scalar_sin_op<Scalar> >
|
||||
*/
|
||||
template<typename Scalar> struct scalar_tan_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op)
|
||||
inline const Scalar operator() (const Scalar& a) const { return tan(a); }
|
||||
inline const Scalar operator() (const Scalar& a) const { return internal::tan(a); }
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
inline Packet packetOp(const Packet& a) const { return internal::ptan(a); }
|
||||
};
|
||||
@@ -733,7 +733,7 @@ struct functor_traits<scalar_tan_op<Scalar> >
|
||||
*/
|
||||
template<typename Scalar> struct scalar_acos_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op)
|
||||
inline const Scalar operator() (const Scalar& a) const { return acos(a); }
|
||||
inline const Scalar operator() (const Scalar& a) const { return internal::acos(a); }
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
inline Packet packetOp(const Packet& a) const { return internal::pacos(a); }
|
||||
};
|
||||
@@ -752,7 +752,7 @@ struct functor_traits<scalar_acos_op<Scalar> >
|
||||
*/
|
||||
template<typename Scalar> struct scalar_asin_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op)
|
||||
inline const Scalar operator() (const Scalar& a) const { return asin(a); }
|
||||
inline const Scalar operator() (const Scalar& a) const { return internal::asin(a); }
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
inline Packet packetOp(const Packet& a) const { return internal::pasin(a); }
|
||||
};
|
||||
|
||||
@@ -102,7 +102,7 @@ struct traits<Map<PlainObjectType, MapOptions, StrideType> >
|
||||
|| HasNoOuterStride
|
||||
|| ( OuterStrideAtCompileTime!=Dynamic
|
||||
&& ((static_cast<int>(sizeof(Scalar))*OuterStrideAtCompileTime)%16)==0 ) ),
|
||||
Flags0 = TraitsBase::Flags,
|
||||
Flags0 = TraitsBase::Flags & (~NestByRefBit),
|
||||
Flags1 = IsAligned ? (int(Flags0) | AlignedBit) : (int(Flags0) & ~AlignedBit),
|
||||
Flags2 = (bool(HasNoStride) || bool(PlainObjectType::IsVectorAtCompileTime))
|
||||
? int(Flags1) : int(Flags1 & ~LinearAccessBit),
|
||||
@@ -120,7 +120,6 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
|
||||
public:
|
||||
|
||||
typedef MapBase<Map> Base;
|
||||
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Map)
|
||||
|
||||
typedef typename Base::PointerType PointerType;
|
||||
@@ -181,7 +180,6 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
|
||||
PlainObjectType::Base::_check_template_params();
|
||||
}
|
||||
|
||||
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map)
|
||||
|
||||
protected:
|
||||
|
||||
@@ -170,8 +170,8 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
||||
EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(internal::traits<Derived>::Flags&PacketAccessBit,
|
||||
internal::inner_stride_at_compile_time<Derived>::ret==1),
|
||||
PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1);
|
||||
eigen_assert(EIGEN_IMPLIES(internal::traits<Derived>::Flags&AlignedBit, (size_t(m_data) % (sizeof(Scalar)*internal::packet_traits<Scalar>::size)) == 0)
|
||||
&& "data is not aligned");
|
||||
eigen_assert(EIGEN_IMPLIES(internal::traits<Derived>::Flags&AlignedBit, (size_t(m_data) % 16) == 0)
|
||||
&& "data is not aligned");
|
||||
}
|
||||
|
||||
PointerType m_data;
|
||||
|
||||
@@ -153,10 +153,6 @@ class Matrix
|
||||
|
||||
typedef typename Base::PlainObject PlainObject;
|
||||
|
||||
enum { NeedsToAlign = (!(Options&DontAlign))
|
||||
&& SizeAtCompileTime!=Dynamic && ((static_cast<int>(sizeof(Scalar))*SizeAtCompileTime)%16)==0 };
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
|
||||
|
||||
using Base::base;
|
||||
using Base::coeffRef;
|
||||
|
||||
|
||||
@@ -34,7 +34,20 @@
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <typename Derived, typename OtherDerived = Derived, bool IsVector = static_cast<bool>(Derived::IsVectorAtCompileTime)> struct conservative_resize_like_impl;
|
||||
template<typename Index>
|
||||
EIGEN_ALWAYS_INLINE void check_rows_cols_for_overflow(Index rows, Index cols)
|
||||
{
|
||||
// http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242
|
||||
// we assume Index is signed
|
||||
Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed
|
||||
bool error = (rows < 0 || cols < 0) ? true
|
||||
: (rows == 0 || cols == 0) ? false
|
||||
: (rows > max_index / cols);
|
||||
if (error)
|
||||
throw_std_bad_alloc();
|
||||
}
|
||||
|
||||
template <typename Derived, typename OtherDerived = Derived, bool IsVector = bool(Derived::IsVectorAtCompileTime)> struct conservative_resize_like_impl;
|
||||
|
||||
template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl;
|
||||
|
||||
@@ -84,14 +97,12 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
template<typename StrideType> struct StridedConstMapType { typedef Eigen::Map<const Derived, Unaligned, StrideType> type; };
|
||||
template<typename StrideType> struct StridedAlignedMapType { typedef Eigen::Map<Derived, Aligned, StrideType> type; };
|
||||
template<typename StrideType> struct StridedConstAlignedMapType { typedef Eigen::Map<const Derived, Aligned, StrideType> type; };
|
||||
|
||||
|
||||
protected:
|
||||
DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
|
||||
|
||||
public:
|
||||
enum { NeedsToAlign = (!(Options&DontAlign))
|
||||
&& SizeAtCompileTime!=Dynamic && ((static_cast<int>(sizeof(Scalar))*SizeAtCompileTime)%16)==0 };
|
||||
enum { NeedsToAlign = SizeAtCompileTime != Dynamic && (internal::traits<Derived>::Flags & AlignedBit) != 0 };
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
|
||||
|
||||
Base& base() { return *static_cast<Base*>(this); }
|
||||
@@ -200,11 +211,13 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
|
||||
{
|
||||
#ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
|
||||
internal::check_rows_cols_for_overflow(rows, cols);
|
||||
Index 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
|
||||
internal::check_rows_cols_for_overflow(rows, cols);
|
||||
m_storage.resize(rows*cols, rows, cols);
|
||||
#endif
|
||||
}
|
||||
@@ -273,6 +286,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
|
||||
{
|
||||
const OtherDerived& other = _other.derived();
|
||||
internal::check_rows_cols_for_overflow(other.rows(), other.cols());
|
||||
const Index othersize = other.rows()*other.cols();
|
||||
if(RowsAtCompileTime == 1)
|
||||
{
|
||||
@@ -417,6 +431,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
: m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
|
||||
{
|
||||
_check_template_params();
|
||||
internal::check_rows_cols_for_overflow(other.derived().rows(), other.derived().cols());
|
||||
Base::operator=(other.derived());
|
||||
}
|
||||
|
||||
@@ -581,6 +596,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
{
|
||||
eigen_assert(rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
|
||||
&& cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
|
||||
internal::check_rows_cols_for_overflow(rows, cols);
|
||||
m_storage.resize(rows*cols,rows,cols);
|
||||
EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
|
||||
}
|
||||
@@ -638,6 +654,7 @@ struct internal::conservative_resize_like_impl
|
||||
if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows
|
||||
(!Derived::IsRowMajor && _this.rows() == rows) ) // column-major and we change only the number of columns
|
||||
{
|
||||
internal::check_rows_cols_for_overflow(rows, cols);
|
||||
_this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -152,7 +152,8 @@ class ProductBase : public MatrixBase<Derived>
|
||||
#else
|
||||
EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
|
||||
eigen_assert(this->rows() == 1 && this->cols() == 1);
|
||||
return derived().coeff(row,col);
|
||||
Matrix<Scalar,1,1> result = *this;
|
||||
return result.coeff(row,col);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -160,7 +161,8 @@ class ProductBase : public MatrixBase<Derived>
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
|
||||
eigen_assert(this->rows() == 1 && this->cols() == 1);
|
||||
return derived().coeff(i);
|
||||
Matrix<Scalar,1,1> result = *this;
|
||||
return result.coeff(i);
|
||||
}
|
||||
|
||||
const Scalar& coeffRef(Index row, Index col) const
|
||||
|
||||
@@ -48,7 +48,10 @@ struct traits<Replicate<MatrixType,RowFactor,ColFactor> >
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename traits<MatrixType>::StorageKind StorageKind;
|
||||
typedef typename traits<MatrixType>::XprKind XprKind;
|
||||
typedef typename nested<MatrixType>::type MatrixTypeNested;
|
||||
enum {
|
||||
Factor = (RowFactor==Dynamic || ColFactor==Dynamic) ? Dynamic : RowFactor*ColFactor
|
||||
};
|
||||
typedef typename nested<MatrixType,Factor>::type MatrixTypeNested;
|
||||
typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
|
||||
enum {
|
||||
RowsAtCompileTime = RowFactor==Dynamic || int(MatrixType::RowsAtCompileTime)==Dynamic
|
||||
@@ -72,6 +75,8 @@ struct traits<Replicate<MatrixType,RowFactor,ColFactor> >
|
||||
template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
|
||||
: public internal::dense_xpr_base< Replicate<MatrixType,RowFactor,ColFactor> >::type
|
||||
{
|
||||
typedef typename internal::traits<Replicate>::MatrixTypeNested MatrixTypeNested;
|
||||
typedef typename internal::traits<Replicate>::_MatrixTypeNested _MatrixTypeNested;
|
||||
public:
|
||||
|
||||
typedef typename internal::dense_xpr_base<Replicate>::type Base;
|
||||
@@ -124,7 +129,7 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
|
||||
|
||||
|
||||
protected:
|
||||
const typename MatrixType::Nested m_matrix;
|
||||
const MatrixTypeNested m_matrix;
|
||||
const internal::variable_if_dynamic<Index, RowFactor> m_rowFactor;
|
||||
const internal::variable_if_dynamic<Index, ColFactor> m_colFactor;
|
||||
};
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
|
||||
namespace internal {
|
||||
|
||||
static uint32x4_t p4ui_CONJ_XOR = { 0x00000000, 0x80000000, 0x00000000, 0x80000000 };
|
||||
static uint32x2_t p2ui_CONJ_XOR = { 0x00000000, 0x80000000 };
|
||||
static uint32x4_t p4ui_CONJ_XOR = EIGEN_INIT_NEON_PACKET4(0x00000000, 0x80000000, 0x00000000, 0x80000000);
|
||||
static uint32x2_t p2ui_CONJ_XOR = EIGEN_INIT_NEON_PACKET2(0x00000000, 0x80000000);
|
||||
|
||||
//---------- float ----------
|
||||
struct Packet2cf
|
||||
|
||||
@@ -52,6 +52,16 @@ typedef uint32x4_t Packet4ui;
|
||||
#define _EIGEN_DECLARE_CONST_Packet4i(NAME,X) \
|
||||
const Packet4i p4i_##NAME = pset1<Packet4i>(X)
|
||||
|
||||
#if defined(__llvm__) && !defined(__clang__)
|
||||
//Special treatment for Apple's llvm-gcc, its NEON packet types are unions
|
||||
#define EIGEN_INIT_NEON_PACKET2(X, Y) {{X, Y}}
|
||||
#define EIGEN_INIT_NEON_PACKET4(X, Y, Z, W) {{X, Y, Z, W}}
|
||||
#else
|
||||
//Default initializer for packets
|
||||
#define EIGEN_INIT_NEON_PACKET2(X, Y) {X, Y}
|
||||
#define EIGEN_INIT_NEON_PACKET4(X, Y, Z, W) {X, Y, Z, W}
|
||||
#endif
|
||||
|
||||
#ifndef __pld
|
||||
#define __pld(x) asm volatile ( " pld [%[addr]]\n" :: [addr] "r" (x) : "cc" );
|
||||
#endif
|
||||
@@ -84,7 +94,7 @@ template<> struct packet_traits<int> : default_packet_traits
|
||||
};
|
||||
};
|
||||
|
||||
#if EIGEN_GNUC_AT_MOST(4,4)
|
||||
#if EIGEN_GNUC_AT_MOST(4,4) && !defined(__llvm__)
|
||||
// workaround gcc 4.2, 4.3 and 4.4 compilatin issue
|
||||
EIGEN_STRONG_INLINE float32x4_t vld1q_f32(const float* x) { return ::vld1q_f32((const float32_t*)x); }
|
||||
EIGEN_STRONG_INLINE float32x2_t vld1_f32 (const float* x) { return ::vld1_f32 ((const float32_t*)x); }
|
||||
@@ -100,12 +110,12 @@ template<> EIGEN_STRONG_INLINE Packet4i pset1<Packet4i>(const int& from) {
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f plset<float>(const float& a)
|
||||
{
|
||||
Packet4f countdown = { 0, 1, 2, 3 };
|
||||
Packet4f countdown = EIGEN_INIT_NEON_PACKET4(0, 1, 2, 3);
|
||||
return vaddq_f32(pset1<Packet4f>(a), countdown);
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet4i plset<int>(const int& a)
|
||||
{
|
||||
Packet4i countdown = { 0, 1, 2, 3 };
|
||||
Packet4i countdown = EIGEN_INIT_NEON_PACKET4(0, 1, 2, 3);
|
||||
return vaddq_s32(pset1<Packet4i>(a), countdown);
|
||||
}
|
||||
|
||||
@@ -395,25 +405,29 @@ template<> EIGEN_STRONG_INLINE int predux_max<Packet4i>(const Packet4i& a)
|
||||
return s[0];
|
||||
}
|
||||
|
||||
template<int Offset>
|
||||
struct palign_impl<Offset,Packet4f>
|
||||
{
|
||||
EIGEN_STRONG_INLINE static void run(Packet4f& first, const Packet4f& second)
|
||||
{
|
||||
if (Offset!=0)
|
||||
first = vextq_f32(first, second, Offset);
|
||||
}
|
||||
};
|
||||
// this PALIGN_NEON business is to work around a bug in LLVM Clang 3.0 causing incorrect compilation errors,
|
||||
// see bug 347 and this LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=11074
|
||||
#define PALIGN_NEON(Offset,Type,Command) \
|
||||
template<>\
|
||||
struct palign_impl<Offset,Type>\
|
||||
{\
|
||||
EIGEN_STRONG_INLINE static void run(Type& first, const Type& second)\
|
||||
{\
|
||||
if (Offset!=0)\
|
||||
first = Command(first, second, Offset);\
|
||||
}\
|
||||
};\
|
||||
|
||||
template<int Offset>
|
||||
struct palign_impl<Offset,Packet4i>
|
||||
{
|
||||
EIGEN_STRONG_INLINE static void run(Packet4i& first, const Packet4i& second)
|
||||
{
|
||||
if (Offset!=0)
|
||||
first = vextq_s32(first, second, Offset);
|
||||
}
|
||||
};
|
||||
PALIGN_NEON(0,Packet4f,vextq_f32)
|
||||
PALIGN_NEON(1,Packet4f,vextq_f32)
|
||||
PALIGN_NEON(2,Packet4f,vextq_f32)
|
||||
PALIGN_NEON(3,Packet4f,vextq_f32)
|
||||
PALIGN_NEON(0,Packet4i,vextq_s32)
|
||||
PALIGN_NEON(1,Packet4i,vextq_s32)
|
||||
PALIGN_NEON(2,Packet4i,vextq_s32)
|
||||
PALIGN_NEON(3,Packet4i,vextq_s32)
|
||||
|
||||
#undef PALIGN_NEON
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ Packet4f pexp<Packet4f>(const Packet4f& _x)
|
||||
_EIGEN_DECLARE_CONST_Packet4i(0x7f, 0x7f);
|
||||
|
||||
|
||||
_EIGEN_DECLARE_CONST_Packet4f(exp_hi, 88.3762626647949f);
|
||||
_EIGEN_DECLARE_CONST_Packet4f(exp_hi, 88.3762626647950f);
|
||||
_EIGEN_DECLARE_CONST_Packet4f(exp_lo, -88.3762626647949f);
|
||||
|
||||
_EIGEN_DECLARE_CONST_Packet4f(cephes_LOG2EF, 1.44269504088896341f);
|
||||
@@ -168,7 +168,7 @@ Packet4f pexp<Packet4f>(const Packet4f& _x)
|
||||
y = pmadd(y, z, x);
|
||||
y = padd(y, p4f_1);
|
||||
|
||||
/* build 2^n */
|
||||
// build 2^n
|
||||
emm0 = _mm_cvttps_epi32(fx);
|
||||
emm0 = _mm_add_epi32(emm0, p4i_0x7f);
|
||||
emm0 = _mm_slli_epi32(emm0, 23);
|
||||
|
||||
@@ -30,18 +30,24 @@ namespace internal {
|
||||
template<typename _LhsScalar, typename _RhsScalar, bool _ConjLhs=false, bool _ConjRhs=false>
|
||||
class gebp_traits;
|
||||
|
||||
/** \internal \returns b if a<=0, and returns a otherwise. */
|
||||
inline std::ptrdiff_t manage_caching_sizes_helper(std::ptrdiff_t a, std::ptrdiff_t b)
|
||||
{
|
||||
return a<=0 ? b : a;
|
||||
}
|
||||
|
||||
/** \internal */
|
||||
inline void manage_caching_sizes(Action action, std::ptrdiff_t* l1=0, std::ptrdiff_t* l2=0)
|
||||
{
|
||||
static std::ptrdiff_t m_l1CacheSize = 0;
|
||||
static std::ptrdiff_t m_l2CacheSize = 0;
|
||||
#ifdef _OPENMP
|
||||
#pragma omp threadprivate(m_l1CacheSize,m_l2CacheSize)
|
||||
#endif
|
||||
if(m_l1CacheSize==0)
|
||||
{
|
||||
m_l1CacheSize = queryL1CacheSize();
|
||||
m_l2CacheSize = queryTopLevelCacheSize();
|
||||
|
||||
if(m_l1CacheSize<=0) m_l1CacheSize = 8 * 1024;
|
||||
if(m_l2CacheSize<=0) m_l2CacheSize = 1 * 1024 * 1024;
|
||||
m_l1CacheSize = manage_caching_sizes_helper(queryL1CacheSize(),8 * 1024);
|
||||
m_l2CacheSize = manage_caching_sizes_helper(queryTopLevelCacheSize(),1*1024*1024);
|
||||
}
|
||||
|
||||
if(action==SetAction)
|
||||
@@ -118,14 +124,14 @@ inline void computeProductBlockingSizes(std::ptrdiff_t& k, std::ptrdiff_t& m, st
|
||||
// FIXME (a bit overkill maybe ?)
|
||||
|
||||
template<typename CJ, typename A, typename B, typename C, typename T> struct gebp_madd_selector {
|
||||
EIGEN_STRONG_INLINE EIGEN_ALWAYS_INLINE_ATTRIB static void run(const CJ& cj, A& a, B& b, C& c, T& /*t*/)
|
||||
EIGEN_ALWAYS_INLINE static void run(const CJ& cj, A& a, B& b, C& c, T& /*t*/)
|
||||
{
|
||||
c = cj.pmadd(a,b,c);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename CJ, typename T> struct gebp_madd_selector<CJ,T,T,T,T> {
|
||||
EIGEN_STRONG_INLINE EIGEN_ALWAYS_INLINE_ATTRIB static void run(const CJ& cj, T& a, T& b, T& c, T& t)
|
||||
EIGEN_ALWAYS_INLINE static void run(const CJ& cj, T& a, T& b, T& c, T& t)
|
||||
{
|
||||
t = b; t = cj.pmul(a,t); c = padd(c,t);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
@@ -28,7 +29,7 @@
|
||||
|
||||
#define EIGEN_WORLD_VERSION 3
|
||||
#define EIGEN_MAJOR_VERSION 0
|
||||
#define EIGEN_MINOR_VERSION 3
|
||||
#define EIGEN_MINOR_VERSION 6
|
||||
|
||||
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
|
||||
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
|
||||
@@ -45,7 +46,7 @@
|
||||
#define EIGEN_GNUC_AT_MOST(x,y) 0
|
||||
#endif
|
||||
|
||||
#if EIGEN_GNUC_AT_MOST(4,3)
|
||||
#if EIGEN_GNUC_AT_MOST(4,3) && !defined(__clang__)
|
||||
// see bug 89
|
||||
#define EIGEN_SAFE_TO_USE_STANDARD_ASSERT_MACRO 0
|
||||
#else
|
||||
@@ -130,31 +131,34 @@
|
||||
#define EIGEN_MAKESTRING2(a) #a
|
||||
#define EIGEN_MAKESTRING(a) EIGEN_MAKESTRING2(a)
|
||||
|
||||
// EIGEN_ALWAYS_INLINE_ATTRIB should be use in the declaration of function
|
||||
// which should be inlined even in debug mode.
|
||||
// FIXME with the always_inline attribute,
|
||||
// gcc 3.4.x reports the following compilation error:
|
||||
// Eval.h:91: sorry, unimplemented: inlining failed in call to 'const Eigen::Eval<Derived> Eigen::MatrixBase<Scalar, Derived>::eval() const'
|
||||
// : function body not available
|
||||
#if EIGEN_GNUC_AT_LEAST(4,0)
|
||||
#define EIGEN_ALWAYS_INLINE_ATTRIB __attribute__((always_inline))
|
||||
#else
|
||||
#define EIGEN_ALWAYS_INLINE_ATTRIB
|
||||
#endif
|
||||
|
||||
#if EIGEN_GNUC_AT_LEAST(4,1) && !defined(__clang__) && !defined(__INTEL_COMPILER)
|
||||
#define EIGEN_FLATTEN_ATTRIB __attribute__((flatten))
|
||||
#else
|
||||
#define EIGEN_FLATTEN_ATTRIB
|
||||
#endif
|
||||
|
||||
// EIGEN_FORCE_INLINE means "inline as much as possible"
|
||||
// EIGEN_STRONG_INLINE is a stronger version of the inline, using __forceinline on MSVC,
|
||||
// but it still doesn't use GCC's always_inline. This is useful in (common) situations where MSVC needs forceinline
|
||||
// but GCC is still doing fine with just inline.
|
||||
#if (defined _MSC_VER) || (defined __INTEL_COMPILER)
|
||||
#define EIGEN_STRONG_INLINE __forceinline
|
||||
#else
|
||||
#define EIGEN_STRONG_INLINE inline
|
||||
#endif
|
||||
|
||||
// EIGEN_ALWAYS_INLINE is the stronget, it has the effect of making the function inline and adding every possible
|
||||
// attribute to maximize inlining. This should only be used when really necessary: in particular,
|
||||
// it uses __attribute__((always_inline)) on GCC, which most of the time is useless and can severely harm compile times.
|
||||
// FIXME with the always_inline attribute,
|
||||
// gcc 3.4.x reports the following compilation error:
|
||||
// Eval.h:91: sorry, unimplemented: inlining failed in call to 'const Eigen::Eval<Derived> Eigen::MatrixBase<Scalar, Derived>::eval() const'
|
||||
// : function body not available
|
||||
#if EIGEN_GNUC_AT_LEAST(4,0)
|
||||
#define EIGEN_ALWAYS_INLINE __attribute__((always_inline)) inline
|
||||
#else
|
||||
#define EIGEN_ALWAYS_INLINE EIGEN_STRONG_INLINE
|
||||
#endif
|
||||
|
||||
#if (defined __GNUC__)
|
||||
#define EIGEN_DONT_INLINE __attribute__((noinline))
|
||||
#elif (defined _MSC_VER)
|
||||
@@ -249,7 +253,7 @@
|
||||
#define EIGEN_UNUSED_VARIABLE(var) (void)var;
|
||||
|
||||
#if (defined __GNUC__)
|
||||
#define EIGEN_ASM_COMMENT(X) asm("#"X)
|
||||
#define EIGEN_ASM_COMMENT(X) asm("#" X)
|
||||
#else
|
||||
#define EIGEN_ASM_COMMENT(X)
|
||||
#endif
|
||||
@@ -261,7 +265,7 @@
|
||||
* If we made alignment depend on whether or not EIGEN_VECTORIZE is defined, it would be impossible to link
|
||||
* vectorized and non-vectorized code.
|
||||
*/
|
||||
#if (defined __GNUC__) || (defined __PGI) || (defined __IBMCPP__)
|
||||
#if (defined __GNUC__) || (defined __PGI) || (defined __IBMCPP__) || (defined __ARMCC_VERSION)
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n)))
|
||||
#elif (defined _MSC_VER)
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __declspec(align(n))
|
||||
|
||||
@@ -82,6 +82,16 @@
|
||||
|
||||
namespace internal {
|
||||
|
||||
inline void throw_std_bad_alloc()
|
||||
{
|
||||
#ifdef EIGEN_EXCEPTIONS
|
||||
throw std::bad_alloc();
|
||||
#else
|
||||
std::size_t huge = -1;
|
||||
new int[huge];
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*** Implementation of handmade aligned functions ***
|
||||
*****************************************************************************/
|
||||
@@ -192,7 +202,7 @@ inline void check_that_malloc_is_allowed()
|
||||
#endif
|
||||
|
||||
/** \internal Allocates \a size bytes. The returned pointer is guaranteed to have 16 bytes alignment.
|
||||
* On allocation error, the returned pointer is null, and if exceptions are enabled then a std::bad_alloc is thrown.
|
||||
* On allocation error, the returned pointer is null, and std::bad_alloc is thrown.
|
||||
*/
|
||||
inline void* aligned_malloc(size_t size)
|
||||
{
|
||||
@@ -213,10 +223,9 @@ inline void* aligned_malloc(size_t size)
|
||||
result = handmade_aligned_malloc(size);
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_EXCEPTIONS
|
||||
if(result == 0)
|
||||
throw std::bad_alloc();
|
||||
#endif
|
||||
if(!result && size)
|
||||
throw_std_bad_alloc();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -241,7 +250,7 @@ inline void aligned_free(void *ptr)
|
||||
/**
|
||||
* \internal
|
||||
* \brief Reallocates an aligned block of memory.
|
||||
* \throws std::bad_alloc if EIGEN_EXCEPTIONS are defined.
|
||||
* \throws std::bad_alloc on allocation failure
|
||||
**/
|
||||
inline void* aligned_realloc(void *ptr, size_t new_size, size_t old_size)
|
||||
{
|
||||
@@ -269,10 +278,9 @@ inline void* aligned_realloc(void *ptr, size_t new_size, size_t old_size)
|
||||
result = handmade_aligned_realloc(ptr,new_size,old_size);
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_EXCEPTIONS
|
||||
if (result==0 && new_size!=0)
|
||||
throw std::bad_alloc();
|
||||
#endif
|
||||
if (!result && new_size)
|
||||
throw_std_bad_alloc();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -281,7 +289,7 @@ inline void* aligned_realloc(void *ptr, size_t new_size, size_t old_size)
|
||||
*****************************************************************************/
|
||||
|
||||
/** \internal Allocates \a size bytes. If Align is true, then the returned ptr is 16-byte-aligned.
|
||||
* On allocation error, the returned pointer is null, and if exceptions are enabled then a std::bad_alloc is thrown.
|
||||
* On allocation error, the returned pointer is null, and a std::bad_alloc is thrown.
|
||||
*/
|
||||
template<bool Align> inline void* conditional_aligned_malloc(size_t size)
|
||||
{
|
||||
@@ -293,9 +301,8 @@ template<> inline void* conditional_aligned_malloc<false>(size_t size)
|
||||
check_that_malloc_is_allowed();
|
||||
|
||||
void *result = std::malloc(size);
|
||||
#ifdef EIGEN_EXCEPTIONS
|
||||
if(!result) throw std::bad_alloc();
|
||||
#endif
|
||||
if(!result && size)
|
||||
throw_std_bad_alloc();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -347,18 +354,27 @@ template<typename T> inline void destruct_elements_of_array(T *ptr, size_t size)
|
||||
*** Implementation of aligned new/delete-like functions ***
|
||||
*****************************************************************************/
|
||||
|
||||
template<typename T>
|
||||
EIGEN_ALWAYS_INLINE void check_size_for_overflow(size_t size)
|
||||
{
|
||||
if(size > size_t(-1) / sizeof(T))
|
||||
throw_std_bad_alloc();
|
||||
}
|
||||
|
||||
/** \internal Allocates \a size objects of type T. The returned pointer is guaranteed to have 16 bytes alignment.
|
||||
* On allocation error, the returned pointer is undefined, but if exceptions are enabled then a std::bad_alloc is thrown.
|
||||
* On allocation error, the returned pointer is undefined, but a std::bad_alloc is thrown.
|
||||
* The default constructor of T is called.
|
||||
*/
|
||||
template<typename T> inline T* aligned_new(size_t size)
|
||||
{
|
||||
check_size_for_overflow<T>(size);
|
||||
T *result = reinterpret_cast<T*>(aligned_malloc(sizeof(T)*size));
|
||||
return construct_elements_of_array(result, size);
|
||||
}
|
||||
|
||||
template<typename T, bool Align> inline T* conditional_aligned_new(size_t size)
|
||||
{
|
||||
check_size_for_overflow<T>(size);
|
||||
T *result = reinterpret_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
|
||||
return construct_elements_of_array(result, size);
|
||||
}
|
||||
@@ -383,6 +399,8 @@ template<typename T, bool Align> inline void conditional_aligned_delete(T *ptr,
|
||||
|
||||
template<typename T, bool Align> inline T* conditional_aligned_realloc_new(T* pts, size_t new_size, size_t old_size)
|
||||
{
|
||||
check_size_for_overflow<T>(new_size);
|
||||
check_size_for_overflow<T>(old_size);
|
||||
if(new_size < old_size)
|
||||
destruct_elements_of_array(pts+new_size, old_size-new_size);
|
||||
T *result = reinterpret_cast<T*>(conditional_aligned_realloc<Align>(reinterpret_cast<void*>(pts), sizeof(T)*new_size, sizeof(T)*old_size));
|
||||
@@ -394,6 +412,7 @@ template<typename T, bool Align> inline T* conditional_aligned_realloc_new(T* pt
|
||||
|
||||
template<typename T, bool Align> inline T* conditional_aligned_new_auto(size_t size)
|
||||
{
|
||||
check_size_for_overflow<T>(size);
|
||||
T *result = reinterpret_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
|
||||
if(NumTraits<T>::RequireInitialization)
|
||||
construct_elements_of_array(result, size);
|
||||
@@ -402,6 +421,8 @@ template<typename T, bool Align> inline T* conditional_aligned_new_auto(size_t s
|
||||
|
||||
template<typename T, bool Align> inline T* conditional_aligned_realloc_new_auto(T* pts, size_t new_size, size_t old_size)
|
||||
{
|
||||
check_size_for_overflow<T>(new_size);
|
||||
check_size_for_overflow<T>(old_size);
|
||||
if(NumTraits<T>::RequireInitialization && (new_size < old_size))
|
||||
destruct_elements_of_array(pts+new_size, old_size-new_size);
|
||||
T *result = reinterpret_cast<T*>(conditional_aligned_realloc<Align>(reinterpret_cast<void*>(pts), sizeof(T)*new_size, sizeof(T)*old_size));
|
||||
@@ -536,6 +557,7 @@ template<typename T> class aligned_stack_memory_handler
|
||||
#endif
|
||||
|
||||
#define ei_declare_aligned_stack_constructed_variable(TYPE,NAME,SIZE,BUFFER) \
|
||||
Eigen::internal::check_size_for_overflow<TYPE>(SIZE); \
|
||||
TYPE* NAME = (BUFFER)!=0 ? (BUFFER) \
|
||||
: reinterpret_cast<TYPE*>( \
|
||||
(sizeof(TYPE)*SIZE<=EIGEN_STACK_ALLOCATION_LIMIT) ? EIGEN_ALIGNED_ALLOCA(sizeof(TYPE)*SIZE) \
|
||||
@@ -545,6 +567,7 @@ template<typename T> class aligned_stack_memory_handler
|
||||
#else
|
||||
|
||||
#define ei_declare_aligned_stack_constructed_variable(TYPE,NAME,SIZE,BUFFER) \
|
||||
Eigen::internal::check_size_for_overflow<TYPE>(SIZE); \
|
||||
TYPE* NAME = (BUFFER)!=0 ? BUFFER : reinterpret_cast<TYPE*>(Eigen::internal::aligned_malloc(sizeof(TYPE)*SIZE)); \
|
||||
Eigen::internal::aligned_stack_memory_handler<TYPE> EIGEN_CAT(NAME,_stack_memory_destructor)((BUFFER)==0 ? NAME : 0,SIZE,true)
|
||||
|
||||
@@ -669,6 +692,7 @@ public:
|
||||
pointer allocate( size_type num, const void* hint = 0 )
|
||||
{
|
||||
EIGEN_UNUSED_VARIABLE(hint);
|
||||
internal::check_size_for_overflow<T>(num);
|
||||
return static_cast<pointer>( internal::aligned_malloc( num * sizeof(T) ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -125,10 +125,9 @@ class compute_matrix_flags
|
||||
aligned_bit =
|
||||
(
|
||||
((Options&DontAlign)==0)
|
||||
&& packet_traits<Scalar>::Vectorizable
|
||||
&& (
|
||||
#if EIGEN_ALIGN_STATICALLY
|
||||
((!is_dynamic_size_storage) && (((MaxCols*MaxRows) % packet_traits<Scalar>::size) == 0))
|
||||
((!is_dynamic_size_storage) && (((MaxCols*MaxRows*int(sizeof(Scalar))) % 16) == 0))
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
|
||||
@@ -291,7 +291,7 @@ template<typename _MatrixType> class EigenSolver
|
||||
|
||||
ComputationInfo info() const
|
||||
{
|
||||
eigen_assert(m_isInitialized && "ComplexEigenSolver is not initialized.");
|
||||
eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
|
||||
return m_realSchur.info();
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ typename EigenSolver<MatrixType>::EigenvectorsType EigenSolver<MatrixType>::eige
|
||||
EigenvectorsType matV(n,n);
|
||||
for (Index j=0; j<n; ++j)
|
||||
{
|
||||
if (internal::isMuchSmallerThan(internal::imag(m_eivalues.coeff(j)), internal::real(m_eivalues.coeff(j))))
|
||||
if (internal::isMuchSmallerThan(internal::imag(m_eivalues.coeff(j)), internal::real(m_eivalues.coeff(j))) || j+1==n)
|
||||
{
|
||||
// we have a real eigen value
|
||||
matV.col(j) = m_eivec.col(j).template cast<ComplexScalar>();
|
||||
@@ -570,10 +570,13 @@ void EigenSolver<MatrixType>::doComputeEigenvectors()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// We handled a pair of complex conjugate eigenvalues, so need to skip them both
|
||||
n--;
|
||||
}
|
||||
else
|
||||
{
|
||||
eigen_assert("Internal bug in EigenSolver"); // this should not happen
|
||||
eigen_assert(0 && "Internal bug in EigenSolver"); // this should not happen
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -238,38 +238,41 @@ RealSchur<MatrixType>& RealSchur<MatrixType>::compute(const MatrixType& matrix,
|
||||
Scalar exshift = 0.0; // sum of exceptional shifts
|
||||
Scalar norm = computeNormOfT();
|
||||
|
||||
while (iu >= 0)
|
||||
if(norm!=0)
|
||||
{
|
||||
Index il = findSmallSubdiagEntry(iu, norm);
|
||||
|
||||
// Check for convergence
|
||||
if (il == iu) // One root found
|
||||
{
|
||||
m_matT.coeffRef(iu,iu) = m_matT.coeff(iu,iu) + exshift;
|
||||
if (iu > 0)
|
||||
m_matT.coeffRef(iu, iu-1) = Scalar(0);
|
||||
iu--;
|
||||
iter = 0;
|
||||
}
|
||||
else if (il == iu-1) // Two roots found
|
||||
{
|
||||
splitOffTwoRows(iu, computeU, exshift);
|
||||
iu -= 2;
|
||||
iter = 0;
|
||||
}
|
||||
else // No convergence yet
|
||||
{
|
||||
// The firstHouseholderVector vector has to be initialized to something to get rid of a silly GCC warning (-O1 -Wall -DNDEBUG )
|
||||
Vector3s firstHouseholderVector(0,0,0), shiftInfo;
|
||||
computeShift(iu, iter, exshift, shiftInfo);
|
||||
iter = iter + 1;
|
||||
if (iter > m_maxIterations) break;
|
||||
Index im;
|
||||
initFrancisQRStep(il, iu, shiftInfo, im, firstHouseholderVector);
|
||||
performFrancisQRStep(il, im, iu, computeU, firstHouseholderVector, workspace);
|
||||
}
|
||||
}
|
||||
while (iu >= 0)
|
||||
{
|
||||
Index il = findSmallSubdiagEntry(iu, norm);
|
||||
|
||||
// Check for convergence
|
||||
if (il == iu) // One root found
|
||||
{
|
||||
m_matT.coeffRef(iu,iu) = m_matT.coeff(iu,iu) + exshift;
|
||||
if (iu > 0)
|
||||
m_matT.coeffRef(iu, iu-1) = Scalar(0);
|
||||
iu--;
|
||||
iter = 0;
|
||||
}
|
||||
else if (il == iu-1) // Two roots found
|
||||
{
|
||||
splitOffTwoRows(iu, computeU, exshift);
|
||||
iu -= 2;
|
||||
iter = 0;
|
||||
}
|
||||
else // No convergence yet
|
||||
{
|
||||
// The firstHouseholderVector vector has to be initialized to something to get rid of a silly GCC warning (-O1 -Wall -DNDEBUG )
|
||||
Vector3s firstHouseholderVector(0,0,0), shiftInfo;
|
||||
computeShift(iu, iter, exshift, shiftInfo);
|
||||
iter = iter + 1;
|
||||
if (iter > m_maxIterations) break;
|
||||
Index im;
|
||||
initFrancisQRStep(il, iu, shiftInfo, im, firstHouseholderVector);
|
||||
performFrancisQRStep(il, im, iu, computeU, firstHouseholderVector, workspace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(iter <= m_maxIterations)
|
||||
m_info = Success;
|
||||
else
|
||||
|
||||
@@ -307,7 +307,8 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
||||
|
||||
/** \brief Maximum number of iterations.
|
||||
*
|
||||
* Maximum number of iterations allowed for an eigenvalue to converge.
|
||||
* The algorithm terminates if it does not converge within m_maxIterations * n iterations, where n
|
||||
* denotes the size of the matrix. This value is currently set to 30 (copied from LAPACK).
|
||||
*/
|
||||
static const int m_maxIterations = 30;
|
||||
|
||||
@@ -407,7 +408,7 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
|
||||
|
||||
Index end = n-1;
|
||||
Index start = 0;
|
||||
Index iter = 0; // number of iterations we are working on one element
|
||||
Index iter = 0; // total number of iterations
|
||||
|
||||
while (end>0)
|
||||
{
|
||||
@@ -418,15 +419,14 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
|
||||
// find the largest unreduced block
|
||||
while (end>0 && m_subdiag[end-1]==0)
|
||||
{
|
||||
iter = 0;
|
||||
end--;
|
||||
}
|
||||
if (end<=0)
|
||||
break;
|
||||
|
||||
// if we spent too many iterations on the current element, we give up
|
||||
// if we spent too many iterations, we give up
|
||||
iter++;
|
||||
if(iter > m_maxIterations) break;
|
||||
if(iter > m_maxIterations * n) break;
|
||||
|
||||
start = end - 1;
|
||||
while (start>0 && m_subdiag[start-1]!=0)
|
||||
@@ -435,7 +435,7 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
|
||||
internal::tridiagonal_qr_step<MatrixType::Flags&RowMajorBit ? RowMajor : ColMajor>(diag.data(), m_subdiag.data(), start, end, computeEigenvectors ? m_eivec.data() : (Scalar*)0, n);
|
||||
}
|
||||
|
||||
if (iter <= m_maxIterations)
|
||||
if (iter <= m_maxIterations * n)
|
||||
m_info = Success;
|
||||
else
|
||||
m_info = NoConvergence;
|
||||
|
||||
@@ -225,7 +225,7 @@ public:
|
||||
normal() = mat * normal();
|
||||
else
|
||||
{
|
||||
eigen_assert("invalid traits value in Hyperplane::transform()");
|
||||
eigen_assert(0 && "invalid traits value in Hyperplane::transform()");
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -182,10 +182,9 @@ public:
|
||||
template<typename NewScalarType>
|
||||
inline typename internal::cast_return_type<Derived,Quaternion<NewScalarType> >::type cast() const
|
||||
{
|
||||
return typename internal::cast_return_type<Derived,Quaternion<NewScalarType> >::type(
|
||||
coeffs().template cast<NewScalarType>());
|
||||
return typename internal::cast_return_type<Derived,Quaternion<NewScalarType> >::type(derived());
|
||||
}
|
||||
|
||||
|
||||
#ifdef EIGEN_QUATERNIONBASE_PLUGIN
|
||||
# include EIGEN_QUATERNIONBASE_PLUGIN
|
||||
#endif
|
||||
@@ -225,22 +224,25 @@ struct traits<Quaternion<_Scalar,_Options> >
|
||||
typedef _Scalar Scalar;
|
||||
typedef Matrix<_Scalar,4,1,_Options> Coefficients;
|
||||
enum{
|
||||
IsAligned = bool(EIGEN_ALIGN) && ((int(_Options)&Aligned)==Aligned),
|
||||
IsAligned = internal::traits<Coefficients>::Flags & AlignedBit,
|
||||
Flags = IsAligned ? (AlignedBit | LvalueBit) : LvalueBit
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
template<typename _Scalar, int _Options>
|
||||
class Quaternion : public QuaternionBase<Quaternion<_Scalar,_Options> >{
|
||||
class Quaternion : public QuaternionBase<Quaternion<_Scalar,_Options> >
|
||||
{
|
||||
typedef QuaternionBase<Quaternion<_Scalar,_Options> > Base;
|
||||
enum { IsAligned = internal::traits<Quaternion>::IsAligned };
|
||||
|
||||
public:
|
||||
typedef _Scalar Scalar;
|
||||
|
||||
EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Quaternion)
|
||||
using Base::operator*=;
|
||||
|
||||
typedef typename internal::traits<Quaternion<Scalar,_Options> >::Coefficients Coefficients;
|
||||
typedef typename internal::traits<Quaternion>::Coefficients Coefficients;
|
||||
typedef typename Base::AngleAxisType AngleAxisType;
|
||||
|
||||
/** Default constructor leaving the quaternion uninitialized. */
|
||||
@@ -271,9 +273,16 @@ public:
|
||||
template<typename Derived>
|
||||
explicit inline Quaternion(const MatrixBase<Derived>& other) { *this = other; }
|
||||
|
||||
/** Explicit copy constructor with scalar conversion */
|
||||
template<typename OtherScalar, int OtherOptions>
|
||||
explicit inline Quaternion(const Quaternion<OtherScalar, OtherOptions>& other)
|
||||
{ m_coeffs = other.coeffs().template cast<Scalar>(); }
|
||||
|
||||
inline Coefficients& coeffs() { return m_coeffs;}
|
||||
inline const Coefficients& coeffs() const { return m_coeffs;}
|
||||
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(IsAligned)
|
||||
|
||||
protected:
|
||||
Coefficients m_coeffs;
|
||||
|
||||
@@ -673,7 +682,7 @@ QuaternionBase<Derived>::slerp(Scalar t, const QuaternionBase<OtherDerived>& oth
|
||||
Scalar scale0;
|
||||
Scalar scale1;
|
||||
|
||||
if (absD>=one)
|
||||
if(absD>=one)
|
||||
{
|
||||
scale0 = Scalar(1) - t;
|
||||
scale1 = t;
|
||||
@@ -686,9 +695,8 @@ QuaternionBase<Derived>::slerp(Scalar t, const QuaternionBase<OtherDerived>& oth
|
||||
|
||||
scale0 = internal::sin( ( Scalar(1) - t ) * theta) / sinTheta;
|
||||
scale1 = internal::sin( ( t * theta) ) / sinTheta;
|
||||
if (d<0)
|
||||
scale1 = -scale1;
|
||||
}
|
||||
if(d<0) scale1 = -scale1;
|
||||
|
||||
return Quaternion<Scalar>(scale0 * coeffs() + scale1 * other.coeffs());
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ public:
|
||||
|
||||
/** Concatenates two rotations */
|
||||
inline Rotation2D& operator*=(const Rotation2D& other)
|
||||
{ return m_angle += other.m_angle; return *this; }
|
||||
{ m_angle += other.m_angle; return *this; }
|
||||
|
||||
/** Applies the rotation to a 2D vector */
|
||||
Vector2 operator* (const Vector2& vec) const
|
||||
|
||||
@@ -37,7 +37,7 @@ struct transform_traits
|
||||
Dim = Transform::Dim,
|
||||
HDim = Transform::HDim,
|
||||
Mode = Transform::Mode,
|
||||
IsProjective = (Mode==Projective)
|
||||
IsProjective = (int(Mode)==int(Projective))
|
||||
};
|
||||
};
|
||||
|
||||
@@ -61,7 +61,7 @@ template< typename Lhs,
|
||||
typename Rhs,
|
||||
bool AnyProjective =
|
||||
transform_traits<Lhs>::IsProjective ||
|
||||
transform_traits<Lhs>::IsProjective>
|
||||
transform_traits<Rhs>::IsProjective>
|
||||
struct transform_transform_product_impl;
|
||||
|
||||
template< typename Other,
|
||||
@@ -571,7 +571,7 @@ public:
|
||||
if(int(Mode)!=int(AffineCompact))
|
||||
{
|
||||
matrix().template block<1,Dim>(Dim,0).setZero();
|
||||
matrix().coeffRef(Dim,Dim) = 1;
|
||||
matrix().coeffRef(Dim,Dim) = Scalar(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1391,6 +1391,35 @@ struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Scalar, int Dim, int LhsOptions, int RhsOptions>
|
||||
struct transform_transform_product_impl<Transform<Scalar,Dim,AffineCompact,LhsOptions>,Transform<Scalar,Dim,Projective,RhsOptions>,true >
|
||||
{
|
||||
typedef Transform<Scalar,Dim,AffineCompact,LhsOptions> Lhs;
|
||||
typedef Transform<Scalar,Dim,Projective,RhsOptions> Rhs;
|
||||
typedef Transform<Scalar,Dim,Projective> ResultType;
|
||||
static ResultType run(const Lhs& lhs, const Rhs& rhs)
|
||||
{
|
||||
ResultType res;
|
||||
res.matrix().template topRows<Dim>() = lhs.matrix() * rhs.matrix();
|
||||
res.matrix().row(Dim) = rhs.matrix().row(Dim);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Scalar, int Dim, int LhsOptions, int RhsOptions>
|
||||
struct transform_transform_product_impl<Transform<Scalar,Dim,Projective,LhsOptions>,Transform<Scalar,Dim,AffineCompact,RhsOptions>,true >
|
||||
{
|
||||
typedef Transform<Scalar,Dim,Projective,LhsOptions> Lhs;
|
||||
typedef Transform<Scalar,Dim,AffineCompact,RhsOptions> Rhs;
|
||||
typedef Transform<Scalar,Dim,Projective> ResultType;
|
||||
static ResultType run(const Lhs& lhs, const Rhs& rhs)
|
||||
{
|
||||
ResultType res(lhs.matrix().template leftCols<Dim>() * rhs.matrix());
|
||||
res.matrix().col(Dim) += lhs.matrix().col(Dim);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
#endif // EIGEN_TRANSFORM_H
|
||||
|
||||
@@ -96,7 +96,7 @@ struct quat_product<Architecture::SSE, Derived, OtherDerived, double, Aligned>
|
||||
*/
|
||||
t1 = padd(pmul(a_ww, b_xy), pmul(a_yy, b_zw));
|
||||
t2 = psub(pmul(a_zz, b_xy), pmul(a_xx, b_zw));
|
||||
#ifdef __SSE3__
|
||||
#ifdef EIGEN_VECTORIZE_SSE3
|
||||
EIGEN_UNUSED_VARIABLE(mask)
|
||||
pstore(&res.x(), _mm_addsub_pd(t1, preverse(t2)));
|
||||
#else
|
||||
@@ -110,7 +110,7 @@ struct quat_product<Architecture::SSE, Derived, OtherDerived, double, Aligned>
|
||||
*/
|
||||
t1 = psub(pmul(a_ww, b_zw), pmul(a_yy, b_xy));
|
||||
t2 = padd(pmul(a_zz, b_zw), pmul(a_xx, b_xy));
|
||||
#ifdef __SSE3__
|
||||
#ifdef EIGEN_VECTORIZE_SSE3
|
||||
EIGEN_UNUSED_VARIABLE(mask)
|
||||
pstore(&res.z(), preverse(_mm_addsub_pd(preverse(t1), t2)));
|
||||
#else
|
||||
|
||||
@@ -443,7 +443,6 @@ FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix)
|
||||
|
||||
m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
|
||||
m_maxpivot = RealScalar(0);
|
||||
RealScalar cutoff(0);
|
||||
|
||||
for(Index k = 0; k < size; ++k)
|
||||
{
|
||||
@@ -458,14 +457,7 @@ FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix)
|
||||
row_of_biggest_in_corner += k; // correct the values! since they were computed in the corner,
|
||||
col_of_biggest_in_corner += k; // need to add k to them.
|
||||
|
||||
// when k==0, biggest_in_corner is the biggest coeff absolute value in the original matrix
|
||||
if(k == 0) cutoff = biggest_in_corner * NumTraits<Scalar>::epsilon();
|
||||
|
||||
// if the pivot (hence the corner) is "zero", terminate to avoid generating nan/inf values.
|
||||
// Notice that using an exact comparison (biggest_in_corner==0) here, as Golub-van Loan do in
|
||||
// their pseudo-code, results in numerical instability! The cutoff here has been validated
|
||||
// by running the unit test 'lu' with many repetitions.
|
||||
if(biggest_in_corner < cutoff)
|
||||
if(biggest_in_corner==RealScalar(0))
|
||||
{
|
||||
// before exiting, make sure to initialize the still uninitialized transpositions
|
||||
// in a sane state without destroying what we already have.
|
||||
|
||||
@@ -55,7 +55,7 @@ struct compute_inverse_size4<Architecture::SSE, float, MatrixType, ResultType>
|
||||
|
||||
static void run(const MatrixType& matrix, ResultType& result)
|
||||
{
|
||||
EIGEN_ALIGN16 const int _Sign_PNNP[4] = { 0x00000000, 0x80000000, 0x80000000, 0x00000000 };
|
||||
EIGEN_ALIGN16 const unsigned int _Sign_PNNP[4] = { 0x00000000, 0x80000000, 0x80000000, 0x00000000 };
|
||||
|
||||
// Load the full matrix into registers
|
||||
__m128 _L1 = matrix.template packet<MatrixAlignment>( 0);
|
||||
|
||||
@@ -708,6 +708,13 @@ struct solve_retval<JacobiSVD<_MatrixType, QRPreconditioner>, Rhs>
|
||||
};
|
||||
} // end namespace internal
|
||||
|
||||
/** \svd_module
|
||||
*
|
||||
* \return the singular value decomposition of \c *this computed by two-sided
|
||||
* Jacobi transformations.
|
||||
*
|
||||
* \sa class JacobiSVD
|
||||
*/
|
||||
template<typename Derived>
|
||||
JacobiSVD<typename MatrixBase<Derived>::PlainObject>
|
||||
MatrixBase<Derived>::jacobiSvd(unsigned int computationOptions) const
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#endif
|
||||
|
||||
#if (defined __GNUC__)
|
||||
#define BTL_ASM_COMMENT(X) asm("#"X)
|
||||
#define BTL_ASM_COMMENT(X) asm("#" X)
|
||||
#else
|
||||
#define BTL_ASM_COMMENT(X)
|
||||
#endif
|
||||
|
||||
@@ -51,10 +51,10 @@ AngleAxis<float> aa(angle_in_radian, Vector3f(ax,ay,az));\endcode</td></tr>
|
||||
Quaternion<float> q; q = AngleAxis<float>(angle_in_radian, axis);\endcode</td></tr>
|
||||
<tr class="alt"><td>
|
||||
N-D Scaling</td><td>\code
|
||||
Scaling<float,2>(sx, sy)
|
||||
Scaling<float,3>(sx, sy, sz)
|
||||
Scaling<float,N>(s)
|
||||
Scaling<float,N>(vecN)\endcode</td></tr>
|
||||
Scaling(sx, sy)
|
||||
Scaling(sx, sy, sz)
|
||||
Scaling(s)
|
||||
Scaling(vecN)\endcode</td></tr>
|
||||
<tr><td>
|
||||
N-D Translation</td><td>\code
|
||||
Translation<float,2>(tx, ty)
|
||||
@@ -64,13 +64,13 @@ Translation<float,N>(vecN)\endcode</td></tr>
|
||||
<tr class="alt"><td>
|
||||
N-D \ref TutorialGeoTransform "Affine transformation"</td><td>\code
|
||||
Transform<float,N,Affine> t = concatenation_of_any_transformations;
|
||||
Transform<float,3,Affine> t = Translation3f(p) * AngleAxisf(a,axis) * Scaling3f(s);\endcode</td></tr>
|
||||
Transform<float,3,Affine> t = Translation3f(p) * AngleAxisf(a,axis) * Scaling(s);\endcode</td></tr>
|
||||
<tr><td>
|
||||
N-D Linear transformations \n
|
||||
<em class=note>(pure rotations, \n scaling, etc.)</em></td><td>\code
|
||||
Matrix<float,N> t = concatenation_of_rotations_and_scalings;
|
||||
Matrix<float,2> t = Rotation2Df(a) * Scaling2f(s);
|
||||
Matrix<float,3> t = AngleAxisf(a,axis) * Scaling3f(s);\endcode</td></tr>
|
||||
Matrix<float,2> t = Rotation2Df(a) * Scaling(s);
|
||||
Matrix<float,3> t = AngleAxisf(a,axis) * Scaling(s);\endcode</td></tr>
|
||||
</table>
|
||||
|
||||
<strong>Notes on rotations</strong>\n To transform more than a single vector the preferred
|
||||
@@ -92,8 +92,8 @@ Rotation2Df r; r = Matrix2f(..); // assumes a pure rotation matrix
|
||||
AngleAxisf aa; aa = Quaternionf(..);
|
||||
AngleAxisf aa; aa = Matrix3f(..); // assumes a pure rotation matrix
|
||||
Matrix2f m; m = Rotation2Df(..);
|
||||
Matrix3f m; m = Quaternionf(..); Matrix3f m; m = Scaling3f(..);
|
||||
Affine3f m; m = AngleAxis3f(..); Affine3f m; m = Scaling3f(..);
|
||||
Matrix3f m; m = Quaternionf(..); Matrix3f m; m = Scaling(..);
|
||||
Affine3f m; m = AngleAxis3f(..); Affine3f m; m = Scaling(..);
|
||||
Affine3f m; m = Translation3f(..); Affine3f m; m = Matrix3f(..);
|
||||
\endcode</td></tr>
|
||||
</table>
|
||||
@@ -207,10 +207,10 @@ t.scale(s);
|
||||
t.prescale(Vector_(sx,sy,..));
|
||||
t.prescale(s);
|
||||
\endcode</td><td>\code
|
||||
t *= Scaling_(sx,sy,..);
|
||||
t *= Scaling_(s);
|
||||
t = Scaling_(sx,sy,..) * t;
|
||||
t = Scaling_(s) * t;
|
||||
t *= Scaling(sx,sy,..);
|
||||
t *= Scaling(s);
|
||||
t = Scaling(sx,sy,..) * t;
|
||||
t = Scaling(s) * t;
|
||||
\endcode</td></tr>
|
||||
<tr class="alt"><td>Shear transformation \n ( \b 2D \b only ! )</td><td>\code
|
||||
t.shear(sx,sy);
|
||||
@@ -224,7 +224,7 @@ Note that in both API, any many transformations can be concatenated in a single
|
||||
t.pretranslate(..).rotate(..).translate(..).scale(..);
|
||||
\endcode</td></tr>
|
||||
<tr><td>\code
|
||||
t = Translation_(..) * t * RotationType(..) * Translation_(..) * Scaling_(..);
|
||||
t = Translation_(..) * t * RotationType(..) * Translation_(..) * Scaling(..);
|
||||
\endcode</td></tr>
|
||||
</table>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace Eigen {
|
||||
\ingroup Tutorial
|
||||
|
||||
\li \b Previous: \ref TutorialGeometry
|
||||
\li \b Next: TODO
|
||||
\li \b Next: \ref TutorialMapClass
|
||||
|
||||
\b Table \b of \b contents \n
|
||||
- \ref TutorialSparseIntro
|
||||
@@ -254,7 +254,7 @@ if(!lu_of_A.solve(b,&x)) {
|
||||
|
||||
See also the class SparseLLT, class SparseLU, and class SparseLDLT.
|
||||
|
||||
\li \b Next: TODO
|
||||
\li \b Next: \ref TutorialMapClass
|
||||
|
||||
*/
|
||||
|
||||
|
||||
96
doc/C10_TutorialMapClass.dox
Normal file
96
doc/C10_TutorialMapClass.dox
Normal file
@@ -0,0 +1,96 @@
|
||||
namespace Eigen {
|
||||
|
||||
/** \page TutorialMapClass Tutorial page 10 - Interfacing with C/C++ arrays and external libraries: the %Map class
|
||||
|
||||
\ingroup Tutorial
|
||||
|
||||
\li \b Previous: \ref TutorialSparse
|
||||
\li \b Next: \ref TODO
|
||||
|
||||
This tutorial page explains how to work with "raw" C++ arrays. This can be useful in a variety of contexts, particularly when "importing" vectors and matrices from other libraries into Eigen.
|
||||
|
||||
\b Table \b of \b contents
|
||||
- \ref TutorialMapIntroduction
|
||||
- \ref TutorialMapTypes
|
||||
- \ref TutorialMapUsing
|
||||
- \ref TutorialMapPlacementNew
|
||||
|
||||
\section TutorialMapIntroduction Introduction
|
||||
|
||||
Occasionally you may have a pre-defined array of numbers that you want to use within Eigen as a vector or matrix. While one option is to make a copy of the data, most commonly you probably want to re-use this memory as an Eigen type. Fortunately, this is very easy with the Map class.
|
||||
|
||||
\section TutorialMapTypes Map types and declaring Map variables
|
||||
|
||||
A Map object has a type defined by its Eigen equivalent:
|
||||
\code
|
||||
Map<Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime> >
|
||||
\endcode
|
||||
Note that, in this default case, a Map requires just a single template parameter.
|
||||
|
||||
To construct a Map variable, you need two other pieces of information: a pointer to the region of memory defining the array of coefficients, and the desired shape of the matrix or vector. For example, to define a matrix of \c float with sizes determined at compile time, you might do the following:
|
||||
\code
|
||||
Map<MatrixXf> mf(pf,rows,columns);
|
||||
\endcode
|
||||
where \c pf is a \c float \c * pointing to the array of memory. A fixed-size read-only vector of integers might be declared as
|
||||
\code
|
||||
Map<const Vector4i> mi(pi);
|
||||
\endcode
|
||||
where \c pi is an \c int \c *. In this case the size does not have to be passed to the constructor, because it is already specified by the Matrix/Array type.
|
||||
|
||||
Note that Map does not have a default constructor; you \em must pass a pointer to intialize the object. However, you can work around this requirement (see \ref TutorialMapPlacementNew).
|
||||
|
||||
Map is flexible enough to accomodate a variety of different data representations. There are two other (optional) template parameters:
|
||||
\code
|
||||
Map<typename MatrixType,
|
||||
int MapOptions,
|
||||
typename StrideType>
|
||||
\endcode
|
||||
\li \c MapOptions specifies whether the pointer is \c #Aligned, or \c #Unaligned. The default is \c #Unaligned.
|
||||
\li \c StrideType allows you to specify a custom layout for the memory array, using the Stride class. One example would be to specify that the data array is organized in row-major format:
|
||||
<table class="example">
|
||||
<tr><th>Example:</th><th>Output:</th></tr>
|
||||
<tr>
|
||||
<td>\include Tutorial_Map_rowmajor.cpp </td>
|
||||
<td>\verbinclude Tutorial_Map_rowmajor.out </td>
|
||||
</table>
|
||||
However, Stride is even more flexible than this; for details, see the documentation for the Map and Stride classes.
|
||||
|
||||
\section TutorialMapUsing Using Map variables
|
||||
|
||||
You can use a Map object just like any other Eigen type:
|
||||
<table class="example">
|
||||
<tr><th>Example:</th><th>Output:</th></tr>
|
||||
<tr>
|
||||
<td>\include Tutorial_Map_using.cpp </td>
|
||||
<td>\verbinclude Tutorial_Map_using.out </td>
|
||||
</table>
|
||||
|
||||
However, when writing functions taking Eigen types, it is important to realize that a Map type is \em not identical to its Dense equivalent. See \ref TopicFunctionTakingEigenTypesMultiarguments for details.
|
||||
|
||||
\section TutorialMapPlacementNew Changing the mapped array
|
||||
|
||||
It is possible to change the array of a Map object after declaration, using the C++ "placement new" syntax:
|
||||
<table class="example">
|
||||
<tr><th>Example:</th><th>Output:</th></tr>
|
||||
<tr>
|
||||
<td>\include Map_placement_new.cpp </td>
|
||||
<td>\verbinclude Map_placement_new.out </td>
|
||||
</table>
|
||||
Despite appearances, this does not invoke the memory allocator, because the syntax specifies the location for storing the result.
|
||||
|
||||
This syntax makes it possible to declare a Map object without first knowing the mapped array's location in memory:
|
||||
\code
|
||||
Map<Matrix3f> A(NULL); // don't try to use this matrix yet!
|
||||
VectorXf b(n_matrices);
|
||||
for (int i = 0; i < n_matrices; i++)
|
||||
{
|
||||
new (&A) Map<Matrix3f>(get_matrix_pointer(i));
|
||||
b(i) = A.trace();
|
||||
}
|
||||
\endcode
|
||||
|
||||
\li \b Next: \ref TODO
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
@@ -64,9 +64,14 @@ add_custom_target(
|
||||
|
||||
add_dependencies(doc-eigen-prerequisites all_snippets all_examples)
|
||||
add_dependencies(doc-unsupported-prerequisites unsupported_snippets unsupported_examples)
|
||||
|
||||
add_custom_target(doc ALL
|
||||
COMMAND doxygen Doxyfile-unsupported
|
||||
COMMAND doxygen
|
||||
COMMAND doxygen Doxyfile-unsupported # run doxygen twice to get proper eigen <=> unsupported cross references
|
||||
COMMAND ${CMAKE_COMMAND} -E rename html eigen-doc
|
||||
COMMAND ${CMAKE_COMMAND} -E tar cvfz eigen-doc/eigen-doc.tgz eigen-doc/*.html eigen-doc/*.map eigen-doc/*.png eigen-doc/*.css eigen-doc/*.js eigen-doc/*.txt eigen-doc/unsupported
|
||||
COMMAND ${CMAKE_COMMAND} -E rename eigen-doc html
|
||||
WORKING_DIRECTORY ${Eigen_BINARY_DIR}/doc)
|
||||
|
||||
add_dependencies(doc doc-eigen-prerequisites doc-unsupported-prerequisites)
|
||||
|
||||
@@ -47,9 +47,9 @@ void print_block(const DenseBase<Derived>& b, int x, int y, int r, int c)
|
||||
Prints the maximum coefficient of the array or array-expression.
|
||||
\code
|
||||
template <typename Derived>
|
||||
void print_max(const ArrayBase<Derived>& a, const ArrayBase<Derived>& b)
|
||||
void print_max_coeff(const ArrayBase<Derived> &a)
|
||||
{
|
||||
std::cout << "max: " << (a.max(b)).maxCoeff() << std::endl;
|
||||
std::cout << "max: " << a.maxCoeff() << std::endl;
|
||||
}
|
||||
\endcode
|
||||
<b> %MatrixBase Example </b><br/><br/>
|
||||
@@ -63,6 +63,21 @@ void print_inv_cond(const MatrixBase<Derived>& a)
|
||||
std::cout << "inv cond: " << sing_vals(sing_vals.size()-1) / sing_vals(0) << std::endl;
|
||||
}
|
||||
\endcode
|
||||
<b> Multiple templated arguments example </b><br/><br/>
|
||||
Calculate the Euclidean distance between two points.
|
||||
\code
|
||||
template <typename DerivedA,typename DerivedB>
|
||||
typename DerivedA::Scalar squaredist(const MatrixBase<DerivedA>& p1,const MatrixBase<DerivedB>& p2)
|
||||
{
|
||||
return (p1-p2).squaredNorm();
|
||||
}
|
||||
\endcode
|
||||
Notice that we used two template parameters, one per argument. This permits the function to handle inputs of different types, e.g.,
|
||||
\code
|
||||
squaredist(v1,2*v2)
|
||||
\endcode
|
||||
where the first argument \c v1 is a vector and the second argument \c 2*v2 is an expression.
|
||||
<br/><br/>
|
||||
|
||||
These examples are just intended to give the reader a first impression of how functions can be written which take a plain and constant Matrix or Array argument. They are also intended to give the reader an idea about the most common base classes being the optimal candidates for functions. In the next section we will look in more detail at an example and the different ways it can be implemented, while discussing each implementation's problems and advantages. For the discussion below, Matrix and Array as well as MatrixBase and ArrayBase can be exchanged and all arguments still hold.
|
||||
|
||||
@@ -128,6 +143,8 @@ The implementation above does now not only work with temporary expressions but i
|
||||
|
||||
\b Note: The const cast hack will only work with templated functions. It will not work with the MatrixXf implementation because it is not possible to cast a Block expression to a Matrix reference!
|
||||
|
||||
|
||||
|
||||
\section TopicResizingInGenericImplementations How to resize matrices in generic implementations?
|
||||
|
||||
One might think we are done now, right? This is not completely true because in order for our covariance function to be generically applicable, we want the follwing code to work
|
||||
|
||||
@@ -8,7 +8,7 @@ o /** \mainpage Eigen
|
||||
| \ref QuickRefPage "Short reference"
|
||||
</div>
|
||||
|
||||
This is the API documentation for Eigen3.
|
||||
This is the API documentation for Eigen3. You can <a href="eigen-doc.tgz">download</a> it as a tgz archive for offline reading.
|
||||
|
||||
Eigen2 users: here is a \ref Eigen2ToEigen3 guide to help porting your application.
|
||||
|
||||
@@ -27,6 +27,7 @@ For a first contact with Eigen, the best place is to have a look at the \ref Get
|
||||
- \ref TutorialReductionsVisitorsBroadcasting
|
||||
- \ref TutorialGeometry
|
||||
- \ref TutorialSparse
|
||||
- \ref TutorialMapClass
|
||||
- \ref QuickRefPage
|
||||
- <b>Advanced topics</b>
|
||||
- \ref TopicAliasing
|
||||
|
||||
@@ -645,11 +645,11 @@ m3 -= s1 * m3.adjoint() * m1.selfadjointView<Eigen::Lower>();\endcode
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
Rank 1 and rank K update: \n
|
||||
\f$ upper(M_1) \mathrel{{+}{=}} s_1 M_2^* M_2 \f$ \n
|
||||
\f$ lower(M_1) \mathbin{{-}{=}} M_2 M_2^* \f$
|
||||
\f$ upper(M_1) \mathrel{{+}{=}} s_1 M_2 M_2^* \f$ \n
|
||||
\f$ lower(M_1) \mathbin{{-}{=}} M_2^* M_2 \f$
|
||||
</td><td>\n \code
|
||||
M1.selfadjointView<Eigen::Upper>().rankUpdate(M2,s1);
|
||||
m1.selfadjointView<Eigen::Lower>().rankUpdate(m2.adjoint(),-1); \endcode
|
||||
M1.selfadjointView<Eigen::Lower>().rankUpdate(M2.adjoint(),-1); \endcode
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
Rank 2 update: (\f$ M \mathrel{{+}{=}} s u v^* + s v u^* \f$)
|
||||
|
||||
@@ -10,8 +10,9 @@ int main()
|
||||
A << 1, 2, 2, 3;
|
||||
cout << "Here is the matrix A:\n" << A << endl;
|
||||
SelfAdjointEigenSolver<Matrix2f> eigensolver(A);
|
||||
if (eigensolver.info() != Success) abort();
|
||||
cout << "The eigenvalues of A are:\n" << eigensolver.eigenvalues() << endl;
|
||||
cout << "Here's a matrix whose columns are eigenvectors of A "
|
||||
cout << "Here's a matrix whose columns are eigenvectors of A \n"
|
||||
<< "corresponding to these eigenvalues:\n"
|
||||
<< eigensolver.eigenvectors() << endl;
|
||||
}
|
||||
|
||||
7
doc/snippets/Tutorial_Map_rowmajor.cpp
Normal file
7
doc/snippets/Tutorial_Map_rowmajor.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
int array[8];
|
||||
for(int i = 0; i < 8; ++i) array[i] = i;
|
||||
cout << "Column-major:\n" << Map<Matrix<int,2,4> >(array) << endl;
|
||||
cout << "Row-major:\n" << Map<Matrix<int,2,4,RowMajor> >(array) << endl;
|
||||
cout << "Row-major using stride:\n" <<
|
||||
Map<Matrix<int,2,4>, Unaligned, Stride<1,4> >(array) << endl;
|
||||
|
||||
21
doc/snippets/Tutorial_Map_using.cpp
Normal file
21
doc/snippets/Tutorial_Map_using.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
typedef Matrix<float,1,Dynamic> MatrixType;
|
||||
typedef Map<MatrixType> MapType;
|
||||
typedef Map<const MatrixType> MapTypeConst; // a read-only map
|
||||
const int n_dims = 5;
|
||||
|
||||
MatrixType m1(n_dims), m2(n_dims);
|
||||
m1.setRandom();
|
||||
m2.setRandom();
|
||||
float *p = &m2(0); // get the address storing the data for m2
|
||||
MapType m2map(p,m2.size()); // m2map shares data with m2
|
||||
MapTypeConst m2mapconst(p,m2.size()); // a read-only accessor for m2
|
||||
|
||||
cout << "m1: " << m1 << endl;
|
||||
cout << "m2: " << m2 << endl;
|
||||
cout << "Squared euclidean distance: " << (m1-m2).squaredNorm() << endl;
|
||||
cout << "Squared euclidean distance, using map: " <<
|
||||
(m1-m2map).squaredNorm() << endl;
|
||||
m2map(3) = 7; // this will change m2, since they share the same array
|
||||
cout << "Updated m2: " << m2 << endl;
|
||||
cout << "m2 coefficient 2, constant accessor: " << m2mapconst(2) << endl;
|
||||
/* m2mapconst(2) = 5; */ // this yields a compile-time error
|
||||
@@ -1,64 +0,0 @@
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
/** \defgroup Unsupported_modules Unsupported modules
|
||||
*
|
||||
* The unsupported modules are contributions from various users. They are
|
||||
* provided "as is", without any support. Nevertheless, some of them are
|
||||
* subject to be included in Eigen in the future.
|
||||
*/
|
||||
|
||||
// please list here all unsupported modules
|
||||
|
||||
/** \ingroup Unsupported_modules
|
||||
* \defgroup AdolcForward_Module */
|
||||
|
||||
/** \ingroup Unsupported_modules
|
||||
* \defgroup AlignedVector3_Module */
|
||||
|
||||
/** \ingroup Unsupported_modules
|
||||
* \defgroup AutoDiff_Module */
|
||||
|
||||
/** \ingroup Unsupported_modules
|
||||
* \defgroup BVH_Module */
|
||||
|
||||
/** \ingroup Unsupported_modules
|
||||
* \defgroup FFT_Module */
|
||||
|
||||
/** \ingroup Unsupported_modules
|
||||
* \defgroup IterativeSolvers_Module */
|
||||
|
||||
/** \ingroup Unsupported_modules
|
||||
* \defgroup MatrixFunctions_Module */
|
||||
|
||||
/** \ingroup Unsupported_modules
|
||||
* \defgroup MoreVectorization */
|
||||
|
||||
/** \ingroup Unsupported_modules
|
||||
* \defgroup NonLinearOptimization_Module */
|
||||
|
||||
/** \ingroup Unsupported_modules
|
||||
* \defgroup NumericalDiff_Module */
|
||||
|
||||
/** \ingroup Unsupported_modules
|
||||
* \defgroup Polynomials_Module */
|
||||
|
||||
/** \ingroup Unsupported_modules
|
||||
* \defgroup Skyline_Module */
|
||||
|
||||
/** \ingroup Unsupported_modules
|
||||
* \defgroup CholmodSupport_Module */
|
||||
|
||||
/** \ingroup Unsupported_modules
|
||||
* \defgroup SuperLUSupport_Module */
|
||||
|
||||
/** \ingroup Unsupported_modules
|
||||
* \defgroup UmfPackSupport_Module */
|
||||
|
||||
/** \ingroup Unsupported_modules
|
||||
* \defgroup SparseExtra_Module */
|
||||
|
||||
/** \ingroup Unsupported_modules
|
||||
* \defgroup MpfrcxxSupport_Module */
|
||||
|
||||
} // namespace Eigen
|
||||
@@ -8,14 +8,12 @@ USER=${USER:-'orzel'}
|
||||
#ulimit -v 1024000
|
||||
|
||||
# step 1 : build
|
||||
# todo if 'build is not there, create one:
|
||||
mkdir build -p
|
||||
(cd build && cmake .. && make doc) || { echo "make failed"; exit 1; }
|
||||
#todo: n+1 where n = number of cpus
|
||||
|
||||
#step 2 : upload
|
||||
# (the '/' at the end of path are very important, see rsync documentation)
|
||||
rsync -az build/doc/html/ $USER@ssh.tuxfamily.org:eigen/eigen.tuxfamily.org-web/htdocs/dox-3.0/ || { echo "upload failed"; exit 1; }
|
||||
# (the '/' at the end of path is very important, see rsync documentation)
|
||||
rsync -az --no-p --delete build/doc/html/ $USER@ssh.tuxfamily.org:eigen/eigen.tuxfamily.org-web/htdocs/dox-3.0/ || { echo "upload failed"; exit 1; }
|
||||
|
||||
echo "Uploaded successfully"
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ ei_add_test(nullary)
|
||||
ei_add_test(nesting_ops "${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
ei_add_test(zerosized)
|
||||
ei_add_test(dontalign)
|
||||
|
||||
ei_add_test(sizeoverflow)
|
||||
ei_add_test(prec_inverse_4x4)
|
||||
|
||||
string(TOLOWER "${CMAKE_CXX_COMPILER}" cmake_cxx_compiler_tolower)
|
||||
|
||||
@@ -124,6 +124,11 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
|
||||
MatrixType neg = -symmLo;
|
||||
chollo.compute(neg);
|
||||
VERIFY(chollo.info()==NumericalIssue);
|
||||
|
||||
VERIFY_IS_APPROX(MatrixType(chollo.matrixL().transpose().conjugate()), MatrixType(chollo.matrixU()));
|
||||
VERIFY_IS_APPROX(MatrixType(chollo.matrixU().transpose().conjugate()), MatrixType(chollo.matrixL()));
|
||||
VERIFY_IS_APPROX(MatrixType(cholup.matrixL().transpose().conjugate()), MatrixType(cholup.matrixU()));
|
||||
VERIFY_IS_APPROX(MatrixType(cholup.matrixU().transpose().conjugate()), MatrixType(cholup.matrixL()));
|
||||
}
|
||||
|
||||
// LDLT
|
||||
@@ -152,6 +157,11 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
|
||||
matX = ldltup.solve(matB);
|
||||
VERIFY_IS_APPROX(symm * matX, matB);
|
||||
|
||||
VERIFY_IS_APPROX(MatrixType(ldltlo.matrixL().transpose().conjugate()), MatrixType(ldltlo.matrixU()));
|
||||
VERIFY_IS_APPROX(MatrixType(ldltlo.matrixU().transpose().conjugate()), MatrixType(ldltlo.matrixL()));
|
||||
VERIFY_IS_APPROX(MatrixType(ldltup.matrixL().transpose().conjugate()), MatrixType(ldltup.matrixU()));
|
||||
VERIFY_IS_APPROX(MatrixType(ldltup.matrixU().transpose().conjugate()), MatrixType(ldltup.matrixL()));
|
||||
|
||||
if(MatrixType::RowsAtCompileTime==Dynamic)
|
||||
{
|
||||
// note : each inplace permutation requires a small temporary vector (mask)
|
||||
|
||||
@@ -28,6 +28,35 @@
|
||||
#include <Eigen/LU>
|
||||
#include <Eigen/SVD>
|
||||
|
||||
template<typename T> T bounded_acos(T v)
|
||||
{
|
||||
using std::acos;
|
||||
using std::min;
|
||||
using std::max;
|
||||
return acos((max)(T(-1),(min)(v,T(1))));
|
||||
}
|
||||
|
||||
template<typename QuatType> void check_slerp(const QuatType& q0, const QuatType& q1)
|
||||
{
|
||||
typedef typename QuatType::Scalar Scalar;
|
||||
typedef Matrix<Scalar,3,1> VectorType;
|
||||
typedef AngleAxis<Scalar> AA;
|
||||
|
||||
Scalar largeEps = test_precision<Scalar>();
|
||||
|
||||
Scalar theta_tot = AA(q1*q0.inverse()).angle();
|
||||
if(theta_tot>M_PI)
|
||||
theta_tot = 2.*M_PI-theta_tot;
|
||||
for(Scalar t=0; t<=1.001; t+=0.1)
|
||||
{
|
||||
QuatType q = q0.slerp(t,q1);
|
||||
Scalar theta = AA(q*q0.inverse()).angle();
|
||||
VERIFY(internal::abs(q.norm() - 1) < largeEps);
|
||||
if(theta_tot==0) VERIFY(theta_tot==0);
|
||||
else VERIFY(internal::abs(theta/theta_tot - t) < largeEps);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Scalar, int Options> void quaternion(void)
|
||||
{
|
||||
/* this test covers the following files:
|
||||
@@ -36,6 +65,7 @@ template<typename Scalar, int Options> void quaternion(void)
|
||||
|
||||
typedef Matrix<Scalar,3,3> Matrix3;
|
||||
typedef Matrix<Scalar,3,1> Vector3;
|
||||
typedef Matrix<Scalar,4,1> Vector4;
|
||||
typedef Quaternion<Scalar,Options> Quaternionx;
|
||||
typedef AngleAxis<Scalar> AngleAxisx;
|
||||
|
||||
@@ -50,7 +80,8 @@ template<typename Scalar, int Options> void quaternion(void)
|
||||
v2 = Vector3::Random(),
|
||||
v3 = Vector3::Random();
|
||||
|
||||
Scalar a = internal::random<Scalar>(-Scalar(M_PI), Scalar(M_PI));
|
||||
Scalar a = internal::random<Scalar>(-Scalar(M_PI), Scalar(M_PI)),
|
||||
b = internal::random<Scalar>(-Scalar(M_PI), Scalar(M_PI));
|
||||
|
||||
// Quaternion: Identity(), setIdentity();
|
||||
Quaternionx q1, q2;
|
||||
@@ -120,6 +151,26 @@ template<typename Scalar, int Options> void quaternion(void)
|
||||
VERIFY_IS_APPROX(q1f.template cast<Scalar>(),q1);
|
||||
Quaternion<double> q1d = q1.template cast<double>();
|
||||
VERIFY_IS_APPROX(q1d.template cast<Scalar>(),q1);
|
||||
|
||||
// test bug 369 - improper alignment.
|
||||
Quaternionx *q = new Quaternionx;
|
||||
delete q;
|
||||
|
||||
q1 = AngleAxisx(a, v0.normalized());
|
||||
q2 = AngleAxisx(b, v1.normalized());
|
||||
check_slerp(q1,q2);
|
||||
|
||||
q1 = AngleAxisx(b, v1.normalized());
|
||||
q2 = AngleAxisx(b+M_PI, v1.normalized());
|
||||
check_slerp(q1,q2);
|
||||
|
||||
q1 = AngleAxisx(b, v1.normalized());
|
||||
q2 = AngleAxisx(-b, -v1.normalized());
|
||||
check_slerp(q1,q2);
|
||||
|
||||
q1.coeffs() = Vector4::Random().normalized();
|
||||
q2.coeffs() = -q1.coeffs();
|
||||
check_slerp(q1,q2);
|
||||
}
|
||||
|
||||
template<typename Scalar> void mapQuaternion(void){
|
||||
@@ -191,7 +242,6 @@ template<typename PlainObjectType> void check_const_correctness(const PlainObjec
|
||||
VERIFY( !(Map<ConstPlainObjectType, Aligned>::Flags & LvalueBit) );
|
||||
}
|
||||
|
||||
|
||||
void test_geo_quaternion()
|
||||
{
|
||||
for(int i = 0; i < g_repeat; i++) {
|
||||
|
||||
@@ -448,6 +448,29 @@ template<typename Scalar> void transform_alignment()
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename Scalar, int Dim, int Options> void transform_products()
|
||||
{
|
||||
typedef Matrix<Scalar,Dim+1,Dim+1> Mat;
|
||||
typedef Transform<Scalar,Dim,Projective,Options> Proj;
|
||||
typedef Transform<Scalar,Dim,Affine,Options> Aff;
|
||||
typedef Transform<Scalar,Dim,AffineCompact,Options> AffC;
|
||||
|
||||
Proj p; p.matrix().setRandom();
|
||||
Aff a; a.linear().setRandom(); a.translation().setRandom();
|
||||
AffC ac = a;
|
||||
|
||||
Mat p_m(p.matrix()), a_m(a.matrix());
|
||||
|
||||
VERIFY_IS_APPROX((p*p).matrix(), p_m*p_m);
|
||||
VERIFY_IS_APPROX((a*a).matrix(), a_m*a_m);
|
||||
VERIFY_IS_APPROX((p*a).matrix(), p_m*a_m);
|
||||
VERIFY_IS_APPROX((a*p).matrix(), a_m*p_m);
|
||||
VERIFY_IS_APPROX((ac*a).matrix(), a_m*a_m);
|
||||
VERIFY_IS_APPROX((a*ac).matrix(), a_m*a_m);
|
||||
VERIFY_IS_APPROX((p*ac).matrix(), p_m*a_m);
|
||||
VERIFY_IS_APPROX((ac*p).matrix(), a_m*p_m);
|
||||
}
|
||||
|
||||
void test_geo_transformations()
|
||||
{
|
||||
for(int i = 0; i < g_repeat; i++) {
|
||||
@@ -470,5 +493,9 @@ void test_geo_transformations()
|
||||
|
||||
CALL_SUBTEST_6(( transformations<double,Projective,RowMajor|AutoAlign>() ));
|
||||
CALL_SUBTEST_6(( transformations<double,Projective,RowMajor|DontAlign>() ));
|
||||
|
||||
|
||||
CALL_SUBTEST_7(( transform_products<double,3,RowMajor|AutoAlign>() ));
|
||||
CALL_SUBTEST_7(( transform_products<float,2,AutoAlign>() ));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ namespace Eigen
|
||||
} \
|
||||
else if (Eigen::internal::push_assert) \
|
||||
{ \
|
||||
eigen_assert_list.push_back(std::string(EI_PP_MAKE_STRING(__FILE__)" ("EI_PP_MAKE_STRING(__LINE__)") : "#a) ); \
|
||||
eigen_assert_list.push_back(std::string(EI_PP_MAKE_STRING(__FILE__) " (" EI_PP_MAKE_STRING(__LINE__) ") : " #a) ); \
|
||||
}
|
||||
|
||||
#define VERIFY_RAISES_ASSERT(a) \
|
||||
|
||||
@@ -25,6 +25,25 @@
|
||||
#define EIGEN_NO_STATIC_ASSERT
|
||||
#include "product.h"
|
||||
|
||||
// regression test for bug 447
|
||||
void product1x1()
|
||||
{
|
||||
Matrix<float,1,3> matAstatic;
|
||||
Matrix<float,3,1> matBstatic;
|
||||
matAstatic.setRandom();
|
||||
matBstatic.setRandom();
|
||||
VERIFY_IS_APPROX( (matAstatic * matBstatic).coeff(0,0),
|
||||
matAstatic.cwiseProduct(matBstatic.transpose()).sum() );
|
||||
|
||||
MatrixXf matAdynamic(1,3);
|
||||
MatrixXf matBdynamic(3,1);
|
||||
matAdynamic.setRandom();
|
||||
matBdynamic.setRandom();
|
||||
VERIFY_IS_APPROX( (matAdynamic * matBdynamic).coeff(0,0),
|
||||
matAdynamic.cwiseProduct(matBdynamic.transpose()).sum() );
|
||||
}
|
||||
|
||||
|
||||
void test_product_small()
|
||||
{
|
||||
for(int i = 0; i < g_repeat; i++) {
|
||||
@@ -33,6 +52,7 @@ void test_product_small()
|
||||
CALL_SUBTEST_3( product(Matrix3d()) );
|
||||
CALL_SUBTEST_4( product(Matrix4d()) );
|
||||
CALL_SUBTEST_5( product(Matrix4f()) );
|
||||
CALL_SUBTEST_6( product1x1() );
|
||||
}
|
||||
|
||||
#ifdef EIGEN_TEST_PART_6
|
||||
|
||||
81
test/sizeoverflow.cpp
Normal file
81
test/sizeoverflow.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
//
|
||||
// Eigen is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// Alternatively, you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License and a copy of the GNU General Public License along with
|
||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#define VERIFY_THROWS_BADALLOC(a) { \
|
||||
bool threw = false; \
|
||||
try { \
|
||||
a; \
|
||||
} \
|
||||
catch (std::bad_alloc&) { threw = true; } \
|
||||
VERIFY(threw && "should have thrown bad_alloc: " #a); \
|
||||
}
|
||||
|
||||
typedef DenseIndex Index;
|
||||
|
||||
template<typename MatrixType>
|
||||
void triggerMatrixBadAlloc(Index rows, Index cols)
|
||||
{
|
||||
VERIFY_THROWS_BADALLOC( MatrixType m(rows, cols) );
|
||||
VERIFY_THROWS_BADALLOC( MatrixType m; m.resize(rows, cols) );
|
||||
VERIFY_THROWS_BADALLOC( MatrixType m; m.conservativeResize(rows, cols) );
|
||||
}
|
||||
|
||||
template<typename VectorType>
|
||||
void triggerVectorBadAlloc(Index size)
|
||||
{
|
||||
VERIFY_THROWS_BADALLOC( VectorType v(size) );
|
||||
VERIFY_THROWS_BADALLOC( VectorType v; v.resize(size) );
|
||||
VERIFY_THROWS_BADALLOC( VectorType v; v.conservativeResize(size) );
|
||||
}
|
||||
|
||||
void test_sizeoverflow()
|
||||
{
|
||||
// there are 2 levels of overflow checking. first in PlainObjectBase.h we check for overflow in rows*cols computations.
|
||||
// this is tested in tests of the form times_itself_gives_0 * times_itself_gives_0
|
||||
// Then in Memory.h we check for overflow in size * sizeof(T) computations.
|
||||
// this is tested in tests of the form times_4_gives_0 * sizeof(float)
|
||||
|
||||
size_t times_itself_gives_0 = size_t(1) << (8 * sizeof(Index) / 2);
|
||||
VERIFY(times_itself_gives_0 * times_itself_gives_0 == 0);
|
||||
|
||||
size_t times_4_gives_0 = size_t(1) << (8 * sizeof(Index) - 2);
|
||||
VERIFY(times_4_gives_0 * 4 == 0);
|
||||
|
||||
size_t times_8_gives_0 = size_t(1) << (8 * sizeof(Index) - 3);
|
||||
VERIFY(times_8_gives_0 * 8 == 0);
|
||||
|
||||
triggerMatrixBadAlloc<MatrixXf>(times_itself_gives_0, times_itself_gives_0);
|
||||
triggerMatrixBadAlloc<MatrixXf>(times_itself_gives_0 / 4, times_itself_gives_0);
|
||||
triggerMatrixBadAlloc<MatrixXf>(times_4_gives_0, 1);
|
||||
|
||||
triggerMatrixBadAlloc<MatrixXd>(times_itself_gives_0, times_itself_gives_0);
|
||||
triggerMatrixBadAlloc<MatrixXd>(times_itself_gives_0 / 8, times_itself_gives_0);
|
||||
triggerMatrixBadAlloc<MatrixXd>(times_8_gives_0, 1);
|
||||
|
||||
triggerVectorBadAlloc<VectorXf>(times_4_gives_0);
|
||||
|
||||
triggerVectorBadAlloc<VectorXd>(times_8_gives_0);
|
||||
}
|
||||
@@ -35,7 +35,8 @@
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
/** \defgroup MPRealSupport_Module MPFRC++ Support module
|
||||
/** \ingroup Unsupported_modules
|
||||
* \defgroup MPRealSupport_Module MPFRC++ Support module
|
||||
*
|
||||
* \code
|
||||
* #include <Eigen/MPRealSupport>
|
||||
|
||||
@@ -69,7 +69,7 @@ struct get_boxes_helper<ObjectList, VolumeList, int> {
|
||||
*
|
||||
* \param _Scalar The underlying scalar type of the bounding boxes
|
||||
* \param _Dim The dimension of the space in which the hierarchy lives
|
||||
* \param _Object The object type that lives in the hierarchy. It must have value semantics. Either internal::bounding_box(_Object) must
|
||||
* \param _Object The object type that lives in the hierarchy. It must have value semantics. Either bounding_box(_Object) must
|
||||
* be defined and return an AlignedBox<_Scalar, _Dim> or bounding boxes must be provided to the tree initializer.
|
||||
*
|
||||
* This class provides a simple (as opposed to optimized) implementation of a bounding volume hierarchy analogous to a Kd-tree.
|
||||
@@ -92,14 +92,14 @@ public:
|
||||
|
||||
KdBVH() {}
|
||||
|
||||
/** Given an iterator range over \a Object references, constructs the BVH. Requires that internal::bounding_box(Object) return a Volume. */
|
||||
/** Given an iterator range over \a Object references, constructs the BVH. Requires that bounding_box(Object) return a Volume. */
|
||||
template<typename Iter> KdBVH(Iter begin, Iter end) { init(begin, end, 0, 0); } //int is recognized by init as not being an iterator type
|
||||
|
||||
/** Given an iterator range over \a Object references and an iterator range over their bounding boxes, constructs the BVH */
|
||||
template<typename OIter, typename BIter> KdBVH(OIter begin, OIter end, BIter boxBegin, BIter boxEnd) { init(begin, end, boxBegin, boxEnd); }
|
||||
|
||||
/** Given an iterator range over \a Object references, constructs the BVH, overwriting whatever is in there currently.
|
||||
* Requires that internal::bounding_box(Object) return a Volume. */
|
||||
* Requires that bounding_box(Object) return a Volume. */
|
||||
template<typename Iter> void init(Iter begin, Iter end) { init(begin, end, 0, 0); }
|
||||
|
||||
/** Given an iterator range over \a Object references and an iterator range over their bounding boxes,
|
||||
|
||||
@@ -640,7 +640,7 @@ LevenbergMarquardt<FunctorType,Scalar>::lmdif1(
|
||||
|
||||
NumericalDiff<FunctorType> numDiff(functor);
|
||||
// embedded LevenbergMarquardt
|
||||
LevenbergMarquardt<NumericalDiff<FunctorType> > lm(numDiff);
|
||||
LevenbergMarquardt<NumericalDiff<FunctorType>, Scalar > lm(numDiff);
|
||||
lm.parameters.ftol = tol;
|
||||
lm.parameters.xtol = tol;
|
||||
lm.parameters.maxfev = 200*(n+1);
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
template<typename T0, typename T1>
|
||||
NumericalDiff(const T0& a0, const T1& a1) : Functor(a0, a1), epsfcn(0) {}
|
||||
template<typename T0, typename T1, typename T2>
|
||||
NumericalDiff(const T0& a0, const T1& a1, const T1& a2) : Functor(a0, a1, a2), epsfcn(0) {}
|
||||
NumericalDiff(const T0& a0, const T1& a1, const T2& a2) : Functor(a0, a1, a2), epsfcn(0) {}
|
||||
|
||||
enum {
|
||||
InputsAtCompileTime = Functor::InputsAtCompileTime,
|
||||
|
||||
@@ -104,7 +104,7 @@ class SparseLU
|
||||
void setOrderingMethod(int m)
|
||||
{
|
||||
eigen_assert( (m&~OrderingMask) == 0 && m!=0 && "invalid ordering method");
|
||||
m_flags = m_flags&~OrderingMask | m&OrderingMask;
|
||||
m_flags = (m_flags & ~OrderingMask) | (m & OrderingMask);
|
||||
}
|
||||
|
||||
int orderingMethod() const
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
namespace Eigen {
|
||||
|
||||
o /** \mainpage Eigen's unsupported modules
|
||||
/** \mainpage Eigen's unsupported modules
|
||||
|
||||
This is the API documentation for Eigen's unsupported modules.
|
||||
|
||||
These modules are contributions from various users. They are provided "as is", without any support.
|
||||
|
||||
Click on the \e Modules tab at the top of this page to get a list of all unsupported modules.
|
||||
|
||||
Don't miss the <a href="..//index.html">official Eigen documentation</a>.
|
||||
|
||||
|
||||
\defgroup Unsupported_modules Unsupported modules
|
||||
|
||||
The unsupported modules are contributions from various users. They are
|
||||
provided "as is", without any support. Nevertheless, some of them are
|
||||
subject to be included in Eigen in the future.
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@@ -24,9 +24,15 @@
|
||||
|
||||
#include "main.h"
|
||||
#include <Eigen/StdVector>
|
||||
#include <Eigen/Geometry>
|
||||
#include <unsupported/Eigen/BVH>
|
||||
|
||||
inline double SQR(double x) { return x * x; }
|
||||
namespace Eigen {
|
||||
|
||||
template<typename Scalar, int Dim> AlignedBox<Scalar, Dim> bounding_box(const Matrix<Scalar, Dim, 1> &v) { return AlignedBox<Scalar, Dim>(v); }
|
||||
|
||||
}
|
||||
|
||||
|
||||
template<int Dim>
|
||||
struct Ball
|
||||
@@ -41,16 +47,10 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(double, Dim)
|
||||
VectorType center;
|
||||
double radius;
|
||||
};
|
||||
|
||||
namespace Eigen {
|
||||
namespace internal {
|
||||
|
||||
template<typename Scalar, int Dim> AlignedBox<Scalar, Dim> bounding_box(const Matrix<Scalar, Dim, 1> &v) { return AlignedBox<Scalar, Dim>(v); }
|
||||
template<int Dim> AlignedBox<double, Dim> bounding_box(const Ball<Dim> &b)
|
||||
{ return AlignedBox<double, Dim>(b.center.array() - b.radius, b.center.array() + b.radius); }
|
||||
|
||||
} // end namespace internal
|
||||
}
|
||||
inline double SQR(double x) { return x * x; }
|
||||
|
||||
template<int Dim>
|
||||
struct BallPointStuff //this class provides functions to be both an intersector and a minimizer, both for a ball and a point and for two trees
|
||||
|
||||
Reference in New Issue
Block a user