From e40f6752bda0824f2f44376d46879972da17f728 Mon Sep 17 00:00:00 2001 From: jonathan Date: Mon, 21 Mar 2011 00:44:22 +0000 Subject: [PATCH] OP-191: Merge from full-calibration branch. Import Eigen 2.0.15 to the GCS. Add the bits that eclipse missed the first time around. git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@3052 ebee16cc-31ac-478f-84a7-5cbb03baadba --- .../src/libs/eigen/Eigen/src/CMakeLists.txt | 9 + .../eigen/Eigen/src/Core/arch/CMakeLists.txt | 2 + .../eigen/Eigen/src/Core/util/CMakeLists.txt | 6 + .../eigen/Eigen/src/Core/util/Constants.h | 254 +++++++++++ .../Eigen/src/Core/util/DisableMSVCWarnings.h | 5 + .../Eigen/src/Core/util/EnableMSVCWarnings.h | 4 + .../Eigen/src/Core/util/ForwardDeclarations.h | 125 ++++++ .../libs/eigen/Eigen/src/Core/util/Macros.h | 276 ++++++++++++ .../libs/eigen/Eigen/src/Core/util/Memory.h | 417 ++++++++++++++++++ .../src/libs/eigen/Eigen/src/Core/util/Meta.h | 183 ++++++++ .../eigen/Eigen/src/Core/util/StaticAssert.h | 149 +++++++ .../eigen/Eigen/src/Core/util/XprHelper.h | 242 ++++++++++ 12 files changed, 1672 insertions(+) create mode 100644 ground/openpilotgcs/src/libs/eigen/Eigen/src/CMakeLists.txt create mode 100644 ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/arch/CMakeLists.txt create mode 100644 ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/CMakeLists.txt create mode 100644 ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/Constants.h create mode 100644 ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/DisableMSVCWarnings.h create mode 100644 ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/EnableMSVCWarnings.h create mode 100644 ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/ForwardDeclarations.h create mode 100644 ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/Macros.h create mode 100644 ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/Memory.h create mode 100644 ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/Meta.h create mode 100644 ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/StaticAssert.h create mode 100644 ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/XprHelper.h diff --git a/ground/openpilotgcs/src/libs/eigen/Eigen/src/CMakeLists.txt b/ground/openpilotgcs/src/libs/eigen/Eigen/src/CMakeLists.txt new file mode 100644 index 000000000..e6832e850 --- /dev/null +++ b/ground/openpilotgcs/src/libs/eigen/Eigen/src/CMakeLists.txt @@ -0,0 +1,9 @@ +ADD_SUBDIRECTORY(Core) +ADD_SUBDIRECTORY(LU) +ADD_SUBDIRECTORY(QR) +ADD_SUBDIRECTORY(SVD) +ADD_SUBDIRECTORY(Cholesky) +ADD_SUBDIRECTORY(Array) +ADD_SUBDIRECTORY(Geometry) +ADD_SUBDIRECTORY(LeastSquares) +ADD_SUBDIRECTORY(Sparse) diff --git a/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/arch/CMakeLists.txt b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/arch/CMakeLists.txt new file mode 100644 index 000000000..8ddba284e --- /dev/null +++ b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/arch/CMakeLists.txt @@ -0,0 +1,2 @@ +ADD_SUBDIRECTORY(SSE) +ADD_SUBDIRECTORY(AltiVec) \ No newline at end of file diff --git a/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/CMakeLists.txt b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/CMakeLists.txt new file mode 100644 index 000000000..eb7b2b6eb --- /dev/null +++ b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/CMakeLists.txt @@ -0,0 +1,6 @@ +FILE(GLOB Eigen_Core_util_SRCS "*.h") + +INSTALL(FILES + ${Eigen_Core_util_SRCS} + DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Core/util + ) diff --git a/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/Constants.h b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/Constants.h new file mode 100644 index 000000000..296c3caa5 --- /dev/null +++ b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/Constants.h @@ -0,0 +1,254 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// 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 . + +#ifndef EIGEN_CONSTANTS_H +#define EIGEN_CONSTANTS_H + +/** This value means that a quantity is not known at compile-time, and that instead the value is + * stored in some runtime variable. + * + * Explanation for the choice of this value: + * - It should be positive and larger than any reasonable compile-time-fixed number of rows or columns. + * This allows to simplify many compile-time conditions throughout Eigen. + * - It should be smaller than the sqrt of INT_MAX. Indeed, we often multiply a number of rows with a number + * of columns in order to compute a number of coefficients. Even if we guard that with an "if" checking whether + * the values are Dynamic, we still get a compiler warning "integer overflow". So the only way to get around + * it would be a meta-selector. Doing this everywhere would reduce code readability and lenghten compilation times. + * Also, disabling compiler warnings for integer overflow, sounds like a bad idea. + * + * If you wish to port Eigen to a platform where sizeof(int)==2, it is perfectly possible to set Dynamic to, say, 100. + */ +const int Dynamic = 10000; + +/** This value means +Infinity; it is currently used only as the p parameter to MatrixBase::lpNorm(). + * The value Infinity there means the L-infinity norm. + */ +const int Infinity = -1; + +/** \defgroup flags flags + * \ingroup Core_Module + * + * These are the possible bits which can be OR'ed to constitute the flags of a matrix or + * expression. + * + * It is important to note that these flags are a purely compile-time notion. They are a compile-time property of + * an expression type, implemented as enum's. They are not stored in memory at runtime, and they do not incur any + * runtime overhead. + * + * \sa MatrixBase::Flags + */ + +/** \ingroup flags + * + * for a matrix, this means that the storage order is row-major. + * If this bit is not set, the storage order is column-major. + * For an expression, this determines the storage order of + * the matrix created by evaluation of that expression. */ +const unsigned int RowMajorBit = 0x1; + +/** \ingroup flags + * + * means the expression should be evaluated by the calling expression */ +const unsigned int EvalBeforeNestingBit = 0x2; + +/** \ingroup flags + * + * means the expression should be evaluated before any assignement */ +const unsigned int EvalBeforeAssigningBit = 0x4; + +/** \ingroup flags + * + * Short version: means the expression might be vectorized + * + * Long version: means that the coefficients can be handled by packets + * and start at a memory location whose alignment meets the requirements + * of the present CPU architecture for optimized packet access. In the fixed-size + * case, there is the additional condition that the total size of the coefficients + * array is a multiple of the packet size, so that it is possible to access all the + * coefficients by packets. In the dynamic-size case, there is no such condition + * on the total size, so it might not be possible to access the few last coeffs + * by packets. + * + * \note This bit can be set regardless of whether vectorization is actually enabled. + * To check for actual vectorizability, see \a ActualPacketAccessBit. + */ +const unsigned int PacketAccessBit = 0x8; + +#ifdef EIGEN_VECTORIZE +/** \ingroup flags + * + * If vectorization is enabled (EIGEN_VECTORIZE is defined) this constant + * is set to the value \a PacketAccessBit. + * + * If vectorization is not enabled (EIGEN_VECTORIZE is not defined) this constant + * is set to the value 0. + */ +const unsigned int ActualPacketAccessBit = PacketAccessBit; +#else +const unsigned int ActualPacketAccessBit = 0x0; +#endif + +/** \ingroup flags + * + * Short version: means the expression can be seen as 1D vector. + * + * Long version: means that one can access the coefficients + * of this expression by coeff(int), and coeffRef(int) in the case of a lvalue expression. These + * index-based access methods are guaranteed + * to not have to do any runtime computation of a (row, col)-pair from the index, so that it + * is guaranteed that whenever it is available, index-based access is at least as fast as + * (row,col)-based access. Expressions for which that isn't possible don't have the LinearAccessBit. + * + * If both PacketAccessBit and LinearAccessBit are set, then the + * packets of this expression can be accessed by packet(int), and writePacket(int) in the case of a + * lvalue expression. + * + * Typically, all vector expressions have the LinearAccessBit, but there is one exception: + * Product expressions don't have it, because it would be troublesome for vectorization, even when the + * Product is a vector expression. Thus, vector Product expressions allow index-based coefficient access but + * not index-based packet access, so they don't have the LinearAccessBit. + */ +const unsigned int LinearAccessBit = 0x10; + +/** \ingroup flags + * + * Means that the underlying array of coefficients can be directly accessed. This means two things. + * First, references to the coefficients must be available through coeffRef(int, int). This rules out read-only + * expressions whose coefficients are computed on demand by coeff(int, int). Second, the memory layout of the + * array of coefficients must be exactly the natural one suggested by rows(), cols(), stride(), and the RowMajorBit. + * This rules out expressions such as DiagonalCoeffs, whose coefficients, though referencable, do not have + * such a regular memory layout. + */ +const unsigned int DirectAccessBit = 0x20; + +/** \ingroup flags + * + * means the first coefficient packet is guaranteed to be aligned */ +const unsigned int AlignedBit = 0x40; + +/** \ingroup flags + * + * means all diagonal coefficients are equal to 0 */ +const unsigned int ZeroDiagBit = 0x80; + +/** \ingroup flags + * + * means all diagonal coefficients are equal to 1 */ +const unsigned int UnitDiagBit = 0x100; + +/** \ingroup flags + * + * means the matrix is selfadjoint (M=M*). */ +const unsigned int SelfAdjointBit = 0x200; + +/** \ingroup flags + * + * means the strictly lower triangular part is 0 */ +const unsigned int UpperTriangularBit = 0x400; + +/** \ingroup flags + * + * means the strictly upper triangular part is 0 */ +const unsigned int LowerTriangularBit = 0x800; + +/** \ingroup flags + * + * means the expression includes sparse matrices and the sparse path has to be taken. */ +const unsigned int SparseBit = 0x1000; + +// list of flags that are inherited by default +const unsigned int HereditaryBits = RowMajorBit + | EvalBeforeNestingBit + | EvalBeforeAssigningBit + | SparseBit; + +// Possible values for the Mode parameter of part() and of extract() +const unsigned int UpperTriangular = UpperTriangularBit; +const unsigned int StrictlyUpperTriangular = UpperTriangularBit | ZeroDiagBit; +const unsigned int LowerTriangular = LowerTriangularBit; +const unsigned int StrictlyLowerTriangular = LowerTriangularBit | ZeroDiagBit; +const unsigned int SelfAdjoint = SelfAdjointBit; + +// additional possible values for the Mode parameter of extract() +const unsigned int UnitUpperTriangular = UpperTriangularBit | UnitDiagBit; +const unsigned int UnitLowerTriangular = LowerTriangularBit | UnitDiagBit; +const unsigned int Diagonal = UpperTriangular | LowerTriangular; + +enum { Aligned, Unaligned }; +enum { ForceAligned, AsRequested }; +enum { ConditionalJumpCost = 5 }; +enum CornerType { TopLeft, TopRight, BottomLeft, BottomRight }; +enum DirectionType { Vertical, Horizontal }; +enum ProductEvaluationMode { NormalProduct, CacheFriendlyProduct, DiagonalProduct, SparseTimeSparseProduct, SparseTimeDenseProduct, DenseTimeSparseProduct }; + +enum { + /** \internal Equivalent to a slice vectorization for fixed-size matrices having good alignment + * and good size */ + InnerVectorization, + /** \internal Vectorization path using a single loop plus scalar loops for the + * unaligned boundaries */ + LinearVectorization, + /** \internal Generic vectorization path using one vectorized loop per row/column with some + * scalar loops to handle the unaligned boundaries */ + SliceVectorization, + NoVectorization +}; + +enum { + NoUnrolling, + InnerUnrolling, + CompleteUnrolling +}; + +enum { + ColMajor = 0, + RowMajor = 0x1, // it is only a coincidence that this is equal to RowMajorBit -- don't rely on that + /** \internal Don't require alignment for the matrix itself (the array of coefficients, if dynamically allocated, may still be + requested to be aligned) */ + DontAlign = 0, + /** \internal Align the matrix itself if it is vectorizable fixed-size */ + AutoAlign = 0x2 +}; + +enum { + IsDense = 0, + IsSparse = SparseBit, + NoDirectAccess = 0, + HasDirectAccess = DirectAccessBit +}; + +const int EiArch_Generic = 0x0; +const int EiArch_SSE = 0x1; +const int EiArch_AltiVec = 0x2; + +#if defined EIGEN_VECTORIZE_SSE + const int EiArch = EiArch_SSE; +#elif defined EIGEN_VECTORIZE_ALTIVEC + const int EiArch = EiArch_AltiVec; +#else + const int EiArch = EiArch_Generic; +#endif + +#endif // EIGEN_CONSTANTS_H diff --git a/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/DisableMSVCWarnings.h b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/DisableMSVCWarnings.h new file mode 100644 index 000000000..765ddecc5 --- /dev/null +++ b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/DisableMSVCWarnings.h @@ -0,0 +1,5 @@ + +#ifdef _MSC_VER + #pragma warning( push ) + #pragma warning( disable : 4181 4244 4127 4211 4717 ) +#endif diff --git a/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/EnableMSVCWarnings.h b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/EnableMSVCWarnings.h new file mode 100644 index 000000000..8bd61601e --- /dev/null +++ b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/EnableMSVCWarnings.h @@ -0,0 +1,4 @@ + +#ifdef _MSC_VER + #pragma warning( pop ) +#endif diff --git a/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/ForwardDeclarations.h b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/ForwardDeclarations.h new file mode 100644 index 000000000..a72a40b1b --- /dev/null +++ b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/ForwardDeclarations.h @@ -0,0 +1,125 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2006-2008 Benoit Jacob +// +// 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 . + +#ifndef EIGEN_FORWARDDECLARATIONS_H +#define EIGEN_FORWARDDECLARATIONS_H + +template struct ei_traits; +template struct NumTraits; + +template class Matrix; + +template class Flagged; +template class NestByValue; +template class SwapWrapper; +template class Minor; +template::Flags&DirectAccessBit ? DirectAccessBit + : ei_traits::Flags&SparseBit> class Block; +template class Transpose; +template class Conjugate; +template class CwiseNullaryOp; +template class CwiseUnaryOp; +template class CwiseBinaryOp; +template class Product; +template class DiagonalMatrix; +template class DiagonalCoeffs; +template class Map; +template class Part; +template class Extract; +template class Cwise; +template class WithFormat; +template struct CommaInitializer; + + +template struct ei_product_mode; +template::value> struct ProductReturnType; + +template struct ei_scalar_sum_op; +template struct ei_scalar_difference_op; +template struct ei_scalar_product_op; +template struct ei_scalar_quotient_op; +template struct ei_scalar_opposite_op; +template struct ei_scalar_conjugate_op; +template struct ei_scalar_real_op; +template struct ei_scalar_imag_op; +template struct ei_scalar_abs_op; +template struct ei_scalar_abs2_op; +template struct ei_scalar_sqrt_op; +template struct ei_scalar_exp_op; +template struct ei_scalar_log_op; +template struct ei_scalar_cos_op; +template struct ei_scalar_sin_op; +template struct ei_scalar_pow_op; +template struct ei_scalar_inverse_op; +template struct ei_scalar_square_op; +template struct ei_scalar_cube_op; +template struct ei_scalar_cast_op; +template struct ei_scalar_multiple_op; +template struct ei_scalar_quotient1_op; +template struct ei_scalar_min_op; +template struct ei_scalar_max_op; +template struct ei_scalar_random_op; +template struct ei_scalar_add_op; +template struct ei_scalar_constant_op; +template struct ei_scalar_identity_op; + +struct IOFormat; + +template +void ei_cache_friendly_product( + int _rows, int _cols, int depth, + bool _lhsRowMajor, const Scalar* _lhs, int _lhsStride, + bool _rhsRowMajor, const Scalar* _rhs, int _rhsStride, + bool resRowMajor, Scalar* res, int resStride); + +// Array module +template class Select; +template class PartialReduxExpr; +template class PartialRedux; + +template class LU; +template class QR; +template class SVD; +template class LLT; +template class LDLT; + +// Geometry module: +template class RotationBase; +template class Cross; +template class Quaternion; +template class Rotation2D; +template class AngleAxis; +template class Transform; +template class ParametrizedLine; +template class Hyperplane; +template class Translation; +template class Scaling; + +// Sparse module: +template class SparseProduct; + +#endif // EIGEN_FORWARDDECLARATIONS_H diff --git a/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/Macros.h b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/Macros.h new file mode 100644 index 000000000..e64ff8644 --- /dev/null +++ b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/Macros.h @@ -0,0 +1,276 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// 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 . + +#ifndef EIGEN_MACROS_H +#define EIGEN_MACROS_H + +#undef minor + +#define EIGEN_WORLD_VERSION 2 +#define EIGEN_MAJOR_VERSION 0 +#define EIGEN_MINOR_VERSION 15 + +#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \ + (EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \ + EIGEN_MINOR_VERSION>=z)))) + +// 16 byte alignment is only useful for vectorization. Since it affects the ABI, we need to enable 16 byte alignment on all +// platforms where vectorization might be enabled. In theory we could always enable alignment, but it can be a cause of problems +// on some platforms, so we just disable it in certain common platform (compiler+architecture combinations) to avoid these problems. +#if defined(__GNUC__) && !(defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || defined(__ppc__) || defined(__ia64__)) +#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_ALIGNMENT 1 +#else +#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_ALIGNMENT 0 +#endif + +#if defined(__GNUC__) && (__GNUC__ <= 3) +#define EIGEN_GCC3_OR_OLDER 1 +#else +#define EIGEN_GCC3_OR_OLDER 0 +#endif + +// FIXME vectorization + alignment is completely disabled with sun studio +#if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_ALIGNMENT && !EIGEN_GCC3_OR_OLDER && !defined(__SUNPRO_CC) && !defined(__QNXNTO__) + #define EIGEN_ARCH_WANTS_ALIGNMENT 1 +#else + #define EIGEN_ARCH_WANTS_ALIGNMENT 0 +#endif + +// EIGEN_ALIGN is the true test whether we want to align or not. It takes into account both the user choice to explicitly disable +// alignment (EIGEN_DONT_ALIGN) and the architecture config (EIGEN_ARCH_WANTS_ALIGNMENT). Henceforth, only EIGEN_ALIGN should be used. +#if EIGEN_ARCH_WANTS_ALIGNMENT && !defined(EIGEN_DONT_ALIGN) + #define EIGEN_ALIGN 1 +#else + #define EIGEN_ALIGN 0 + #ifdef EIGEN_VECTORIZE + #error "Vectorization enabled, but our platform checks say that we don't do 16 byte alignment on this platform. If you added vectorization for another architecture, you also need to edit this platform check." + #endif + #ifndef EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT + #define EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT + #endif +#endif + +#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR +#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION RowMajor +#else +#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ColMajor +#endif + +/** \internal Defines the maximal loop size to enable meta unrolling of loops. + * Note that the value here is expressed in Eigen's own notion of "number of FLOPS", + * it does not correspond to the number of iterations or the number of instructions + */ +#ifndef EIGEN_UNROLLING_LIMIT +#define EIGEN_UNROLLING_LIMIT 100 +#endif + +/** \internal Define the maximal size in Bytes of blocks fitting in CPU cache. + * The current value is set to generate blocks of 256x256 for float + * + * Typically for a single-threaded application you would set that to 25% of the size of your CPU caches in bytes + */ +#ifndef EIGEN_TUNE_FOR_CPU_CACHE_SIZE +#define EIGEN_TUNE_FOR_CPU_CACHE_SIZE (sizeof(float)*256*256) +#endif + +// FIXME this should go away quickly +#ifdef EIGEN_TUNE_FOR_L2_CACHE_SIZE +#error EIGEN_TUNE_FOR_L2_CACHE_SIZE is now called EIGEN_TUNE_FOR_CPU_CACHE_SIZE. +#endif + +#define USING_PART_OF_NAMESPACE_EIGEN \ +EIGEN_USING_MATRIX_TYPEDEFS \ +using Eigen::Matrix; \ +using Eigen::MatrixBase; \ +using Eigen::ei_random; \ +using Eigen::ei_real; \ +using Eigen::ei_imag; \ +using Eigen::ei_conj; \ +using Eigen::ei_abs; \ +using Eigen::ei_abs2; \ +using Eigen::ei_sqrt; \ +using Eigen::ei_exp; \ +using Eigen::ei_log; \ +using Eigen::ei_sin; \ +using Eigen::ei_cos; + +#ifdef NDEBUG +# ifndef EIGEN_NO_DEBUG +# define EIGEN_NO_DEBUG +# endif +#endif + +#ifndef ei_assert +#ifdef EIGEN_NO_DEBUG +#define ei_assert(x) +#else +#define ei_assert(x) assert(x) +#endif +#endif + +#ifdef EIGEN_INTERNAL_DEBUGGING +#define ei_internal_assert(x) ei_assert(x) +#else +#define ei_internal_assert(x) +#endif + +#ifdef EIGEN_NO_DEBUG +#define EIGEN_ONLY_USED_FOR_DEBUG(x) (void)x +#else +#define EIGEN_ONLY_USED_FOR_DEBUG(x) +#endif + +// EIGEN_ALWAYS_INLINE_ATTRIB should be use in the declaration of function +// 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 Eigen::MatrixBase::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 + +// EIGEN_FORCE_INLINE means "inline as much as possible" +#if (defined _MSC_VER) +#define EIGEN_STRONG_INLINE __forceinline +#else +#define EIGEN_STRONG_INLINE inline +#endif + +#if (defined __GNUC__) +#define EIGEN_DONT_INLINE __attribute__((noinline)) +#elif (defined _MSC_VER) +#define EIGEN_DONT_INLINE __declspec(noinline) +#else +#define EIGEN_DONT_INLINE +#endif + +#if (defined __GNUC__) +#define EIGEN_DEPRECATED __attribute__((deprecated)) +#elif (defined _MSC_VER) +#define EIGEN_DEPRECATED __declspec(deprecated) +#else +#define EIGEN_DEPRECATED +#endif + +/* EIGEN_ALIGN_128 forces data to be 16-byte aligned, EVEN if vectorization (EIGEN_VECTORIZE) is disabled, + * so that vectorization doesn't affect binary compatibility. + * + * 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 !EIGEN_ALIGN +#define EIGEN_ALIGN_128 +#elif (defined __GNUC__) +#define EIGEN_ALIGN_128 __attribute__((aligned(16))) +#elif (defined _MSC_VER) +#define EIGEN_ALIGN_128 __declspec(align(16)) +#else +#error Please tell me what is the equivalent of __attribute__((aligned(16))) for your compiler +#endif + +#ifdef EIGEN_DONT_USE_RESTRICT_KEYWORD + #define EIGEN_RESTRICT +#endif +#ifndef EIGEN_RESTRICT + #define EIGEN_RESTRICT __restrict +#endif + +#ifndef EIGEN_STACK_ALLOCATION_LIMIT +#define EIGEN_STACK_ALLOCATION_LIMIT 1000000 +#endif + +#ifndef EIGEN_DEFAULT_IO_FORMAT +#define EIGEN_DEFAULT_IO_FORMAT Eigen::IOFormat() +#endif + +// format used in Eigen's documentation +// needed to define it here as escaping characters in CMake add_definition's argument seems very problematic. +#define EIGEN_DOCS_IO_FORMAT IOFormat(3, AlignCols, " ", "\n", "", "") + +#define EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, Op) \ +template \ +EIGEN_STRONG_INLINE Derived& operator Op(const Eigen::MatrixBase& other) \ +{ \ + return Base::operator Op(other.derived()); \ +} \ +EIGEN_STRONG_INLINE Derived& operator Op(const Derived& other) \ +{ \ + return Base::operator Op(other); \ +} + +#define EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, Op) \ +template \ +EIGEN_STRONG_INLINE Derived& operator Op(const Other& scalar) \ +{ \ + return Base::operator Op(scalar); \ +} + +#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) \ +EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, =) \ +EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, +=) \ +EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, -=) \ +EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, *=) \ +EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, /=) + +#define _EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, BaseClass) \ +typedef BaseClass Base; \ +typedef typename Eigen::ei_traits::Scalar Scalar; \ +typedef typename Eigen::NumTraits::Real RealScalar; \ +typedef typename Base::PacketScalar PacketScalar; \ +typedef typename Eigen::ei_nested::type Nested; \ +enum { RowsAtCompileTime = Eigen::ei_traits::RowsAtCompileTime, \ + ColsAtCompileTime = Eigen::ei_traits::ColsAtCompileTime, \ + MaxRowsAtCompileTime = Eigen::ei_traits::MaxRowsAtCompileTime, \ + MaxColsAtCompileTime = Eigen::ei_traits::MaxColsAtCompileTime, \ + Flags = Eigen::ei_traits::Flags, \ + CoeffReadCost = Eigen::ei_traits::CoeffReadCost, \ + SizeAtCompileTime = Base::SizeAtCompileTime, \ + MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \ + IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; + +#define EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) \ +_EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, Eigen::MatrixBase) + +#define EIGEN_ENUM_MIN(a,b) (((int)a <= (int)b) ? (int)a : (int)b) +#define EIGEN_SIZE_MIN(a,b) (((int)a == 1 || (int)b == 1) ? 1 \ + : ((int)a == Dynamic || (int)b == Dynamic) ? Dynamic \ + : ((int)a <= (int)b) ? (int)a : (int)b) +#define EIGEN_ENUM_MAX(a,b) (((int)a >= (int)b) ? (int)a : (int)b) + +// just an empty macro ! +#define EIGEN_EMPTY + +// concatenate two tokens +#define EIGEN_CAT2(a,b) a ## b +#define EIGEN_CAT(a,b) EIGEN_CAT2(a,b) + +// convert a token to a string +#define EIGEN_MAKESTRING2(a) #a +#define EIGEN_MAKESTRING(a) EIGEN_MAKESTRING2(a) + +#endif // EIGEN_MACROS_H diff --git a/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/Memory.h b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/Memory.h new file mode 100644 index 000000000..eff86a23f --- /dev/null +++ b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/Memory.h @@ -0,0 +1,417 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2008-2009 Benoit Jacob +// Copyright (C) 2009 Kenneth Riddile +// +// 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 . + +#ifndef EIGEN_MEMORY_H +#define EIGEN_MEMORY_H + +// FreeBSD 6 seems to have 16-byte aligned malloc +// See http://svn.freebsd.org/viewvc/base/stable/6/lib/libc/stdlib/malloc.c?view=markup +// FreeBSD 7 seems to have 16-byte aligned malloc except on ARM and MIPS architectures +// See http://svn.freebsd.org/viewvc/base/stable/7/lib/libc/stdlib/malloc.c?view=markup +#if defined(__FreeBSD__) && !defined(__arm__) && !defined(__mips__) +#define EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED 1 +#else +#define EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED 0 +#endif + +#if defined(__APPLE__) || defined(_WIN64) || EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED + #define EIGEN_MALLOC_ALREADY_ALIGNED 1 +#else + #define EIGEN_MALLOC_ALREADY_ALIGNED 0 +#endif + +#if (defined __QNXNTO__) || (((defined _GNU_SOURCE) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0)) + #define EIGEN_HAS_POSIX_MEMALIGN 1 +#else + #define EIGEN_HAS_POSIX_MEMALIGN 0 +#endif + +#ifdef EIGEN_VECTORIZE_SSE + #define EIGEN_HAS_MM_MALLOC 1 +#else + #define EIGEN_HAS_MM_MALLOC 0 +#endif + +/** \internal like malloc, but the returned pointer is guaranteed to be 16-byte aligned. + * Fast, but wastes 16 additional bytes of memory. + * Does not throw any exception. + */ +inline void* ei_handmade_aligned_malloc(std::size_t size) +{ + void *original = std::malloc(size+16); + void *aligned = reinterpret_cast((reinterpret_cast(original) & ~(std::size_t(15))) + 16); + *(reinterpret_cast(aligned) - 1) = original; + return aligned; +} + +/** \internal frees memory allocated with ei_handmade_aligned_malloc */ +inline void ei_handmade_aligned_free(void *ptr) +{ + if(ptr) + std::free(*(reinterpret_cast(ptr) - 1)); +} + +/** \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. + */ +inline void* ei_aligned_malloc(std::size_t size) +{ + #ifdef EIGEN_NO_MALLOC + ei_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)"); + #endif + + void *result; + #if !EIGEN_ALIGN + result = std::malloc(size); + #elif EIGEN_MALLOC_ALREADY_ALIGNED + result = std::malloc(size); + #elif EIGEN_HAS_POSIX_MEMALIGN + if(posix_memalign(&result, 16, size)) result = 0; + #elif EIGEN_HAS_MM_MALLOC + result = _mm_malloc(size, 16); + #elif (defined _MSC_VER) + result = _aligned_malloc(size, 16); + #else + result = ei_handmade_aligned_malloc(size); + #endif + + #ifdef EIGEN_EXCEPTIONS + if(result == 0) + throw std::bad_alloc(); + #endif + return result; +} + +/** 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. + */ +template inline void* ei_conditional_aligned_malloc(std::size_t size) +{ + return ei_aligned_malloc(size); +} + +template<> inline void* ei_conditional_aligned_malloc(std::size_t size) +{ + #ifdef EIGEN_NO_MALLOC + ei_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)"); + #endif + + void *result = std::malloc(size); + #ifdef EIGEN_EXCEPTIONS + if(!result) throw std::bad_alloc(); + #endif + return result; +} + +/** \internal construct the elements of an array. + * The \a size parameter tells on how many objects to call the constructor of T. + */ +template inline T* ei_construct_elements_of_array(T *ptr, std::size_t size) +{ + for (std::size_t i=0; i < size; ++i) ::new (ptr + i) T; + return ptr; +} + +/** 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. + * The default constructor of T is called. + */ +template inline T* ei_aligned_new(std::size_t size) +{ + T *result = reinterpret_cast(ei_aligned_malloc(sizeof(T)*size)); + return ei_construct_elements_of_array(result, size); +} + +template inline T* ei_conditional_aligned_new(std::size_t size) +{ + T *result = reinterpret_cast(ei_conditional_aligned_malloc(sizeof(T)*size)); + return ei_construct_elements_of_array(result, size); +} + +/** \internal free memory allocated with ei_aligned_malloc + */ +inline void ei_aligned_free(void *ptr) +{ + #if !EIGEN_ALIGN + std::free(ptr); + #elif EIGEN_MALLOC_ALREADY_ALIGNED + std::free(ptr); + #elif EIGEN_HAS_POSIX_MEMALIGN + std::free(ptr); + #elif EIGEN_HAS_MM_MALLOC + _mm_free(ptr); + #elif defined(_MSC_VER) + _aligned_free(ptr); + #else + ei_handmade_aligned_free(ptr); + #endif +} + +/** \internal free memory allocated with ei_conditional_aligned_malloc + */ +template inline void ei_conditional_aligned_free(void *ptr) +{ + ei_aligned_free(ptr); +} + +template<> inline void ei_conditional_aligned_free(void *ptr) +{ + std::free(ptr); +} + +/** \internal destruct the elements of an array. + * The \a size parameters tells on how many objects to call the destructor of T. + */ +template inline void ei_destruct_elements_of_array(T *ptr, std::size_t size) +{ + // always destruct an array starting from the end. + if(ptr) + while(size) ptr[--size].~T(); +} + +/** \internal delete objects constructed with ei_aligned_new + * The \a size parameters tells on how many objects to call the destructor of T. + */ +template inline void ei_aligned_delete(T *ptr, std::size_t size) +{ + ei_destruct_elements_of_array(ptr, size); + ei_aligned_free(ptr); +} + +/** \internal delete objects constructed with ei_conditional_aligned_new + * The \a size parameters tells on how many objects to call the destructor of T. + */ +template inline void ei_conditional_aligned_delete(T *ptr, std::size_t size) +{ + ei_destruct_elements_of_array(ptr, size); + ei_conditional_aligned_free(ptr); +} + +/** \internal \returns the index of the first element of the array that is well aligned for vectorization. + * + * \param array the address of the start of the array + * \param size the size of the array + * + * \note If no element of the array is well aligned, the size of the array is returned. Typically, + * for example with SSE, "well aligned" means 16-byte-aligned. If vectorization is disabled or if the + * packet size for the given scalar type is 1, then everything is considered well-aligned. + * + * \note If the scalar type is vectorizable, we rely on the following assumptions: sizeof(Scalar) is a + * power of 2, the packet size in bytes is also a power of 2, and is a multiple of sizeof(Scalar). On the + * other hand, we do not assume that the array address is a multiple of sizeof(Scalar), as that fails for + * example with Scalar=double on certain 32-bit platforms, see bug #79. + * + * There is also the variant ei_first_aligned(const MatrixBase&, Integer) defined in Coeffs.h. + */ +template +inline static Integer ei_alignmentOffset(const Scalar* array, Integer size) +{ + typedef typename ei_packet_traits::type Packet; + enum { PacketSize = ei_packet_traits::size, + PacketAlignedMask = PacketSize-1 + }; + + if(PacketSize==1) + { + // Either there is no vectorization, or a packet consists of exactly 1 scalar so that all elements + // of the array have the same aligment. + return 0; + } + else if(std::size_t(array) & (sizeof(Scalar)-1)) + { + // There is vectorization for this scalar type, but the array is not aligned to the size of a single scalar. + // Consequently, no element of the array is well aligned. + return size; + } + else + { + return std::min( (PacketSize - (Integer((std::size_t(array)/sizeof(Scalar))) & PacketAlignedMask)) + & PacketAlignedMask, size); + } +} + +/** \internal + * ei_aligned_stack_alloc(SIZE) allocates an aligned buffer of SIZE bytes + * on the stack if SIZE is smaller than EIGEN_STACK_ALLOCATION_LIMIT. + * Otherwise the memory is allocated on the heap. + * Data allocated with ei_aligned_stack_alloc \b must be freed by calling ei_aligned_stack_free(PTR,SIZE). + * \code + * float * data = ei_aligned_stack_alloc(float,array.size()); + * // ... + * ei_aligned_stack_free(data,float,array.size()); + * \endcode + */ +#ifdef __linux__ + #define ei_aligned_stack_alloc(SIZE) (SIZE<=EIGEN_STACK_ALLOCATION_LIMIT) \ + ? alloca(SIZE) \ + : ei_aligned_malloc(SIZE) + #define ei_aligned_stack_free(PTR,SIZE) if(SIZE>EIGEN_STACK_ALLOCATION_LIMIT) ei_aligned_free(PTR) +#else + #define ei_aligned_stack_alloc(SIZE) ei_aligned_malloc(SIZE) + #define ei_aligned_stack_free(PTR,SIZE) ei_aligned_free(PTR) +#endif + +#define ei_aligned_stack_new(TYPE,SIZE) ei_construct_elements_of_array(reinterpret_cast(ei_aligned_stack_alloc(sizeof(TYPE)*SIZE)), SIZE) +#define ei_aligned_stack_delete(TYPE,PTR,SIZE) do {ei_destruct_elements_of_array(PTR, SIZE); \ + ei_aligned_stack_free(PTR,sizeof(TYPE)*SIZE);} while(0) + + +#if EIGEN_ALIGN + #ifdef EIGEN_EXCEPTIONS + #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \ + void* operator new(std::size_t size, const std::nothrow_t&) throw() { \ + try { return Eigen::ei_conditional_aligned_malloc(size); } \ + catch (...) { return 0; } \ + return 0; \ + } + #else + #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \ + void* operator new(std::size_t size, const std::nothrow_t&) throw() { \ + return Eigen::ei_conditional_aligned_malloc(size); \ + } + #endif + + #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) \ + void *operator new(std::size_t size) { \ + return Eigen::ei_conditional_aligned_malloc(size); \ + } \ + void *operator new[](std::size_t size) { \ + return Eigen::ei_conditional_aligned_malloc(size); \ + } \ + void operator delete(void * ptr) throw() { Eigen::ei_conditional_aligned_free(ptr); } \ + void operator delete[](void * ptr) throw() { Eigen::ei_conditional_aligned_free(ptr); } \ + /* in-place new and delete. since (at least afaik) there is no actual */ \ + /* memory allocated we can safely let the default implementation handle */ \ + /* this particular case. */ \ + static void *operator new(std::size_t size, void *ptr) { return ::operator new(size,ptr); } \ + void operator delete(void * memory, void *ptr) throw() { return ::operator delete(memory,ptr); } \ + /* nothrow-new (returns zero instead of std::bad_alloc) */ \ + EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \ + void operator delete(void *ptr, const std::nothrow_t&) throw() { \ + Eigen::ei_conditional_aligned_free(ptr); \ + } \ + typedef void ei_operator_new_marker_type; +#else + #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) +#endif + +#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(true) +#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(Scalar,Size) \ + EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(((Size)!=Eigen::Dynamic) && ((sizeof(Scalar)*(Size))%16==0)) + + +/** \class aligned_allocator +* +* \brief stl compatible allocator to use with with 16 byte aligned types +* +* Example: +* \code +* // Matrix4f requires 16 bytes alignment: +* std::map< int, Matrix4f, std::less, aligned_allocator > my_map_mat4; +* // Vector3f does not require 16 bytes alignment, no need to use Eigen's allocator: +* std::map< int, Vector3f > my_map_vec3; +* \endcode +* +*/ +template +class aligned_allocator +{ +public: + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef T value_type; + + template + struct rebind + { + typedef aligned_allocator other; + }; + + pointer address( reference value ) const + { + return &value; + } + + const_pointer address( const_reference value ) const + { + return &value; + } + + aligned_allocator() throw() + { + } + + aligned_allocator( const aligned_allocator& ) throw() + { + } + + template + aligned_allocator( const aligned_allocator& ) throw() + { + } + + ~aligned_allocator() throw() + { + } + + size_type max_size() const throw() + { + return std::numeric_limits::max(); + } + + pointer allocate( size_type num, const_pointer* hint = 0 ) + { + static_cast( hint ); // suppress unused variable warning + return static_cast( ei_aligned_malloc( num * sizeof(T) ) ); + } + + void construct( pointer p, const T& value ) + { + ::new( p ) T( value ); + } + + void destroy( pointer p ) + { + p->~T(); + } + + void deallocate( pointer p, size_type /*num*/ ) + { + ei_aligned_free( p ); + } + + bool operator!=(const aligned_allocator& other) const + { return false; } + + bool operator==(const aligned_allocator& other) const + { return true; } +}; + +#endif // EIGEN_MEMORY_H diff --git a/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/Meta.h b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/Meta.h new file mode 100644 index 000000000..c65c52ef4 --- /dev/null +++ b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/Meta.h @@ -0,0 +1,183 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// 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 . + +#ifndef EIGEN_META_H +#define EIGEN_META_H + +/** \internal + * \file Meta.h + * This file contains generic metaprogramming classes which are not specifically related to Eigen. + * \note In case you wonder, yes we're aware that Boost already provides all these features, + * we however don't want to add a dependency to Boost. + */ + +struct ei_meta_true { enum { ret = 1 }; }; +struct ei_meta_false { enum { ret = 0 }; }; + +template +struct ei_meta_if { typedef Then ret; }; + +template +struct ei_meta_if { typedef Else ret; }; + +template struct ei_is_same_type { enum { ret = 0 }; }; +template struct ei_is_same_type { enum { ret = 1 }; }; + +template struct ei_unref { typedef T type; }; +template struct ei_unref { typedef T type; }; + +template struct ei_unpointer { typedef T type; }; +template struct ei_unpointer { typedef T type; }; +template struct ei_unpointer { typedef T type; }; + +template struct ei_unconst { typedef T type; }; +template struct ei_unconst { typedef T type; }; +template struct ei_unconst { typedef T & type; }; +template struct ei_unconst { typedef T * type; }; + +template struct ei_cleantype { typedef T type; }; +template struct ei_cleantype { typedef typename ei_cleantype::type type; }; +template struct ei_cleantype { typedef typename ei_cleantype::type type; }; +template struct ei_cleantype { typedef typename ei_cleantype::type type; }; +template struct ei_cleantype { typedef typename ei_cleantype::type type; }; +template struct ei_cleantype { typedef typename ei_cleantype::type type; }; + +/** \internal + * Convenient struct to get the result type of a unary or binary functor. + * + * It supports both the current STL mechanism (using the result_type member) as well as + * upcoming next STL generation (using a templated result member). + * If none of these members is provided, then the type of the first argument is returned. FIXME, that behavior is a pretty bad hack. + */ +template struct ei_result_of {}; + +struct ei_has_none {int a[1];}; +struct ei_has_std_result_type {int a[2];}; +struct ei_has_tr1_result {int a[3];}; + +template +struct ei_unary_result_of_select {typedef ArgType type;}; + +template +struct ei_unary_result_of_select {typedef typename Func::result_type type;}; + +template +struct ei_unary_result_of_select {typedef typename Func::template result::type type;}; + +template +struct ei_result_of { + template + static ei_has_std_result_type testFunctor(T const *, typename T::result_type const * = 0); + template + static ei_has_tr1_result testFunctor(T const *, typename T::template result::type const * = 0); + static ei_has_none testFunctor(...); + + // note that the following indirection is needed for gcc-3.3 + enum {FunctorType = sizeof(testFunctor(static_cast(0)))}; + typedef typename ei_unary_result_of_select::type type; +}; + +template +struct ei_binary_result_of_select {typedef ArgType0 type;}; + +template +struct ei_binary_result_of_select +{typedef typename Func::result_type type;}; + +template +struct ei_binary_result_of_select +{typedef typename Func::template result::type type;}; + +template +struct ei_result_of { + template + static ei_has_std_result_type testFunctor(T const *, typename T::result_type const * = 0); + template + static ei_has_tr1_result testFunctor(T const *, typename T::template result::type const * = 0); + static ei_has_none testFunctor(...); + + // note that the following indirection is needed for gcc-3.3 + enum {FunctorType = sizeof(testFunctor(static_cast(0)))}; + typedef typename ei_binary_result_of_select::type type; +}; + +/** \internal In short, it computes int(sqrt(\a Y)) with \a Y an integer. + * Usage example: \code ei_meta_sqrt<1023>::ret \endcode + */ +template Y))) > + // use ?: instead of || just to shut up a stupid gcc 4.3 warning +class ei_meta_sqrt +{ + enum { + MidX = (InfX+SupX)/2, + TakeInf = MidX*MidX > Y ? 1 : 0, + NewInf = int(TakeInf) ? InfX : int(MidX), + NewSup = int(TakeInf) ? int(MidX) : SupX + }; + public: + enum { ret = ei_meta_sqrt::ret }; +}; + +template +class ei_meta_sqrt { public: enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; }; + +/** \internal determines whether the product of two numeric types is allowed and what the return type is */ +template struct ei_scalar_product_traits +{ + // dummy general case where T and U aren't compatible -- not allowed anyway but we catch it elsewhere + //enum { Cost = NumTraits::MulCost }; + typedef T ReturnType; +}; + +template struct ei_scalar_product_traits +{ + //enum { Cost = NumTraits::MulCost }; + typedef T ReturnType; +}; + +template struct ei_scalar_product_traits > +{ + //enum { Cost = 2*NumTraits::MulCost }; + typedef std::complex ReturnType; +}; + +template struct ei_scalar_product_traits, T> +{ + //enum { Cost = 2*NumTraits::MulCost }; + typedef std::complex ReturnType; +}; + +// FIXME quick workaround around current limitation of ei_result_of +template +struct ei_result_of(ArgType0,ArgType1)> { +typedef typename ei_scalar_product_traits::type, typename ei_cleantype::type>::ReturnType type; +}; + + + +#endif // EIGEN_META_H diff --git a/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/StaticAssert.h b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/StaticAssert.h new file mode 100644 index 000000000..050504e40 --- /dev/null +++ b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/StaticAssert.h @@ -0,0 +1,149 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// 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 . + +#ifndef EIGEN_STATIC_ASSERT_H +#define EIGEN_STATIC_ASSERT_H + +/* Some notes on Eigen's static assertion mechanism: + * + * - in EIGEN_STATIC_ASSERT(CONDITION,MSG) the parameter CONDITION must be a compile time boolean + * expression, and MSG an enum listed in struct ei_static_assert + * + * - define EIGEN_NO_STATIC_ASSERT to disable them (and save compilation time) + * in that case, the static assertion is converted to the following runtime assert: + * ei_assert(CONDITION && "MSG") + * + * - currently EIGEN_STATIC_ASSERT can only be used in function scope + * + */ + +#ifndef EIGEN_NO_STATIC_ASSERT + + #ifdef __GXX_EXPERIMENTAL_CXX0X__ + + // if native static_assert is enabled, let's use it + #define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG); + + #else // CXX0X + + template + struct ei_static_assert {}; + + template<> + struct ei_static_assert + { + enum { + YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX, + YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES, + YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES, + THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE, + THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE, + YOU_MADE_A_PROGRAMMING_MISTAKE, + YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR, + UNALIGNED_LOAD_AND_STORE_OPERATIONS_UNIMPLEMENTED_ON_ALTIVEC, + NUMERIC_TYPE_MUST_BE_FLOATING_POINT, + COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED, + WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED, + THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE, + INVALID_MATRIX_PRODUCT, + INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS, + INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION, + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY, + THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES, + THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES, + INVALID_MATRIX_TEMPLATE_PARAMETERS, + INVALID_MATRIXBASE_TEMPLATE_PARAMETERS, + BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER, + THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX + }; + }; + + // Specialized implementation for MSVC to avoid "conditional + // expression is constant" warnings. This implementation doesn't + // appear to work under GCC, hence the multiple implementations. + #ifdef _MSC_VER + + #define EIGEN_STATIC_ASSERT(CONDITION,MSG) \ + {Eigen::ei_static_assert::MSG;} + + #else + + #define EIGEN_STATIC_ASSERT(CONDITION,MSG) \ + if (Eigen::ei_static_assert::MSG) {} + + #endif + + #endif // not CXX0X + +#else // EIGEN_NO_STATIC_ASSERT + + #define EIGEN_STATIC_ASSERT(CONDITION,MSG) ei_assert((CONDITION) && #MSG); + +#endif // EIGEN_NO_STATIC_ASSERT + + +// static assertion failing if the type \a TYPE is not a vector type +#define EIGEN_STATIC_ASSERT_VECTOR_ONLY(TYPE) \ + EIGEN_STATIC_ASSERT(TYPE::IsVectorAtCompileTime, \ + YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX) + +// static assertion failing if the type \a TYPE is not fixed-size +#define EIGEN_STATIC_ASSERT_FIXED_SIZE(TYPE) \ + EIGEN_STATIC_ASSERT(TYPE::SizeAtCompileTime!=Eigen::Dynamic, \ + YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR) + +// static assertion failing if the type \a TYPE is not a vector type of the given size +#define EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(TYPE, SIZE) \ + EIGEN_STATIC_ASSERT(TYPE::IsVectorAtCompileTime && TYPE::SizeAtCompileTime==SIZE, \ + THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE) + +// static assertion failing if the type \a TYPE is not a vector type of the given size +#define EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(TYPE, ROWS, COLS) \ + EIGEN_STATIC_ASSERT(TYPE::RowsAtCompileTime==ROWS && TYPE::ColsAtCompileTime==COLS, \ + THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE) + +// static assertion failing if the two vector expression types are not compatible (same fixed-size or dynamic size) +#define EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(TYPE0,TYPE1) \ + EIGEN_STATIC_ASSERT( \ + (int(TYPE0::SizeAtCompileTime)==Eigen::Dynamic \ + || int(TYPE1::SizeAtCompileTime)==Eigen::Dynamic \ + || int(TYPE0::SizeAtCompileTime)==int(TYPE1::SizeAtCompileTime)),\ + YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES) + +#define EIGEN_PREDICATE_SAME_MATRIX_SIZE(TYPE0,TYPE1) \ + ((int(TYPE0::RowsAtCompileTime)==Eigen::Dynamic \ + || int(TYPE1::RowsAtCompileTime)==Eigen::Dynamic \ + || int(TYPE0::RowsAtCompileTime)==int(TYPE1::RowsAtCompileTime)) \ + && (int(TYPE0::ColsAtCompileTime)==Eigen::Dynamic \ + || int(TYPE1::ColsAtCompileTime)==Eigen::Dynamic \ + || int(TYPE0::ColsAtCompileTime)==int(TYPE1::ColsAtCompileTime))) + +// static assertion failing if it is guaranteed at compile-time that the two matrix expression types have different sizes +#define EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(TYPE0,TYPE1) \ + EIGEN_STATIC_ASSERT( \ + EIGEN_PREDICATE_SAME_MATRIX_SIZE(TYPE0,TYPE1),\ + YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES) + +#endif // EIGEN_STATIC_ASSERT_H diff --git a/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/XprHelper.h b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/XprHelper.h new file mode 100644 index 000000000..ab4cf89a7 --- /dev/null +++ b/ground/openpilotgcs/src/libs/eigen/Eigen/src/Core/util/XprHelper.h @@ -0,0 +1,242 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// 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 . + +#ifndef EIGEN_XPRHELPER_H +#define EIGEN_XPRHELPER_H + +// just a workaround because GCC seems to not really like empty structs +#ifdef __GNUG__ + struct ei_empty_struct{char _ei_dummy_;}; + #define EIGEN_EMPTY_STRUCT : Eigen::ei_empty_struct +#else + #define EIGEN_EMPTY_STRUCT +#endif + +//classes inheriting ei_no_assignment_operator don't generate a default operator=. +class ei_no_assignment_operator +{ +#if EIGEN_GCC3_OR_OLDER + protected: + void nevermind_this_is_just_to_work_around_a_stupid_gcc3_warning(); +#endif + private: + ei_no_assignment_operator& operator=(const ei_no_assignment_operator&); +}; + +/** \internal If the template parameter Value is Dynamic, this class is just a wrapper around an int variable that + * can be accessed using value() and setValue(). + * Otherwise, this class is an empty structure and value() just returns the template parameter Value. + */ +template class ei_int_if_dynamic EIGEN_EMPTY_STRUCT +{ + public: + ei_int_if_dynamic() {} + explicit ei_int_if_dynamic(int) {} + static int value() { return Value; } + void setValue(int) {} +}; + +template<> class ei_int_if_dynamic +{ + int m_value; + ei_int_if_dynamic() {} + public: + explicit ei_int_if_dynamic(int value) : m_value(value) {} + int value() const { return m_value; } + void setValue(int value) { m_value = value; } +}; + +template struct ei_functor_traits +{ + enum + { + Cost = 10, + PacketAccess = false + }; +}; + +template struct ei_packet_traits +{ + typedef T type; + enum {size=1}; +}; + +template struct ei_unpacket_traits +{ + typedef T type; + enum {size=1}; +}; + +template +class ei_compute_matrix_flags +{ + enum { + row_major_bit = Options&RowMajor ? RowMajorBit : 0, + inner_max_size = int(MaxRows==1) ? int(MaxCols) + : int(MaxCols==1) ? int(MaxRows) + : int(row_major_bit) ? int(MaxCols) : int(MaxRows), + is_big = inner_max_size == Dynamic, + storage_has_fixed_size = MaxRows != Dynamic && MaxCols != Dynamic, + storage_has_aligned_fixed_size = storage_has_fixed_size + && ( (MaxCols*MaxRows) % ei_packet_traits::size == 0 ), + aligned_bit = ( (Options&AutoAlign) + && (is_big || storage_has_aligned_fixed_size) + ) ? AlignedBit : 0, + packet_access_bit = ei_packet_traits::size > 1 && aligned_bit ? PacketAccessBit : 0 + }; + + public: + enum { ret = LinearAccessBit | DirectAccessBit | packet_access_bit | row_major_bit | aligned_bit }; +}; + +template struct ei_size_at_compile_time +{ + enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols }; +}; + +/* ei_eval : the return type of eval(). For matrices, this is just a const reference + * in order to avoid a useless copy + */ + +template::Flags&SparseBit> class ei_eval; + +template struct ei_eval +{ + typedef Matrix::Scalar, + ei_traits::RowsAtCompileTime, + ei_traits::ColsAtCompileTime, + AutoAlign | (ei_traits::Flags&RowMajorBit ? RowMajor : ColMajor), + ei_traits::MaxRowsAtCompileTime, + ei_traits::MaxColsAtCompileTime + > type; +}; + +// for matrices, no need to evaluate, just use a const reference to avoid a useless copy +template +struct ei_eval, IsDense> +{ + typedef const Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>& type; +}; + +/* ei_plain_matrix_type : the difference from ei_eval is that ei_plain_matrix_type is always a plain matrix type, + * whereas ei_eval is a const reference in the case of a matrix + */ +template struct ei_plain_matrix_type +{ + typedef Matrix::Scalar, + ei_traits::RowsAtCompileTime, + ei_traits::ColsAtCompileTime, + AutoAlign | (ei_traits::Flags&RowMajorBit ? RowMajor : ColMajor), + ei_traits::MaxRowsAtCompileTime, + ei_traits::MaxColsAtCompileTime + > type; +}; + +/* ei_plain_matrix_type_column_major : same as ei_plain_matrix_type but guaranteed to be column-major + */ +template struct ei_plain_matrix_type_column_major +{ + typedef Matrix::Scalar, + ei_traits::RowsAtCompileTime, + ei_traits::ColsAtCompileTime, + AutoAlign | ColMajor, + ei_traits::MaxRowsAtCompileTime, + ei_traits::MaxColsAtCompileTime + > type; +}; + +/* ei_plain_matrix_type_row_major : same as ei_plain_matrix_type but guaranteed to be row-major + */ +template struct ei_plain_matrix_type_row_major +{ + typedef Matrix::Scalar, + ei_traits::RowsAtCompileTime, + ei_traits::ColsAtCompileTime, + AutoAlign | RowMajor, + ei_traits::MaxRowsAtCompileTime, + ei_traits::MaxColsAtCompileTime + > type; +}; + +template struct ei_must_nest_by_value { enum { ret = false }; }; +template struct ei_must_nest_by_value > { enum { ret = true }; }; + +/** \internal Determines how a given expression should be nested into another one. + * For example, when you do a * (b+c), Eigen will determine how the expression b+c should be + * nested into the bigger product expression. The choice is between nesting the expression b+c as-is, or + * evaluating that expression b+c into a temporary variable d, and nest d so that the resulting expression is + * a*d. Evaluating can be beneficial for example if every coefficient access in the resulting expression causes + * many coefficient accesses in the nested expressions -- as is the case with matrix product for example. + * + * \param T the type of the expression being nested + * \param n the number of coefficient accesses in the nested expression for each coefficient access in the bigger expression. + * + * Example. Suppose that a, b, and c are of type Matrix3d. The user forms the expression a*(b+c). + * b+c is an expression "sum of matrices", which we will denote by S. In order to determine how to nest it, + * the Product expression uses: ei_nested::ret, which turns out to be Matrix3d because the internal logic of + * ei_nested determined that in this case it was better to evaluate the expression b+c into a temporary. On the other hand, + * since a is of type Matrix3d, the Product expression nests it as ei_nested::ret, which turns out to be + * const Matrix3d&, because the internal logic of ei_nested determined that since a was already a matrix, there was no point + * in copying it into another matrix. + */ +template::type> struct ei_nested +{ + enum { + CostEval = (n+1) * int(NumTraits::Scalar>::ReadCost), + CostNoEval = (n-1) * int(ei_traits::CoeffReadCost) + }; + typedef typename ei_meta_if< + ei_must_nest_by_value::ret, + T, + typename ei_meta_if< + (int(ei_traits::Flags) & EvalBeforeNestingBit) + || ( int(CostEval) <= int(CostNoEval) ), + PlainMatrixType, + const T& + >::ret + >::ret type; +}; + +template struct ei_are_flags_consistent +{ + enum { ret = !( (Flags&UnitDiagBit && Flags&ZeroDiagBit) ) + }; +}; + +/** \internal Gives the type of a sub-matrix or sub-vector of a matrix of type \a ExpressionType and size \a Size + * TODO: could be a good idea to define a big ReturnType struct ?? + */ +template struct BlockReturnType { + typedef Block::RowsAtCompileTime == 1 ? 1 : RowsOrSize), + (ei_traits::ColsAtCompileTime == 1 ? 1 : RowsOrSize)> SubVectorType; + typedef Block Type; +}; + +template struct ei_cast_return_type +{ + typedef typename ei_meta_if::ret,const CurrentType&,NewType>::ret type; +}; + +#endif // EIGEN_XPRHELPER_H