mirror of
				https://github.com/aportelli/LatAnalyze.git
				synced 2025-10-29 14:19:34 +00:00 
			
		
		
		
	initial commit
This commit is contained in:
		
							
								
								
									
										11
									
								
								latan/Eigen/Array
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								latan/Eigen/Array
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| #ifndef EIGEN_ARRAY_MODULE_H | ||||
| #define EIGEN_ARRAY_MODULE_H | ||||
|  | ||||
| // include Core first to handle Eigen2 support macros | ||||
| #include "Core" | ||||
|  | ||||
| #ifndef EIGEN2_SUPPORT | ||||
|   #error The Eigen/Array header does no longer exist in Eigen3. All that functionality has moved to Eigen/Core. | ||||
| #endif | ||||
|  | ||||
| #endif // EIGEN_ARRAY_MODULE_H | ||||
							
								
								
									
										32
									
								
								latan/Eigen/Cholesky
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								latan/Eigen/Cholesky
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| #ifndef EIGEN_CHOLESKY_MODULE_H | ||||
| #define EIGEN_CHOLESKY_MODULE_H | ||||
|  | ||||
| #include "Core" | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| /** \defgroup Cholesky_Module Cholesky module | ||||
|   * | ||||
|   * | ||||
|   * | ||||
|   * This module provides two variants of the Cholesky decomposition for selfadjoint (hermitian) matrices. | ||||
|   * Those decompositions are accessible via the following MatrixBase methods: | ||||
|   *  - MatrixBase::llt(), | ||||
|   *  - MatrixBase::ldlt() | ||||
|   * | ||||
|   * \code | ||||
|   * #include <Eigen/Cholesky> | ||||
|   * \endcode | ||||
|   */ | ||||
|  | ||||
| #include "src/misc/Solve.h" | ||||
| #include "src/Cholesky/LLT.h" | ||||
| #include "src/Cholesky/LDLT.h" | ||||
| #ifdef EIGEN_USE_LAPACKE | ||||
| #include "src/Cholesky/LLT_MKL.h" | ||||
| #endif | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #endif // EIGEN_CHOLESKY_MODULE_H | ||||
| /* vim: set filetype=cpp et sw=2 ts=2 ai: */ | ||||
							
								
								
									
										45
									
								
								latan/Eigen/CholmodSupport
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								latan/Eigen/CholmodSupport
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| #ifndef EIGEN_CHOLMODSUPPORT_MODULE_H | ||||
| #define EIGEN_CHOLMODSUPPORT_MODULE_H | ||||
|  | ||||
| #include "SparseCore" | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| extern "C" { | ||||
|   #include <cholmod.h> | ||||
| } | ||||
|  | ||||
| /** \ingroup Support_modules | ||||
|   * \defgroup CholmodSupport_Module CholmodSupport module | ||||
|   * | ||||
|   * This module provides an interface to the Cholmod library which is part of the <a href="http://www.cise.ufl.edu/research/sparse/SuiteSparse/">suitesparse</a> package. | ||||
|   * It provides the two following main factorization classes: | ||||
|   * - class CholmodSupernodalLLT: a supernodal LLT Cholesky factorization. | ||||
|   * - class CholmodDecomposiiton: a general L(D)LT Cholesky factorization with automatic or explicit runtime selection of the underlying factorization method (supernodal or simplicial). | ||||
|   * | ||||
|   * For the sake of completeness, this module also propose the two following classes: | ||||
|   * - class CholmodSimplicialLLT | ||||
|   * - class CholmodSimplicialLDLT | ||||
|   * Note that these classes does not bring any particular advantage compared to the built-in | ||||
|   * SimplicialLLT and SimplicialLDLT factorization classes. | ||||
|   * | ||||
|   * \code | ||||
|   * #include <Eigen/CholmodSupport> | ||||
|   * \endcode | ||||
|   * | ||||
|   * In order to use this module, the cholmod headers must be accessible from the include paths, and your binary must be linked to the cholmod library and its dependencies. | ||||
|   * The dependencies depend on how cholmod has been compiled. | ||||
|   * For a cmake based project, you can use our FindCholmod.cmake module to help you in this task. | ||||
|   * | ||||
|   */ | ||||
|  | ||||
| #include "src/misc/Solve.h" | ||||
| #include "src/misc/SparseSolve.h" | ||||
|  | ||||
| #include "src/CholmodSupport/CholmodSupport.h" | ||||
|  | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #endif // EIGEN_CHOLMODSUPPORT_MODULE_H | ||||
|  | ||||
							
								
								
									
										366
									
								
								latan/Eigen/Core
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										366
									
								
								latan/Eigen/Core
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,366 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2007-2011 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_CORE_H | ||||
| #define EIGEN_CORE_H | ||||
|  | ||||
| // first thing Eigen does: stop the compiler from committing suicide | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| // then include this file where all our macros are defined. It's really important to do it first because | ||||
| // it's where we do all the alignment settings (platform detection and honoring the user's will if he | ||||
| // defined e.g. EIGEN_DONT_ALIGN) so it needs to be done before we do anything with vectorization. | ||||
| #include "src/Core/util/Macros.h" | ||||
|  | ||||
| #include <complex> | ||||
|  | ||||
| // this include file manages BLAS and MKL related macros | ||||
| // and inclusion of their respective header files | ||||
| #include "src/Core/util/MKL_support.h" | ||||
|  | ||||
| // if alignment is disabled, then disable vectorization. Note: EIGEN_ALIGN is the proper check, it takes into | ||||
| // account both the user's will (EIGEN_DONT_ALIGN) and our own platform checks | ||||
| #if !EIGEN_ALIGN | ||||
|   #ifndef EIGEN_DONT_VECTORIZE | ||||
|     #define EIGEN_DONT_VECTORIZE | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
| #ifdef _MSC_VER | ||||
|   #include <malloc.h> // for _aligned_malloc -- need it regardless of whether vectorization is enabled | ||||
|   #if (_MSC_VER >= 1500) // 2008 or later | ||||
|     // Remember that usage of defined() in a #define is undefined by the standard. | ||||
|     // a user reported that in 64-bit mode, MSVC doesn't care to define _M_IX86_FP. | ||||
|     #if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(_M_X64) | ||||
|       #define EIGEN_SSE2_ON_MSVC_2008_OR_LATER | ||||
|     #endif | ||||
|   #endif | ||||
| #else | ||||
|   // Remember that usage of defined() in a #define is undefined by the standard | ||||
|   #if (defined __SSE2__) && ( (!defined __GNUC__) || (defined __INTEL_COMPILER) || EIGEN_GNUC_AT_LEAST(4,2) ) | ||||
|     #define EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
| #ifndef EIGEN_DONT_VECTORIZE | ||||
|  | ||||
|   #if defined (EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER) | ||||
|  | ||||
|     // Defines symbols for compile-time detection of which instructions are | ||||
|     // used. | ||||
|     // EIGEN_VECTORIZE_YY is defined if and only if the instruction set YY is used | ||||
|     #define EIGEN_VECTORIZE | ||||
|     #define EIGEN_VECTORIZE_SSE | ||||
|     #define EIGEN_VECTORIZE_SSE2 | ||||
|  | ||||
|     // Detect sse3/ssse3/sse4: | ||||
|     // gcc and icc defines __SSE3__, ... | ||||
|     // there is no way to know about this on msvc. You can define EIGEN_VECTORIZE_SSE* if you | ||||
|     // want to force the use of those instructions with msvc. | ||||
|     #ifdef __SSE3__ | ||||
|       #define EIGEN_VECTORIZE_SSE3 | ||||
|     #endif | ||||
|     #ifdef __SSSE3__ | ||||
|       #define EIGEN_VECTORIZE_SSSE3 | ||||
|     #endif | ||||
|     #ifdef __SSE4_1__ | ||||
|       #define EIGEN_VECTORIZE_SSE4_1 | ||||
|     #endif | ||||
|     #ifdef __SSE4_2__ | ||||
|       #define EIGEN_VECTORIZE_SSE4_2 | ||||
|     #endif | ||||
|  | ||||
|     // include files | ||||
|  | ||||
|     // This extern "C" works around a MINGW-w64 compilation issue | ||||
|     // https://sourceforge.net/tracker/index.php?func=detail&aid=3018394&group_id=202880&atid=983354 | ||||
|     // In essence, intrin.h is included by windows.h and also declares intrinsics (just as emmintrin.h etc. below do). | ||||
|     // However, intrin.h uses an extern "C" declaration, and g++ thus complains of duplicate declarations | ||||
|     // with conflicting linkage.  The linkage for intrinsics doesn't matter, but at that stage the compiler doesn't know; | ||||
|     // so, to avoid compile errors when windows.h is included after Eigen/Core, ensure intrinsics are extern "C" here too. | ||||
|     // notice that since these are C headers, the extern "C" is theoretically needed anyways. | ||||
|     extern "C" { | ||||
|       #include <emmintrin.h> | ||||
|       #include <xmmintrin.h> | ||||
|       #ifdef  EIGEN_VECTORIZE_SSE3 | ||||
|       #include <pmmintrin.h> | ||||
|       #endif | ||||
|       #ifdef EIGEN_VECTORIZE_SSSE3 | ||||
|       #include <tmmintrin.h> | ||||
|       #endif | ||||
|       #ifdef EIGEN_VECTORIZE_SSE4_1 | ||||
|       #include <smmintrin.h> | ||||
|       #endif | ||||
|       #ifdef EIGEN_VECTORIZE_SSE4_2 | ||||
|       #include <nmmintrin.h> | ||||
|       #endif | ||||
|     } // end extern "C" | ||||
|   #elif defined __ALTIVEC__ | ||||
|     #define EIGEN_VECTORIZE | ||||
|     #define EIGEN_VECTORIZE_ALTIVEC | ||||
|     #include <altivec.h> | ||||
|     // We need to #undef all these ugly tokens defined in <altivec.h> | ||||
|     // => use __vector instead of vector | ||||
|     #undef bool | ||||
|     #undef vector | ||||
|     #undef pixel | ||||
|   #elif defined  __ARM_NEON__ | ||||
|     #define EIGEN_VECTORIZE | ||||
|     #define EIGEN_VECTORIZE_NEON | ||||
|     #include <arm_neon.h> | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
| #if (defined _OPENMP) && (!defined EIGEN_DONT_PARALLELIZE) | ||||
|   #define EIGEN_HAS_OPENMP | ||||
| #endif | ||||
|  | ||||
| #ifdef EIGEN_HAS_OPENMP | ||||
| #include <omp.h> | ||||
| #endif | ||||
|  | ||||
| // MSVC for windows mobile does not have the errno.h file | ||||
| #if !(defined(_MSC_VER) && defined(_WIN32_WCE)) && !defined(__ARMCC_VERSION) | ||||
| #define EIGEN_HAS_ERRNO | ||||
| #endif | ||||
|  | ||||
| #ifdef EIGEN_HAS_ERRNO | ||||
| #include <cerrno> | ||||
| #endif | ||||
| #include <cstddef> | ||||
| #include <cstdlib> | ||||
| #include <cmath> | ||||
| #include <cassert> | ||||
| #include <functional> | ||||
| #include <iosfwd> | ||||
| #include <cstring> | ||||
| #include <string> | ||||
| #include <limits> | ||||
| #include <climits> // for CHAR_BIT | ||||
| // for min/max: | ||||
| #include <algorithm> | ||||
|  | ||||
| // for outputting debug info | ||||
| #ifdef EIGEN_DEBUG_ASSIGN | ||||
| #include <iostream> | ||||
| #endif | ||||
|  | ||||
| // required for __cpuid, needs to be included after cmath | ||||
| #if defined(_MSC_VER) && (defined(_M_IX86)||defined(_M_X64)) | ||||
|   #include <intrin.h> | ||||
| #endif | ||||
|  | ||||
| #if defined(_CPPUNWIND) || defined(__EXCEPTIONS) | ||||
|   #define EIGEN_EXCEPTIONS | ||||
| #endif | ||||
|  | ||||
| #ifdef EIGEN_EXCEPTIONS | ||||
|   #include <new> | ||||
| #endif | ||||
|  | ||||
| /** \brief Namespace containing all symbols from the %Eigen library. */ | ||||
| namespace Eigen { | ||||
|  | ||||
| inline static const char *SimdInstructionSetsInUse(void) { | ||||
| #if defined(EIGEN_VECTORIZE_SSE4_2) | ||||
|   return "SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2"; | ||||
| #elif defined(EIGEN_VECTORIZE_SSE4_1) | ||||
|   return "SSE, SSE2, SSE3, SSSE3, SSE4.1"; | ||||
| #elif defined(EIGEN_VECTORIZE_SSSE3) | ||||
|   return "SSE, SSE2, SSE3, SSSE3"; | ||||
| #elif defined(EIGEN_VECTORIZE_SSE3) | ||||
|   return "SSE, SSE2, SSE3"; | ||||
| #elif defined(EIGEN_VECTORIZE_SSE2) | ||||
|   return "SSE, SSE2"; | ||||
| #elif defined(EIGEN_VECTORIZE_ALTIVEC) | ||||
|   return "AltiVec"; | ||||
| #elif defined(EIGEN_VECTORIZE_NEON) | ||||
|   return "ARM NEON"; | ||||
| #else | ||||
|   return "None"; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #define STAGE10_FULL_EIGEN2_API             10 | ||||
| #define STAGE20_RESOLVE_API_CONFLICTS       20 | ||||
| #define STAGE30_FULL_EIGEN3_API             30 | ||||
| #define STAGE40_FULL_EIGEN3_STRICTNESS      40 | ||||
| #define STAGE99_NO_EIGEN2_SUPPORT           99 | ||||
|  | ||||
| #if   defined EIGEN2_SUPPORT_STAGE40_FULL_EIGEN3_STRICTNESS | ||||
|   #define EIGEN2_SUPPORT | ||||
|   #define EIGEN2_SUPPORT_STAGE STAGE40_FULL_EIGEN3_STRICTNESS | ||||
| #elif defined EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API | ||||
|   #define EIGEN2_SUPPORT | ||||
|   #define EIGEN2_SUPPORT_STAGE STAGE30_FULL_EIGEN3_API | ||||
| #elif defined EIGEN2_SUPPORT_STAGE20_RESOLVE_API_CONFLICTS | ||||
|   #define EIGEN2_SUPPORT | ||||
|   #define EIGEN2_SUPPORT_STAGE STAGE20_RESOLVE_API_CONFLICTS | ||||
| #elif defined EIGEN2_SUPPORT_STAGE10_FULL_EIGEN2_API | ||||
|   #define EIGEN2_SUPPORT | ||||
|   #define EIGEN2_SUPPORT_STAGE STAGE10_FULL_EIGEN2_API | ||||
| #elif defined EIGEN2_SUPPORT | ||||
|   // default to stage 3, that's what it's always meant | ||||
|   #define EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API | ||||
|   #define EIGEN2_SUPPORT_STAGE STAGE30_FULL_EIGEN3_API | ||||
| #else | ||||
|   #define EIGEN2_SUPPORT_STAGE STAGE99_NO_EIGEN2_SUPPORT | ||||
| #endif | ||||
|  | ||||
| #ifdef EIGEN2_SUPPORT | ||||
| #undef minor | ||||
| #endif | ||||
|  | ||||
| // we use size_t frequently and we'll never remember to prepend it with std:: everytime just to | ||||
| // ensure QNX/QCC support | ||||
| using std::size_t; | ||||
| // gcc 4.6.0 wants std:: for ptrdiff_t  | ||||
| using std::ptrdiff_t; | ||||
|  | ||||
| /** \defgroup Core_Module Core module | ||||
|   * This is the main module of Eigen providing dense matrix and vector support | ||||
|   * (both fixed and dynamic size) with all the features corresponding to a BLAS library | ||||
|   * and much more... | ||||
|   * | ||||
|   * \code | ||||
|   * #include <Eigen/Core> | ||||
|   * \endcode | ||||
|   */ | ||||
|  | ||||
| /** \defgroup Support_modules Support modules [category] | ||||
|   * Category of modules which add support for external libraries. | ||||
|   */ | ||||
|  | ||||
| #include "src/Core/util/Constants.h" | ||||
| #include "src/Core/util/ForwardDeclarations.h" | ||||
| #include "src/Core/util/Meta.h" | ||||
| #include "src/Core/util/XprHelper.h" | ||||
| #include "src/Core/util/StaticAssert.h" | ||||
| #include "src/Core/util/Memory.h" | ||||
|  | ||||
| #include "src/Core/NumTraits.h" | ||||
| #include "src/Core/MathFunctions.h" | ||||
| #include "src/Core/GenericPacketMath.h" | ||||
|  | ||||
| #if defined EIGEN_VECTORIZE_SSE | ||||
|   #include "src/Core/arch/SSE/PacketMath.h" | ||||
|   #include "src/Core/arch/SSE/MathFunctions.h" | ||||
|   #include "src/Core/arch/SSE/Complex.h" | ||||
| #elif defined EIGEN_VECTORIZE_ALTIVEC | ||||
|   #include "src/Core/arch/AltiVec/PacketMath.h" | ||||
|   #include "src/Core/arch/AltiVec/Complex.h" | ||||
| #elif defined EIGEN_VECTORIZE_NEON | ||||
|   #include "src/Core/arch/NEON/PacketMath.h" | ||||
|   #include "src/Core/arch/NEON/Complex.h" | ||||
| #endif | ||||
|  | ||||
| #include "src/Core/arch/Default/Settings.h" | ||||
|  | ||||
| #include "src/Core/Functors.h" | ||||
| #include "src/Core/DenseCoeffsBase.h" | ||||
| #include "src/Core/DenseBase.h" | ||||
| #include "src/Core/MatrixBase.h" | ||||
| #include "src/Core/EigenBase.h" | ||||
|  | ||||
| #ifndef EIGEN_PARSED_BY_DOXYGEN // work around Doxygen bug triggered by Assign.h r814874 | ||||
|                                 // at least confirmed with Doxygen 1.5.5 and 1.5.6 | ||||
|   #include "src/Core/Assign.h" | ||||
| #endif | ||||
|  | ||||
| #include "src/Core/util/BlasUtil.h" | ||||
| #include "src/Core/DenseStorage.h" | ||||
| #include "src/Core/NestByValue.h" | ||||
| #include "src/Core/ForceAlignedAccess.h" | ||||
| #include "src/Core/ReturnByValue.h" | ||||
| #include "src/Core/NoAlias.h" | ||||
| #include "src/Core/PlainObjectBase.h" | ||||
| #include "src/Core/Matrix.h" | ||||
| #include "src/Core/Array.h" | ||||
| #include "src/Core/CwiseBinaryOp.h" | ||||
| #include "src/Core/CwiseUnaryOp.h" | ||||
| #include "src/Core/CwiseNullaryOp.h" | ||||
| #include "src/Core/CwiseUnaryView.h" | ||||
| #include "src/Core/SelfCwiseBinaryOp.h" | ||||
| #include "src/Core/Dot.h" | ||||
| #include "src/Core/StableNorm.h" | ||||
| #include "src/Core/MapBase.h" | ||||
| #include "src/Core/Stride.h" | ||||
| #include "src/Core/Map.h" | ||||
| #include "src/Core/Block.h" | ||||
| #include "src/Core/VectorBlock.h" | ||||
| #include "src/Core/Transpose.h" | ||||
| #include "src/Core/DiagonalMatrix.h" | ||||
| #include "src/Core/Diagonal.h" | ||||
| #include "src/Core/DiagonalProduct.h" | ||||
| #include "src/Core/PermutationMatrix.h" | ||||
| #include "src/Core/Transpositions.h" | ||||
| #include "src/Core/Redux.h" | ||||
| #include "src/Core/Visitor.h" | ||||
| #include "src/Core/Fuzzy.h" | ||||
| #include "src/Core/IO.h" | ||||
| #include "src/Core/Swap.h" | ||||
| #include "src/Core/CommaInitializer.h" | ||||
| #include "src/Core/Flagged.h" | ||||
| #include "src/Core/ProductBase.h" | ||||
| #include "src/Core/GeneralProduct.h" | ||||
| #include "src/Core/TriangularMatrix.h" | ||||
| #include "src/Core/SelfAdjointView.h" | ||||
| #include "src/Core/products/GeneralBlockPanelKernel.h" | ||||
| #include "src/Core/products/Parallelizer.h" | ||||
| #include "src/Core/products/CoeffBasedProduct.h" | ||||
| #include "src/Core/products/GeneralMatrixVector.h" | ||||
| #include "src/Core/products/GeneralMatrixMatrix.h" | ||||
| #include "src/Core/SolveTriangular.h" | ||||
| #include "src/Core/products/GeneralMatrixMatrixTriangular.h" | ||||
| #include "src/Core/products/SelfadjointMatrixVector.h" | ||||
| #include "src/Core/products/SelfadjointMatrixMatrix.h" | ||||
| #include "src/Core/products/SelfadjointProduct.h" | ||||
| #include "src/Core/products/SelfadjointRank2Update.h" | ||||
| #include "src/Core/products/TriangularMatrixVector.h" | ||||
| #include "src/Core/products/TriangularMatrixMatrix.h" | ||||
| #include "src/Core/products/TriangularSolverMatrix.h" | ||||
| #include "src/Core/products/TriangularSolverVector.h" | ||||
| #include "src/Core/BandMatrix.h" | ||||
|  | ||||
| #include "src/Core/BooleanRedux.h" | ||||
| #include "src/Core/Select.h" | ||||
| #include "src/Core/VectorwiseOp.h" | ||||
| #include "src/Core/Random.h" | ||||
| #include "src/Core/Replicate.h" | ||||
| #include "src/Core/Reverse.h" | ||||
| #include "src/Core/ArrayBase.h" | ||||
| #include "src/Core/ArrayWrapper.h" | ||||
|  | ||||
| #ifdef EIGEN_USE_BLAS | ||||
| #include "src/Core/products/GeneralMatrixMatrix_MKL.h" | ||||
| #include "src/Core/products/GeneralMatrixVector_MKL.h" | ||||
| #include "src/Core/products/GeneralMatrixMatrixTriangular_MKL.h" | ||||
| #include "src/Core/products/SelfadjointMatrixMatrix_MKL.h" | ||||
| #include "src/Core/products/SelfadjointMatrixVector_MKL.h" | ||||
| #include "src/Core/products/TriangularMatrixMatrix_MKL.h" | ||||
| #include "src/Core/products/TriangularMatrixVector_MKL.h" | ||||
| #include "src/Core/products/TriangularSolverMatrix_MKL.h" | ||||
| #endif // EIGEN_USE_BLAS | ||||
|  | ||||
| #ifdef EIGEN_USE_MKL_VML | ||||
| #include "src/Core/Assign_MKL.h" | ||||
| #endif | ||||
|  | ||||
| #include "src/Core/GlobalFunctions.h" | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #ifdef EIGEN2_SUPPORT | ||||
| #include "Eigen2Support" | ||||
| #endif | ||||
|  | ||||
| #endif // EIGEN_CORE_H | ||||
							
								
								
									
										7
									
								
								latan/Eigen/Dense
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								latan/Eigen/Dense
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| #include "Core" | ||||
| #include "LU" | ||||
| #include "Cholesky" | ||||
| #include "QR" | ||||
| #include "SVD" | ||||
| #include "Geometry" | ||||
| #include "Eigenvalues" | ||||
							
								
								
									
										2
									
								
								latan/Eigen/Eigen
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								latan/Eigen/Eigen
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| #include "Dense" | ||||
| //#include "Sparse" | ||||
							
								
								
									
										82
									
								
								latan/Eigen/Eigen2Support
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								latan/Eigen/Eigen2Support
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN2SUPPORT_H | ||||
| #define EIGEN2SUPPORT_H | ||||
|  | ||||
| #if (!defined(EIGEN2_SUPPORT)) || (!defined(EIGEN_CORE_H)) | ||||
| #error Eigen2 support must be enabled by defining EIGEN2_SUPPORT before including any Eigen header | ||||
| #endif | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| /** \ingroup Support_modules | ||||
|   * \defgroup Eigen2Support_Module Eigen2 support module | ||||
|   * This module provides a couple of deprecated functions improving the compatibility with Eigen2. | ||||
|   * | ||||
|   * To use it, define EIGEN2_SUPPORT before including any Eigen header | ||||
|   * \code | ||||
|   * #define EIGEN2_SUPPORT | ||||
|   * \endcode | ||||
|   * | ||||
|   */ | ||||
|  | ||||
| #include "src/Eigen2Support/Macros.h" | ||||
| #include "src/Eigen2Support/Memory.h" | ||||
| #include "src/Eigen2Support/Meta.h" | ||||
| #include "src/Eigen2Support/Lazy.h" | ||||
| #include "src/Eigen2Support/Cwise.h" | ||||
| #include "src/Eigen2Support/CwiseOperators.h" | ||||
| #include "src/Eigen2Support/TriangularSolver.h" | ||||
| #include "src/Eigen2Support/Block.h" | ||||
| #include "src/Eigen2Support/VectorBlock.h" | ||||
| #include "src/Eigen2Support/Minor.h" | ||||
| #include "src/Eigen2Support/MathFunctions.h" | ||||
|  | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| // Eigen2 used to include iostream | ||||
| #include<iostream> | ||||
|  | ||||
| #define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \ | ||||
| using Eigen::Matrix##SizeSuffix##TypeSuffix; \ | ||||
| using Eigen::Vector##SizeSuffix##TypeSuffix; \ | ||||
| using Eigen::RowVector##SizeSuffix##TypeSuffix; | ||||
|  | ||||
| #define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(TypeSuffix) \ | ||||
| EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \ | ||||
| EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \ | ||||
| EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \ | ||||
| EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \ | ||||
|  | ||||
| #define EIGEN_USING_MATRIX_TYPEDEFS \ | ||||
| EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(i) \ | ||||
| EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(f) \ | ||||
| EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(d) \ | ||||
| EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cf) \ | ||||
| EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cd) | ||||
|  | ||||
| #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; | ||||
|  | ||||
| #endif // EIGEN2SUPPORT_H | ||||
							
								
								
									
										46
									
								
								latan/Eigen/Eigenvalues
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								latan/Eigen/Eigenvalues
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| #ifndef EIGEN_EIGENVALUES_MODULE_H | ||||
| #define EIGEN_EIGENVALUES_MODULE_H | ||||
|  | ||||
| #include "Core" | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| #include "Cholesky" | ||||
| #include "Jacobi" | ||||
| #include "Householder" | ||||
| #include "LU" | ||||
| #include "Geometry" | ||||
|  | ||||
| /** \defgroup Eigenvalues_Module Eigenvalues module | ||||
|   * | ||||
|   * | ||||
|   * | ||||
|   * This module mainly provides various eigenvalue solvers. | ||||
|   * This module also provides some MatrixBase methods, including: | ||||
|   *  - MatrixBase::eigenvalues(), | ||||
|   *  - MatrixBase::operatorNorm() | ||||
|   * | ||||
|   * \code | ||||
|   * #include <Eigen/Eigenvalues> | ||||
|   * \endcode | ||||
|   */ | ||||
|  | ||||
| #include "src/Eigenvalues/Tridiagonalization.h" | ||||
| #include "src/Eigenvalues/RealSchur.h" | ||||
| #include "src/Eigenvalues/EigenSolver.h" | ||||
| #include "src/Eigenvalues/SelfAdjointEigenSolver.h" | ||||
| #include "src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h" | ||||
| #include "src/Eigenvalues/HessenbergDecomposition.h" | ||||
| #include "src/Eigenvalues/ComplexSchur.h" | ||||
| #include "src/Eigenvalues/ComplexEigenSolver.h" | ||||
| #include "src/Eigenvalues/MatrixBaseEigenvalues.h" | ||||
| #ifdef EIGEN_USE_LAPACKE | ||||
| #include "src/Eigenvalues/RealSchur_MKL.h" | ||||
| #include "src/Eigenvalues/ComplexSchur_MKL.h" | ||||
| #include "src/Eigenvalues/SelfAdjointEigenSolver_MKL.h" | ||||
| #endif | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #endif // EIGEN_EIGENVALUES_MODULE_H | ||||
| /* vim: set filetype=cpp et sw=2 ts=2 ai: */ | ||||
							
								
								
									
										63
									
								
								latan/Eigen/Geometry
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								latan/Eigen/Geometry
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| #ifndef EIGEN_GEOMETRY_MODULE_H | ||||
| #define EIGEN_GEOMETRY_MODULE_H | ||||
|  | ||||
| #include "Core" | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| #include "SVD" | ||||
| #include "LU" | ||||
| #include <limits> | ||||
|  | ||||
| #ifndef M_PI | ||||
| #define M_PI 3.14159265358979323846 | ||||
| #endif | ||||
|  | ||||
| /** \defgroup Geometry_Module Geometry module | ||||
|   * | ||||
|   * | ||||
|   * | ||||
|   * This module provides support for: | ||||
|   *  - fixed-size homogeneous transformations | ||||
|   *  - translation, scaling, 2D and 3D rotations | ||||
|   *  - quaternions | ||||
|   *  - \ref MatrixBase::cross() "cross product" | ||||
|   *  - \ref MatrixBase::unitOrthogonal() "orthognal vector generation" | ||||
|   *  - some linear components: parametrized-lines and hyperplanes | ||||
|   * | ||||
|   * \code | ||||
|   * #include <Eigen/Geometry> | ||||
|   * \endcode | ||||
|   */ | ||||
|  | ||||
| #include "src/Geometry/OrthoMethods.h" | ||||
| #include "src/Geometry/EulerAngles.h" | ||||
|  | ||||
| #if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS | ||||
|   #include "src/Geometry/Homogeneous.h" | ||||
|   #include "src/Geometry/RotationBase.h" | ||||
|   #include "src/Geometry/Rotation2D.h" | ||||
|   #include "src/Geometry/Quaternion.h" | ||||
|   #include "src/Geometry/AngleAxis.h" | ||||
|   #include "src/Geometry/Transform.h" | ||||
|   #include "src/Geometry/Translation.h" | ||||
|   #include "src/Geometry/Scaling.h" | ||||
|   #include "src/Geometry/Hyperplane.h" | ||||
|   #include "src/Geometry/ParametrizedLine.h" | ||||
|   #include "src/Geometry/AlignedBox.h" | ||||
|   #include "src/Geometry/Umeyama.h" | ||||
|  | ||||
|   #if defined EIGEN_VECTORIZE_SSE | ||||
|     #include "src/Geometry/arch/Geometry_SSE.h" | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
| #ifdef EIGEN2_SUPPORT | ||||
| #include "src/Eigen2Support/Geometry/All.h" | ||||
| #endif | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #endif // EIGEN_GEOMETRY_MODULE_H | ||||
| /* vim: set filetype=cpp et sw=2 ts=2 ai: */ | ||||
|  | ||||
							
								
								
									
										23
									
								
								latan/Eigen/Householder
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								latan/Eigen/Householder
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| #ifndef EIGEN_HOUSEHOLDER_MODULE_H | ||||
| #define EIGEN_HOUSEHOLDER_MODULE_H | ||||
|  | ||||
| #include "Core" | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| /** \defgroup Householder_Module Householder module | ||||
|   * This module provides Householder transformations. | ||||
|   * | ||||
|   * \code | ||||
|   * #include <Eigen/Householder> | ||||
|   * \endcode | ||||
|   */ | ||||
|  | ||||
| #include "src/Householder/Householder.h" | ||||
| #include "src/Householder/HouseholderSequence.h" | ||||
| #include "src/Householder/BlockHouseholder.h" | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #endif // EIGEN_HOUSEHOLDER_MODULE_H | ||||
| /* vim: set filetype=cpp et sw=2 ts=2 ai: */ | ||||
							
								
								
									
										40
									
								
								latan/Eigen/IterativeLinearSolvers
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								latan/Eigen/IterativeLinearSolvers
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| #ifndef EIGEN_ITERATIVELINEARSOLVERS_MODULE_H | ||||
| #define EIGEN_ITERATIVELINEARSOLVERS_MODULE_H | ||||
|  | ||||
| #include "SparseCore" | ||||
| #include "OrderingMethods" | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| /** \ingroup Sparse_modules | ||||
|   * \defgroup IterativeLinearSolvers_Module IterativeLinearSolvers module | ||||
|   * | ||||
|   * This module currently provides iterative methods to solve problems of the form \c A \c x = \c b, where \c A is a squared matrix, usually very large and sparse. | ||||
|   * Those solvers are accessible via the following classes: | ||||
|   *  - ConjugateGradient for selfadjoint (hermitian) matrices, | ||||
|   *  - BiCGSTAB for general square matrices. | ||||
|   * | ||||
|   * These iterative solvers are associated with some preconditioners: | ||||
|   *  - IdentityPreconditioner - not really useful | ||||
|   *  - DiagonalPreconditioner - also called JAcobi preconditioner, work very well on diagonal dominant matrices. | ||||
|   *  - IncompleteILUT - incomplete LU factorization with dual thresholding | ||||
|   * | ||||
|   * Such problems can also be solved using the direct sparse decomposition modules: SparseCholesky, CholmodSupport, UmfPackSupport, SuperLUSupport. | ||||
|   * | ||||
|   * \code | ||||
|   * #include <Eigen/IterativeLinearSolvers> | ||||
|   * \endcode | ||||
|   */ | ||||
|  | ||||
| #include "src/misc/Solve.h" | ||||
| #include "src/misc/SparseSolve.h" | ||||
|  | ||||
| #include "src/IterativeLinearSolvers/IterativeSolverBase.h" | ||||
| #include "src/IterativeLinearSolvers/BasicPreconditioners.h" | ||||
| #include "src/IterativeLinearSolvers/ConjugateGradient.h" | ||||
| #include "src/IterativeLinearSolvers/BiCGSTAB.h" | ||||
| #include "src/IterativeLinearSolvers/IncompleteLUT.h" | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #endif // EIGEN_ITERATIVELINEARSOLVERS_MODULE_H | ||||
							
								
								
									
										26
									
								
								latan/Eigen/Jacobi
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								latan/Eigen/Jacobi
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| #ifndef EIGEN_JACOBI_MODULE_H | ||||
| #define EIGEN_JACOBI_MODULE_H | ||||
|  | ||||
| #include "Core" | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| /** \defgroup Jacobi_Module Jacobi module | ||||
|   * This module provides Jacobi and Givens rotations. | ||||
|   * | ||||
|   * \code | ||||
|   * #include <Eigen/Jacobi> | ||||
|   * \endcode | ||||
|   * | ||||
|   * In addition to listed classes, it defines the two following MatrixBase methods to apply a Jacobi or Givens rotation: | ||||
|   *  - MatrixBase::applyOnTheLeft() | ||||
|   *  - MatrixBase::applyOnTheRight(). | ||||
|   */ | ||||
|  | ||||
| #include "src/Jacobi/Jacobi.h" | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #endif // EIGEN_JACOBI_MODULE_H | ||||
| /* vim: set filetype=cpp et sw=2 ts=2 ai: */ | ||||
|  | ||||
							
								
								
									
										41
									
								
								latan/Eigen/LU
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								latan/Eigen/LU
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| #ifndef EIGEN_LU_MODULE_H | ||||
| #define EIGEN_LU_MODULE_H | ||||
|  | ||||
| #include "Core" | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| /** \defgroup LU_Module LU module | ||||
|   * This module includes %LU decomposition and related notions such as matrix inversion and determinant. | ||||
|   * This module defines the following MatrixBase methods: | ||||
|   *  - MatrixBase::inverse() | ||||
|   *  - MatrixBase::determinant() | ||||
|   * | ||||
|   * \code | ||||
|   * #include <Eigen/LU> | ||||
|   * \endcode | ||||
|   */ | ||||
|  | ||||
| #include "src/misc/Solve.h" | ||||
| #include "src/misc/Kernel.h" | ||||
| #include "src/misc/Image.h" | ||||
| #include "src/LU/FullPivLU.h" | ||||
| #include "src/LU/PartialPivLU.h" | ||||
| #ifdef EIGEN_USE_LAPACKE | ||||
| #include "src/LU/PartialPivLU_MKL.h" | ||||
| #endif | ||||
| #include "src/LU/Determinant.h" | ||||
| #include "src/LU/Inverse.h" | ||||
|  | ||||
| #if defined EIGEN_VECTORIZE_SSE | ||||
|   #include "src/LU/arch/Inverse_SSE.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef EIGEN2_SUPPORT | ||||
|   #include "src/Eigen2Support/LU.h" | ||||
| #endif | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #endif // EIGEN_LU_MODULE_H | ||||
| /* vim: set filetype=cpp et sw=2 ts=2 ai: */ | ||||
							
								
								
									
										32
									
								
								latan/Eigen/LeastSquares
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								latan/Eigen/LeastSquares
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| #ifndef EIGEN_REGRESSION_MODULE_H | ||||
| #define EIGEN_REGRESSION_MODULE_H | ||||
|  | ||||
| #ifndef EIGEN2_SUPPORT | ||||
| #error LeastSquares is only available in Eigen2 support mode (define EIGEN2_SUPPORT) | ||||
| #endif | ||||
|  | ||||
| // exclude from normal eigen3-only documentation | ||||
| #ifdef EIGEN2_SUPPORT | ||||
|  | ||||
| #include "Core" | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| #include "Eigenvalues" | ||||
| #include "Geometry" | ||||
|  | ||||
| /** \defgroup LeastSquares_Module LeastSquares module | ||||
|   * This module provides linear regression and related features. | ||||
|   * | ||||
|   * \code | ||||
|   * #include <Eigen/LeastSquares> | ||||
|   * \endcode | ||||
|   */ | ||||
|  | ||||
| #include "src/Eigen2Support/LeastSquares.h" | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #endif // EIGEN2_SUPPORT | ||||
|  | ||||
| #endif // EIGEN_REGRESSION_MODULE_H | ||||
							
								
								
									
										23
									
								
								latan/Eigen/OrderingMethods
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								latan/Eigen/OrderingMethods
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| #ifndef EIGEN_ORDERINGMETHODS_MODULE_H | ||||
| #define EIGEN_ORDERINGMETHODS_MODULE_H | ||||
|  | ||||
| #include "SparseCore" | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| /** \ingroup Sparse_modules | ||||
|   * \defgroup OrderingMethods_Module OrderingMethods module | ||||
|   * | ||||
|   * This module is currently for internal use only. | ||||
|   * | ||||
|   * | ||||
|   * \code | ||||
|   * #include <Eigen/OrderingMethods> | ||||
|   * \endcode | ||||
|   */ | ||||
|  | ||||
| #include "src/OrderingMethods/Amd.h" | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #endif // EIGEN_ORDERINGMETHODS_MODULE_H | ||||
							
								
								
									
										46
									
								
								latan/Eigen/PaStiXSupport
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								latan/Eigen/PaStiXSupport
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| #ifndef EIGEN_PASTIXSUPPORT_MODULE_H | ||||
| #define EIGEN_PASTIXSUPPORT_MODULE_H | ||||
|  | ||||
| #include "SparseCore" | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| #include <complex.h> | ||||
| extern "C" { | ||||
| #include <pastix_nompi.h> | ||||
| #include <pastix.h> | ||||
| } | ||||
|  | ||||
| #ifdef complex | ||||
| #undef complex | ||||
| #endif | ||||
|  | ||||
| /** \ingroup Support_modules | ||||
|   * \defgroup PaStiXSupport_Module PaStiXSupport module | ||||
|   *  | ||||
|   * This module provides an interface to the <a href="http://pastix.gforge.inria.fr/">PaSTiX</a> library. | ||||
|   * PaSTiX is a general \b supernodal, \b parallel and \b opensource sparse solver. | ||||
|   * It provides the two following main factorization classes: | ||||
|   * - class PastixLLT : a supernodal, parallel LLt Cholesky factorization. | ||||
|   * - class PastixLDLT: a supernodal, parallel LDLt Cholesky factorization. | ||||
|   * - class PastixLU : a supernodal, parallel LU factorization (optimized for a symmetric pattern). | ||||
|   *  | ||||
|   * \code | ||||
|   * #include <Eigen/PaStiXSupport> | ||||
|   * \endcode | ||||
|   * | ||||
|   * In order to use this module, the PaSTiX headers must be accessible from the include paths, and your binary must be linked to the PaSTiX library and its dependencies. | ||||
|   * The dependencies depend on how PaSTiX has been compiled. | ||||
|   * For a cmake based project, you can use our FindPaSTiX.cmake module to help you in this task. | ||||
|   * | ||||
|   */ | ||||
|  | ||||
| #include "src/misc/Solve.h" | ||||
| #include "src/misc/SparseSolve.h" | ||||
|  | ||||
| #include "src/PaStiXSupport/PaStiXSupport.h" | ||||
|  | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #endif // EIGEN_PASTIXSUPPORT_MODULE_H | ||||
							
								
								
									
										30
									
								
								latan/Eigen/PardisoSupport
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								latan/Eigen/PardisoSupport
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| #ifndef EIGEN_PARDISOSUPPORT_MODULE_H | ||||
| #define EIGEN_PARDISOSUPPORT_MODULE_H | ||||
|  | ||||
| #include "SparseCore" | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| #include <mkl_pardiso.h> | ||||
|  | ||||
| #include <unsupported/Eigen/SparseExtra> | ||||
|  | ||||
| /** \ingroup Support_modules | ||||
|   * \defgroup PardisoSupport_Module PardisoSupport module | ||||
|   * | ||||
|   * This module brings support for the Intel(R) MKL PARDISO direct sparse solvers. | ||||
|   * | ||||
|   * \code | ||||
|   * #include <Eigen/PardisoSupport> | ||||
|   * \endcode | ||||
|   * | ||||
|   * In order to use this module, the MKL headers must be accessible from the include paths, and your binary must be linked to the MKL library and its dependencies. | ||||
|   * See this \ref TopicUsingIntelMKL "page" for more information on MKL-Eigen integration. | ||||
|   *  | ||||
|   */ | ||||
|  | ||||
| #include "src/PardisoSupport/PardisoSupport.h" | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #endif // EIGEN_PARDISOSUPPORT_MODULE_H | ||||
							
								
								
									
										45
									
								
								latan/Eigen/QR
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								latan/Eigen/QR
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| #ifndef EIGEN_QR_MODULE_H | ||||
| #define EIGEN_QR_MODULE_H | ||||
|  | ||||
| #include "Core" | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| #include "Cholesky" | ||||
| #include "Jacobi" | ||||
| #include "Householder" | ||||
|  | ||||
| /** \defgroup QR_Module QR module | ||||
|   * | ||||
|   * | ||||
|   * | ||||
|   * This module provides various QR decompositions | ||||
|   * This module also provides some MatrixBase methods, including: | ||||
|   *  - MatrixBase::qr(), | ||||
|   * | ||||
|   * \code | ||||
|   * #include <Eigen/QR> | ||||
|   * \endcode | ||||
|   */ | ||||
|  | ||||
| #include "src/misc/Solve.h" | ||||
| #include "src/QR/HouseholderQR.h" | ||||
| #include "src/QR/FullPivHouseholderQR.h" | ||||
| #include "src/QR/ColPivHouseholderQR.h" | ||||
| #ifdef EIGEN_USE_LAPACKE | ||||
| #include "src/QR/HouseholderQR_MKL.h" | ||||
| #include "src/QR/ColPivHouseholderQR_MKL.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef EIGEN2_SUPPORT | ||||
| #include "src/Eigen2Support/QR.h" | ||||
| #endif | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #ifdef EIGEN2_SUPPORT | ||||
| #include "Eigenvalues" | ||||
| #endif | ||||
|  | ||||
| #endif // EIGEN_QR_MODULE_H | ||||
| /* vim: set filetype=cpp et sw=2 ts=2 ai: */ | ||||
							
								
								
									
										34
									
								
								latan/Eigen/QtAlignedMalloc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								latan/Eigen/QtAlignedMalloc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
|  | ||||
| #ifndef EIGEN_QTMALLOC_MODULE_H | ||||
| #define EIGEN_QTMALLOC_MODULE_H | ||||
|  | ||||
| #include "Core" | ||||
|  | ||||
| #if (!EIGEN_MALLOC_ALREADY_ALIGNED) | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| void *qMalloc(size_t size) | ||||
| { | ||||
|   return Eigen::internal::aligned_malloc(size); | ||||
| } | ||||
|  | ||||
| void qFree(void *ptr) | ||||
| { | ||||
|   Eigen::internal::aligned_free(ptr); | ||||
| } | ||||
|  | ||||
| void *qRealloc(void *ptr, size_t size) | ||||
| { | ||||
|   void* newPtr = Eigen::internal::aligned_malloc(size); | ||||
|   memcpy(newPtr, ptr, size); | ||||
|   Eigen::internal::aligned_free(ptr); | ||||
|   return newPtr; | ||||
| } | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif // EIGEN_QTMALLOC_MODULE_H | ||||
| /* vim: set filetype=cpp et sw=2 ts=2 ai: */ | ||||
							
								
								
									
										37
									
								
								latan/Eigen/SVD
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								latan/Eigen/SVD
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| #ifndef EIGEN_SVD_MODULE_H | ||||
| #define EIGEN_SVD_MODULE_H | ||||
|  | ||||
| #include "QR" | ||||
| #include "Householder" | ||||
| #include "Jacobi" | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| /** \defgroup SVD_Module SVD module | ||||
|   * | ||||
|   * | ||||
|   * | ||||
|   * This module provides SVD decomposition for matrices (both real and complex). | ||||
|   * This decomposition is accessible via the following MatrixBase method: | ||||
|   *  - MatrixBase::jacobiSvd() | ||||
|   * | ||||
|   * \code | ||||
|   * #include <Eigen/SVD> | ||||
|   * \endcode | ||||
|   */ | ||||
|  | ||||
| #include "src/misc/Solve.h" | ||||
| #include "src/SVD/JacobiSVD.h" | ||||
| #if defined(EIGEN_USE_LAPACKE) && !defined(EIGEN_USE_LAPACKE_STRICT) | ||||
| #include "src/SVD/JacobiSVD_MKL.h" | ||||
| #endif | ||||
| #include "src/SVD/UpperBidiagonalization.h" | ||||
|  | ||||
| #ifdef EIGEN2_SUPPORT | ||||
| #include "src/Eigen2Support/SVD.h" | ||||
| #endif | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #endif // EIGEN_SVD_MODULE_H | ||||
| /* vim: set filetype=cpp et sw=2 ts=2 ai: */ | ||||
							
								
								
									
										23
									
								
								latan/Eigen/Sparse
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								latan/Eigen/Sparse
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| #ifndef EIGEN_SPARSE_MODULE_H | ||||
| #define EIGEN_SPARSE_MODULE_H | ||||
|  | ||||
| /** \defgroup Sparse_modules Sparse modules | ||||
|   * | ||||
|   * Meta-module including all related modules: | ||||
|   * - SparseCore | ||||
|   * - OrderingMethods | ||||
|   * - SparseCholesky | ||||
|   * - IterativeLinearSolvers | ||||
|   * | ||||
|   * \code | ||||
|   * #include <Eigen/Sparse> | ||||
|   * \endcode | ||||
|   */ | ||||
|  | ||||
| #include "SparseCore" | ||||
| #include "OrderingMethods" | ||||
| #include "SparseCholesky" | ||||
| #include "IterativeLinearSolvers" | ||||
|  | ||||
| #endif // EIGEN_SPARSE_MODULE_H | ||||
|  | ||||
							
								
								
									
										30
									
								
								latan/Eigen/SparseCholesky
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								latan/Eigen/SparseCholesky
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| #ifndef EIGEN_SPARSECHOLESKY_MODULE_H | ||||
| #define EIGEN_SPARSECHOLESKY_MODULE_H | ||||
|  | ||||
| #include "SparseCore" | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| /** \ingroup Sparse_modules | ||||
|   * \defgroup SparseCholesky_Module SparseCholesky module | ||||
|   * | ||||
|   * This module currently provides two variants of the direct sparse Cholesky decomposition for selfadjoint (hermitian) matrices. | ||||
|   * Those decompositions are accessible via the following classes: | ||||
|   *  - SimplicialLLt, | ||||
|   *  - SimplicialLDLt | ||||
|   * | ||||
|   * Such problems can also be solved using the ConjugateGradient solver from the IterativeLinearSolvers module. | ||||
|   * | ||||
|   * \code | ||||
|   * #include <Eigen/SparseCholesky> | ||||
|   * \endcode | ||||
|   */ | ||||
|  | ||||
| #include "src/misc/Solve.h" | ||||
| #include "src/misc/SparseSolve.h" | ||||
|  | ||||
| #include "src/SparseCholesky/SimplicialCholesky.h" | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #endif // EIGEN_SPARSECHOLESKY_MODULE_H | ||||
							
								
								
									
										66
									
								
								latan/Eigen/SparseCore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								latan/Eigen/SparseCore
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| #ifndef EIGEN_SPARSECORE_MODULE_H | ||||
| #define EIGEN_SPARSECORE_MODULE_H | ||||
|  | ||||
| #include "Core" | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| #include <vector> | ||||
| #include <map> | ||||
| #include <cstdlib> | ||||
| #include <cstring> | ||||
| #include <algorithm> | ||||
|  | ||||
| /** \ingroup Sparse_modules | ||||
|   * \defgroup SparseCore_Module SparseCore module | ||||
|   * | ||||
|   * This module provides a sparse matrix representation, and basic associatd matrix manipulations | ||||
|   * and operations. | ||||
|   * | ||||
|   * See the \ref TutorialSparse "Sparse tutorial" | ||||
|   * | ||||
|   * \code | ||||
|   * #include <Eigen/SparseCore> | ||||
|   * \endcode | ||||
|   * | ||||
|   * This module depends on: Core. | ||||
|   */ | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| /** The type used to identify a general sparse storage. */ | ||||
| struct Sparse {}; | ||||
|  | ||||
| } | ||||
|  | ||||
| #include "src/SparseCore/SparseUtil.h" | ||||
| #include "src/SparseCore/SparseMatrixBase.h" | ||||
| #include "src/SparseCore/CompressedStorage.h" | ||||
| #include "src/SparseCore/AmbiVector.h" | ||||
| #include "src/SparseCore/SparseMatrix.h" | ||||
| #include "src/SparseCore/MappedSparseMatrix.h" | ||||
| #include "src/SparseCore/SparseVector.h" | ||||
| #include "src/SparseCore/CoreIterators.h" | ||||
| #include "src/SparseCore/SparseBlock.h" | ||||
| #include "src/SparseCore/SparseTranspose.h" | ||||
| #include "src/SparseCore/SparseCwiseUnaryOp.h" | ||||
| #include "src/SparseCore/SparseCwiseBinaryOp.h" | ||||
| #include "src/SparseCore/SparseDot.h" | ||||
| #include "src/SparseCore/SparsePermutation.h" | ||||
| #include "src/SparseCore/SparseAssign.h" | ||||
| #include "src/SparseCore/SparseRedux.h" | ||||
| #include "src/SparseCore/SparseFuzzy.h" | ||||
| #include "src/SparseCore/ConservativeSparseSparseProduct.h" | ||||
| #include "src/SparseCore/SparseSparseProductWithPruning.h" | ||||
| #include "src/SparseCore/SparseProduct.h" | ||||
| #include "src/SparseCore/SparseDenseProduct.h" | ||||
| #include "src/SparseCore/SparseDiagonalProduct.h" | ||||
| #include "src/SparseCore/SparseTriangularView.h" | ||||
| #include "src/SparseCore/SparseSelfAdjointView.h" | ||||
| #include "src/SparseCore/TriangularSolver.h" | ||||
| #include "src/SparseCore/SparseView.h" | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #endif // EIGEN_SPARSECORE_MODULE_H | ||||
|  | ||||
							
								
								
									
										27
									
								
								latan/Eigen/StdDeque
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								latan/Eigen/StdDeque
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_STDDEQUE_MODULE_H | ||||
| #define EIGEN_STDDEQUE_MODULE_H | ||||
|  | ||||
| #include "Core" | ||||
| #include <deque> | ||||
|  | ||||
| #if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */ | ||||
|  | ||||
| #define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...) | ||||
|  | ||||
| #else | ||||
|  | ||||
| #include "src/StlSupport/StdDeque.h" | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif // EIGEN_STDDEQUE_MODULE_H | ||||
							
								
								
									
										26
									
								
								latan/Eigen/StdList
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								latan/Eigen/StdList
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_STDLIST_MODULE_H | ||||
| #define EIGEN_STDLIST_MODULE_H | ||||
|  | ||||
| #include "Core" | ||||
| #include <list> | ||||
|  | ||||
| #if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */     | ||||
|  | ||||
| #define EIGEN_DEFINE_STL_LIST_SPECIALIZATION(...) | ||||
|  | ||||
| #else | ||||
|  | ||||
| #include "src/StlSupport/StdList.h" | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif // EIGEN_STDLIST_MODULE_H | ||||
							
								
								
									
										27
									
								
								latan/Eigen/StdVector
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								latan/Eigen/StdVector
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_STDVECTOR_MODULE_H | ||||
| #define EIGEN_STDVECTOR_MODULE_H | ||||
|  | ||||
| #include "Core" | ||||
| #include <vector> | ||||
|  | ||||
| #if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */ | ||||
|  | ||||
| #define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...) | ||||
|  | ||||
| #else | ||||
|  | ||||
| #include "src/StlSupport/StdVector.h" | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif // EIGEN_STDVECTOR_MODULE_H | ||||
							
								
								
									
										59
									
								
								latan/Eigen/SuperLUSupport
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								latan/Eigen/SuperLUSupport
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| #ifndef EIGEN_SUPERLUSUPPORT_MODULE_H | ||||
| #define EIGEN_SUPERLUSUPPORT_MODULE_H | ||||
|  | ||||
| #include "SparseCore" | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| #ifdef EMPTY | ||||
| #define EIGEN_EMPTY_WAS_ALREADY_DEFINED | ||||
| #endif | ||||
|  | ||||
| typedef int int_t; | ||||
| #include <slu_Cnames.h> | ||||
| #include <supermatrix.h> | ||||
| #include <slu_util.h> | ||||
|  | ||||
| // slu_util.h defines a preprocessor token named EMPTY which is really polluting, | ||||
| // so we remove it in favor of a SUPERLU_EMPTY token. | ||||
| // If EMPTY was already defined then we don't undef it. | ||||
|  | ||||
| #if defined(EIGEN_EMPTY_WAS_ALREADY_DEFINED) | ||||
| # undef EIGEN_EMPTY_WAS_ALREADY_DEFINED | ||||
| #elif defined(EMPTY) | ||||
| # undef EMPTY | ||||
| #endif | ||||
|  | ||||
| #define SUPERLU_EMPTY (-1) | ||||
|  | ||||
| namespace Eigen { struct SluMatrix; } | ||||
|  | ||||
| /** \ingroup Support_modules | ||||
|   * \defgroup SuperLUSupport_Module SuperLUSupport module | ||||
|   * | ||||
|   * This module provides an interface to the <a href="http://crd-legacy.lbl.gov/~xiaoye/SuperLU/">SuperLU</a> library. | ||||
|   * It provides the following factorization class: | ||||
|   * - class SuperLU: a supernodal sequential LU factorization. | ||||
|   * - class SuperILU: a supernodal sequential incomplete LU factorization (to be used as a preconditioner for iterative methods). | ||||
|   * | ||||
|   * \warning When including this module, you have to use SUPERLU_EMPTY instead of EMPTY which is no longer defined because it is too polluting. | ||||
|   * | ||||
|   * \code | ||||
|   * #include <Eigen/SuperLUSupport> | ||||
|   * \endcode | ||||
|   * | ||||
|   * In order to use this module, the superlu headers must be accessible from the include paths, and your binary must be linked to the superlu library and its dependencies. | ||||
|   * The dependencies depend on how superlu has been compiled. | ||||
|   * For a cmake based project, you can use our FindSuperLU.cmake module to help you in this task. | ||||
|   * | ||||
|   */ | ||||
|  | ||||
| #include "src/misc/Solve.h" | ||||
| #include "src/misc/SparseSolve.h" | ||||
|  | ||||
| #include "src/SuperLUSupport/SuperLUSupport.h" | ||||
|  | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #endif // EIGEN_SUPERLUSUPPORT_MODULE_H | ||||
							
								
								
									
										36
									
								
								latan/Eigen/UmfPackSupport
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								latan/Eigen/UmfPackSupport
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| #ifndef EIGEN_UMFPACKSUPPORT_MODULE_H | ||||
| #define EIGEN_UMFPACKSUPPORT_MODULE_H | ||||
|  | ||||
| #include "SparseCore" | ||||
|  | ||||
| #include "src/Core/util/DisableStupidWarnings.h" | ||||
|  | ||||
| extern "C" { | ||||
| #include <umfpack.h> | ||||
| } | ||||
|  | ||||
| /** \ingroup Support_modules | ||||
|   * \defgroup UmfPackSupport_Module UmfPackSupport module | ||||
|   * | ||||
|   * This module provides an interface to the UmfPack library which is part of the <a href="http://www.cise.ufl.edu/research/sparse/SuiteSparse/">suitesparse</a> package. | ||||
|   * It provides the following factorization class: | ||||
|   * - class UmfPackLU: a multifrontal sequential LU factorization. | ||||
|   * | ||||
|   * \code | ||||
|   * #include <Eigen/UmfPackSupport> | ||||
|   * \endcode | ||||
|   * | ||||
|   * In order to use this module, the umfpack headers must be accessible from the include paths, and your binary must be linked to the umfpack library and its dependencies. | ||||
|   * The dependencies depend on how umfpack has been compiled. | ||||
|   * For a cmake based project, you can use our FindUmfPack.cmake module to help you in this task. | ||||
|   * | ||||
|   */ | ||||
|  | ||||
| #include "src/misc/Solve.h" | ||||
| #include "src/misc/SparseSolve.h" | ||||
|  | ||||
| #include "src/UmfPackSupport/UmfPackSupport.h" | ||||
|  | ||||
| #include "src/Core/util/ReenableStupidWarnings.h" | ||||
|  | ||||
| #endif // EIGEN_UMFPACKSUPPORT_MODULE_H | ||||
							
								
								
									
										591
									
								
								latan/Eigen/src/Cholesky/LDLT.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										591
									
								
								latan/Eigen/src/Cholesky/LDLT.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,591 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2009 Keir Mierle <mierle@gmail.com> | ||||
| // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // Copyright (C) 2011 Timothy E. Holy <tim.holy@gmail.com > | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_LDLT_H | ||||
| #define EIGEN_LDLT_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| namespace internal { | ||||
| template<typename MatrixType, int UpLo> struct LDLT_Traits; | ||||
| } | ||||
|  | ||||
| /** \ingroup Cholesky_Module | ||||
|   * | ||||
|   * \class LDLT | ||||
|   * | ||||
|   * \brief Robust Cholesky decomposition of a matrix with pivoting | ||||
|   * | ||||
|   * \param MatrixType the type of the matrix of which to compute the LDL^T Cholesky decomposition | ||||
|   * \param UpLo the triangular part that will be used for the decompositon: Lower (default) or Upper. | ||||
|   *             The other triangular part won't be read. | ||||
|   * | ||||
|   * Perform a robust Cholesky decomposition of a positive semidefinite or negative semidefinite | ||||
|   * matrix \f$ A \f$ such that \f$ A =  P^TLDL^*P \f$, where P is a permutation matrix, L | ||||
|   * is lower triangular with a unit diagonal and D is a diagonal matrix. | ||||
|   * | ||||
|   * The decomposition uses pivoting to ensure stability, so that L will have | ||||
|   * zeros in the bottom right rank(A) - n submatrix. Avoiding the square root | ||||
|   * on D also stabilizes the computation. | ||||
|   * | ||||
|   * Remember that Cholesky decompositions are not rank-revealing. Also, do not use a Cholesky | ||||
|   * decomposition to determine whether a system of equations has a solution. | ||||
|   * | ||||
|   * \sa MatrixBase::ldlt(), class LLT | ||||
|   */ | ||||
| template<typename _MatrixType, int _UpLo> class LDLT | ||||
| { | ||||
|   public: | ||||
|     typedef _MatrixType MatrixType; | ||||
|     enum { | ||||
|       RowsAtCompileTime = MatrixType::RowsAtCompileTime, | ||||
|       ColsAtCompileTime = MatrixType::ColsAtCompileTime, | ||||
|       Options = MatrixType::Options & ~RowMajorBit, // these are the options for the TmpMatrixType, we need a ColMajor matrix here! | ||||
|       MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, | ||||
|       MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, | ||||
|       UpLo = _UpLo | ||||
|     }; | ||||
|     typedef typename MatrixType::Scalar Scalar; | ||||
|     typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar; | ||||
|     typedef typename MatrixType::Index Index; | ||||
|     typedef Matrix<Scalar, RowsAtCompileTime, 1, Options, MaxRowsAtCompileTime, 1> TmpMatrixType; | ||||
|  | ||||
|     typedef Transpositions<RowsAtCompileTime, MaxRowsAtCompileTime> TranspositionType; | ||||
|     typedef PermutationMatrix<RowsAtCompileTime, MaxRowsAtCompileTime> PermutationType; | ||||
|  | ||||
|     typedef internal::LDLT_Traits<MatrixType,UpLo> Traits; | ||||
|  | ||||
|     /** \brief Default Constructor. | ||||
|       * | ||||
|       * The default constructor is useful in cases in which the user intends to | ||||
|       * perform decompositions via LDLT::compute(const MatrixType&). | ||||
|       */ | ||||
|     LDLT() : m_matrix(), m_transpositions(), m_isInitialized(false) {} | ||||
|  | ||||
|     /** \brief Default Constructor with memory preallocation | ||||
|       * | ||||
|       * Like the default constructor but with preallocation of the internal data | ||||
|       * according to the specified problem \a size. | ||||
|       * \sa LDLT() | ||||
|       */ | ||||
|     LDLT(Index size) | ||||
|       : m_matrix(size, size), | ||||
|         m_transpositions(size), | ||||
|         m_temporary(size), | ||||
|         m_isInitialized(false) | ||||
|     {} | ||||
|  | ||||
|     /** \brief Constructor with decomposition | ||||
|       * | ||||
|       * This calculates the decomposition for the input \a matrix. | ||||
|       * \sa LDLT(Index size) | ||||
|       */ | ||||
|     LDLT(const MatrixType& matrix) | ||||
|       : m_matrix(matrix.rows(), matrix.cols()), | ||||
|         m_transpositions(matrix.rows()), | ||||
|         m_temporary(matrix.rows()), | ||||
|         m_isInitialized(false) | ||||
|     { | ||||
|       compute(matrix); | ||||
|     } | ||||
|  | ||||
|     /** Clear any existing decomposition | ||||
|      * \sa rankUpdate(w,sigma) | ||||
|      */ | ||||
|     void setZero() | ||||
|     { | ||||
|       m_isInitialized = false; | ||||
|     } | ||||
|  | ||||
|     /** \returns a view of the upper triangular matrix U */ | ||||
|     inline typename Traits::MatrixU matrixU() const | ||||
|     { | ||||
|       eigen_assert(m_isInitialized && "LDLT is not initialized."); | ||||
|       return Traits::getU(m_matrix); | ||||
|     } | ||||
|  | ||||
|     /** \returns a view of the lower triangular matrix L */ | ||||
|     inline typename Traits::MatrixL matrixL() const | ||||
|     { | ||||
|       eigen_assert(m_isInitialized && "LDLT is not initialized."); | ||||
|       return Traits::getL(m_matrix); | ||||
|     } | ||||
|  | ||||
|     /** \returns the permutation matrix P as a transposition sequence. | ||||
|       */ | ||||
|     inline const TranspositionType& transpositionsP() const | ||||
|     { | ||||
|       eigen_assert(m_isInitialized && "LDLT is not initialized."); | ||||
|       return m_transpositions; | ||||
|     } | ||||
|  | ||||
|     /** \returns the coefficients of the diagonal matrix D */ | ||||
|     inline Diagonal<const MatrixType> vectorD() const | ||||
|     { | ||||
|       eigen_assert(m_isInitialized && "LDLT is not initialized."); | ||||
|       return m_matrix.diagonal(); | ||||
|     } | ||||
|  | ||||
|     /** \returns true if the matrix is positive (semidefinite) */ | ||||
|     inline bool isPositive() const | ||||
|     { | ||||
|       eigen_assert(m_isInitialized && "LDLT is not initialized."); | ||||
|       return m_sign == 1; | ||||
|     } | ||||
|      | ||||
|     #ifdef EIGEN2_SUPPORT | ||||
|     inline bool isPositiveDefinite() const | ||||
|     { | ||||
|       return isPositive(); | ||||
|     } | ||||
|     #endif | ||||
|  | ||||
|     /** \returns true if the matrix is negative (semidefinite) */ | ||||
|     inline bool isNegative(void) const | ||||
|     { | ||||
|       eigen_assert(m_isInitialized && "LDLT is not initialized."); | ||||
|       return m_sign == -1; | ||||
|     } | ||||
|  | ||||
|     /** \returns a solution x of \f$ A x = b \f$ using the current decomposition of A. | ||||
|       * | ||||
|       * This function also supports in-place solves using the syntax <tt>x = decompositionObject.solve(x)</tt> . | ||||
|       * | ||||
|       * \note_about_checking_solutions | ||||
|       * | ||||
|       * More precisely, this method solves \f$ A x = b \f$ using the decomposition \f$ A = P^T L D L^* P \f$ | ||||
|       * by solving the systems \f$ P^T y_1 = b \f$, \f$ L y_2 = y_1 \f$, \f$ D y_3 = y_2 \f$,  | ||||
|       * \f$ L^* y_4 = y_3 \f$ and \f$ P x = y_4 \f$ in succession. If the matrix \f$ A \f$ is singular, then | ||||
|       * \f$ D \f$ will also be singular (all the other matrices are invertible). In that case, the | ||||
|       * least-square solution of \f$ D y_3 = y_2 \f$ is computed. This does not mean that this function | ||||
|       * computes the least-square solution of \f$ A x = b \f$ is \f$ A \f$ is singular. | ||||
|       * | ||||
|       * \sa MatrixBase::ldlt() | ||||
|       */ | ||||
|     template<typename Rhs> | ||||
|     inline const internal::solve_retval<LDLT, Rhs> | ||||
|     solve(const MatrixBase<Rhs>& b) const | ||||
|     { | ||||
|       eigen_assert(m_isInitialized && "LDLT is not initialized."); | ||||
|       eigen_assert(m_matrix.rows()==b.rows() | ||||
|                 && "LDLT::solve(): invalid number of rows of the right hand side matrix b"); | ||||
|       return internal::solve_retval<LDLT, Rhs>(*this, b.derived()); | ||||
|     } | ||||
|  | ||||
|     #ifdef EIGEN2_SUPPORT | ||||
|     template<typename OtherDerived, typename ResultType> | ||||
|     bool solve(const MatrixBase<OtherDerived>& b, ResultType *result) const | ||||
|     { | ||||
|       *result = this->solve(b); | ||||
|       return true; | ||||
|     } | ||||
|     #endif | ||||
|  | ||||
|     template<typename Derived> | ||||
|     bool solveInPlace(MatrixBase<Derived> &bAndX) const; | ||||
|  | ||||
|     LDLT& compute(const MatrixType& matrix); | ||||
|  | ||||
|     template <typename Derived> | ||||
|     LDLT& rankUpdate(const MatrixBase<Derived>& w,RealScalar alpha=1); | ||||
|  | ||||
|     /** \returns the internal LDLT decomposition matrix | ||||
|       * | ||||
|       * TODO: document the storage layout | ||||
|       */ | ||||
|     inline const MatrixType& matrixLDLT() const | ||||
|     { | ||||
|       eigen_assert(m_isInitialized && "LDLT is not initialized."); | ||||
|       return m_matrix; | ||||
|     } | ||||
|  | ||||
|     MatrixType reconstructedMatrix() const; | ||||
|  | ||||
|     inline Index rows() const { return m_matrix.rows(); } | ||||
|     inline Index cols() const { return m_matrix.cols(); } | ||||
|  | ||||
|     /** \brief Reports whether previous computation was successful. | ||||
|       * | ||||
|       * \returns \c Success if computation was succesful, | ||||
|       *          \c NumericalIssue if the matrix.appears to be negative. | ||||
|       */ | ||||
|     ComputationInfo info() const | ||||
|     { | ||||
|       eigen_assert(m_isInitialized && "LDLT is not initialized."); | ||||
|       return Success; | ||||
|     } | ||||
|  | ||||
|   protected: | ||||
|  | ||||
|     /** \internal | ||||
|       * Used to compute and store the Cholesky decomposition A = L D L^* = U^* D U. | ||||
|       * The strict upper part is used during the decomposition, the strict lower | ||||
|       * part correspond to the coefficients of L (its diagonal is equal to 1 and | ||||
|       * is not stored), and the diagonal entries correspond to D. | ||||
|       */ | ||||
|     MatrixType m_matrix; | ||||
|     TranspositionType m_transpositions; | ||||
|     TmpMatrixType m_temporary; | ||||
|     int m_sign; | ||||
|     bool m_isInitialized; | ||||
| }; | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<int UpLo> struct ldlt_inplace; | ||||
|  | ||||
| template<> struct ldlt_inplace<Lower> | ||||
| { | ||||
|   template<typename MatrixType, typename TranspositionType, typename Workspace> | ||||
|   static bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, int* sign=0) | ||||
|   { | ||||
|     typedef typename MatrixType::Scalar Scalar; | ||||
|     typedef typename MatrixType::RealScalar RealScalar; | ||||
|     typedef typename MatrixType::Index Index; | ||||
|     eigen_assert(mat.rows()==mat.cols()); | ||||
|     const Index size = mat.rows(); | ||||
|  | ||||
|     if (size <= 1) | ||||
|     { | ||||
|       transpositions.setIdentity(); | ||||
|       if(sign) | ||||
|         *sign = real(mat.coeff(0,0))>0 ? 1:-1; | ||||
|       return true; | ||||
|     } | ||||
|  | ||||
|     RealScalar cutoff(0), biggest_in_corner; | ||||
|  | ||||
|     for (Index k = 0; k < size; ++k) | ||||
|     { | ||||
|       // Find largest diagonal element | ||||
|       Index index_of_biggest_in_corner; | ||||
|       biggest_in_corner = mat.diagonal().tail(size-k).cwiseAbs().maxCoeff(&index_of_biggest_in_corner); | ||||
|       index_of_biggest_in_corner += k; | ||||
|  | ||||
|       if(k == 0) | ||||
|       { | ||||
|         // The biggest overall is the point of reference to which further diagonals | ||||
|         // are compared; if any diagonal is negligible compared | ||||
|         // to the largest overall, the algorithm bails. | ||||
|         cutoff = abs(NumTraits<Scalar>::epsilon() * biggest_in_corner); | ||||
|  | ||||
|         if(sign) | ||||
|           *sign = real(mat.diagonal().coeff(index_of_biggest_in_corner)) > 0 ? 1 : -1; | ||||
|       } | ||||
|  | ||||
|       // Finish early if the matrix is not full rank. | ||||
|       if(biggest_in_corner < cutoff) | ||||
|       { | ||||
|         for(Index i = k; i < size; i++) transpositions.coeffRef(i) = i; | ||||
|         break; | ||||
|       } | ||||
|  | ||||
|       transpositions.coeffRef(k) = index_of_biggest_in_corner; | ||||
|       if(k != index_of_biggest_in_corner) | ||||
|       { | ||||
|         // apply the transposition while taking care to consider only | ||||
|         // the lower triangular part | ||||
|         Index s = size-index_of_biggest_in_corner-1; // trailing size after the biggest element | ||||
|         mat.row(k).head(k).swap(mat.row(index_of_biggest_in_corner).head(k)); | ||||
|         mat.col(k).tail(s).swap(mat.col(index_of_biggest_in_corner).tail(s)); | ||||
|         std::swap(mat.coeffRef(k,k),mat.coeffRef(index_of_biggest_in_corner,index_of_biggest_in_corner)); | ||||
|         for(int i=k+1;i<index_of_biggest_in_corner;++i) | ||||
|         { | ||||
|           Scalar tmp = mat.coeffRef(i,k); | ||||
|           mat.coeffRef(i,k) = conj(mat.coeffRef(index_of_biggest_in_corner,i)); | ||||
|           mat.coeffRef(index_of_biggest_in_corner,i) = conj(tmp); | ||||
|         } | ||||
|         if(NumTraits<Scalar>::IsComplex) | ||||
|           mat.coeffRef(index_of_biggest_in_corner,k) = conj(mat.coeff(index_of_biggest_in_corner,k)); | ||||
|       } | ||||
|  | ||||
|       // partition the matrix: | ||||
|       //       A00 |  -  |  - | ||||
|       // lu  = A10 | A11 |  - | ||||
|       //       A20 | A21 | A22 | ||||
|       Index rs = size - k - 1; | ||||
|       Block<MatrixType,Dynamic,1> A21(mat,k+1,k,rs,1); | ||||
|       Block<MatrixType,1,Dynamic> A10(mat,k,0,1,k); | ||||
|       Block<MatrixType,Dynamic,Dynamic> A20(mat,k+1,0,rs,k); | ||||
|  | ||||
|       if(k>0) | ||||
|       { | ||||
|         temp.head(k) = mat.diagonal().head(k).asDiagonal() * A10.adjoint(); | ||||
|         mat.coeffRef(k,k) -= (A10 * temp.head(k)).value(); | ||||
|         if(rs>0) | ||||
|           A21.noalias() -= A20 * temp.head(k); | ||||
|       } | ||||
|       if((rs>0) && (abs(mat.coeffRef(k,k)) > cutoff)) | ||||
|         A21 /= mat.coeffRef(k,k); | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   // Reference for the algorithm: Davis and Hager, "Multiple Rank | ||||
|   // Modifications of a Sparse Cholesky Factorization" (Algorithm 1) | ||||
|   // Trivial rearrangements of their computations (Timothy E. Holy) | ||||
|   // allow their algorithm to work for rank-1 updates even if the | ||||
|   // original matrix is not of full rank. | ||||
|   // Here only rank-1 updates are implemented, to reduce the | ||||
|   // requirement for intermediate storage and improve accuracy | ||||
|   template<typename MatrixType, typename WDerived> | ||||
|   static bool updateInPlace(MatrixType& mat, MatrixBase<WDerived>& w, typename MatrixType::RealScalar sigma=1) | ||||
|   { | ||||
|     using internal::isfinite; | ||||
|     typedef typename MatrixType::Scalar Scalar; | ||||
|     typedef typename MatrixType::RealScalar RealScalar; | ||||
|     typedef typename MatrixType::Index Index; | ||||
|  | ||||
|     const Index size = mat.rows(); | ||||
|     eigen_assert(mat.cols() == size && w.size()==size); | ||||
|  | ||||
|     RealScalar alpha = 1; | ||||
|  | ||||
|     // Apply the update | ||||
|     for (Index j = 0; j < size; j++) | ||||
|     { | ||||
|       // Check for termination due to an original decomposition of low-rank | ||||
|       if (!(isfinite)(alpha)) | ||||
|         break; | ||||
|  | ||||
|       // Update the diagonal terms | ||||
|       RealScalar dj = real(mat.coeff(j,j)); | ||||
|       Scalar wj = w.coeff(j); | ||||
|       RealScalar swj2 = sigma*abs2(wj); | ||||
|       RealScalar gamma = dj*alpha + swj2; | ||||
|  | ||||
|       mat.coeffRef(j,j) += swj2/alpha; | ||||
|       alpha += swj2/dj; | ||||
|  | ||||
|  | ||||
|       // Update the terms of L | ||||
|       Index rs = size-j-1; | ||||
|       w.tail(rs) -= wj * mat.col(j).tail(rs); | ||||
|       if(gamma != 0) | ||||
|         mat.col(j).tail(rs) += (sigma*conj(wj)/gamma)*w.tail(rs); | ||||
|     } | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   template<typename MatrixType, typename TranspositionType, typename Workspace, typename WType> | ||||
|   static bool update(MatrixType& mat, const TranspositionType& transpositions, Workspace& tmp, const WType& w, typename MatrixType::RealScalar sigma=1) | ||||
|   { | ||||
|     // Apply the permutation to the input w | ||||
|     tmp = transpositions * w; | ||||
|  | ||||
|     return ldlt_inplace<Lower>::updateInPlace(mat,tmp,sigma); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct ldlt_inplace<Upper> | ||||
| { | ||||
|   template<typename MatrixType, typename TranspositionType, typename Workspace> | ||||
|   static EIGEN_STRONG_INLINE bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, int* sign=0) | ||||
|   { | ||||
|     Transpose<MatrixType> matt(mat); | ||||
|     return ldlt_inplace<Lower>::unblocked(matt, transpositions, temp, sign); | ||||
|   } | ||||
|  | ||||
|   template<typename MatrixType, typename TranspositionType, typename Workspace, typename WType> | ||||
|   static EIGEN_STRONG_INLINE bool update(MatrixType& mat, TranspositionType& transpositions, Workspace& tmp, WType& w, typename MatrixType::RealScalar sigma=1) | ||||
|   { | ||||
|     Transpose<MatrixType> matt(mat); | ||||
|     return ldlt_inplace<Lower>::update(matt, transpositions, tmp, w.conjugate(), sigma); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename MatrixType> struct LDLT_Traits<MatrixType,Lower> | ||||
| { | ||||
|   typedef const TriangularView<const MatrixType, UnitLower> MatrixL; | ||||
|   typedef const TriangularView<const typename MatrixType::AdjointReturnType, UnitUpper> MatrixU; | ||||
|   static inline MatrixL getL(const MatrixType& m) { return m; } | ||||
|   static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); } | ||||
| }; | ||||
|  | ||||
| template<typename MatrixType> struct LDLT_Traits<MatrixType,Upper> | ||||
| { | ||||
|   typedef const TriangularView<const typename MatrixType::AdjointReturnType, UnitLower> MatrixL; | ||||
|   typedef const TriangularView<const MatrixType, UnitUpper> MatrixU; | ||||
|   static inline MatrixL getL(const MatrixType& m) { return m.adjoint(); } | ||||
|   static inline MatrixU getU(const MatrixType& m) { return m; } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /** Compute / recompute the LDLT decomposition A = L D L^* = U^* D U of \a matrix | ||||
|   */ | ||||
| template<typename MatrixType, int _UpLo> | ||||
| LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::compute(const MatrixType& a) | ||||
| { | ||||
|   eigen_assert(a.rows()==a.cols()); | ||||
|   const Index size = a.rows(); | ||||
|  | ||||
|   m_matrix = a; | ||||
|  | ||||
|   m_transpositions.resize(size); | ||||
|   m_isInitialized = false; | ||||
|   m_temporary.resize(size); | ||||
|  | ||||
|   internal::ldlt_inplace<UpLo>::unblocked(m_matrix, m_transpositions, m_temporary, &m_sign); | ||||
|  | ||||
|   m_isInitialized = true; | ||||
|   return *this; | ||||
| } | ||||
|  | ||||
| /** Update the LDLT decomposition:  given A = L D L^T, efficiently compute the decomposition of A + sigma w w^T. | ||||
|  * \param w a vector to be incorporated into the decomposition. | ||||
|  * \param sigma a scalar, +1 for updates and -1 for "downdates," which correspond to removing previously-added column vectors. Optional; default value is +1. | ||||
|  * \sa setZero() | ||||
|   */ | ||||
| template<typename MatrixType, int _UpLo> | ||||
| template<typename Derived> | ||||
| LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::rankUpdate(const MatrixBase<Derived>& w,typename NumTraits<typename MatrixType::Scalar>::Real sigma) | ||||
| { | ||||
|   const Index size = w.rows(); | ||||
|   if (m_isInitialized) | ||||
|   { | ||||
|     eigen_assert(m_matrix.rows()==size); | ||||
|   } | ||||
|   else | ||||
|   {     | ||||
|     m_matrix.resize(size,size); | ||||
|     m_matrix.setZero(); | ||||
|     m_transpositions.resize(size); | ||||
|     for (Index i = 0; i < size; i++) | ||||
|       m_transpositions.coeffRef(i) = i; | ||||
|     m_temporary.resize(size); | ||||
|     m_sign = sigma>=0 ? 1 : -1; | ||||
|     m_isInitialized = true; | ||||
|   } | ||||
|  | ||||
|   internal::ldlt_inplace<UpLo>::update(m_matrix, m_transpositions, m_temporary, w, sigma); | ||||
|  | ||||
|   return *this; | ||||
| } | ||||
|  | ||||
| namespace internal { | ||||
| template<typename _MatrixType, int _UpLo, typename Rhs> | ||||
| struct solve_retval<LDLT<_MatrixType,_UpLo>, Rhs> | ||||
|   : solve_retval_base<LDLT<_MatrixType,_UpLo>, Rhs> | ||||
| { | ||||
|   typedef LDLT<_MatrixType,_UpLo> LDLTType; | ||||
|   EIGEN_MAKE_SOLVE_HELPERS(LDLTType,Rhs) | ||||
|  | ||||
|   template<typename Dest> void evalTo(Dest& dst) const | ||||
|   { | ||||
|     eigen_assert(rhs().rows() == dec().matrixLDLT().rows()); | ||||
|     // dst = P b | ||||
|     dst = dec().transpositionsP() * rhs(); | ||||
|  | ||||
|     // dst = L^-1 (P b) | ||||
|     dec().matrixL().solveInPlace(dst); | ||||
|  | ||||
|     // dst = D^-1 (L^-1 P b) | ||||
|     // more precisely, use pseudo-inverse of D (see bug 241) | ||||
|     using std::abs; | ||||
|     using std::max; | ||||
|     typedef typename LDLTType::MatrixType MatrixType; | ||||
|     typedef typename LDLTType::Scalar Scalar; | ||||
|     typedef typename LDLTType::RealScalar RealScalar; | ||||
|     const Diagonal<const MatrixType> vectorD = dec().vectorD(); | ||||
|     RealScalar tolerance = (max)(vectorD.array().abs().maxCoeff() * NumTraits<Scalar>::epsilon(), | ||||
| 				 RealScalar(1) / NumTraits<RealScalar>::highest()); // motivated by LAPACK's xGELSS | ||||
|     for (Index i = 0; i < vectorD.size(); ++i) { | ||||
|       if(abs(vectorD(i)) > tolerance) | ||||
| 	dst.row(i) /= vectorD(i); | ||||
|       else | ||||
| 	dst.row(i).setZero(); | ||||
|     } | ||||
|  | ||||
|     // dst = L^-T (D^-1 L^-1 P b) | ||||
|     dec().matrixU().solveInPlace(dst); | ||||
|  | ||||
|     // dst = P^-1 (L^-T D^-1 L^-1 P b) = A^-1 b | ||||
|     dst = dec().transpositionsP().transpose() * dst; | ||||
|   } | ||||
| }; | ||||
| } | ||||
|  | ||||
| /** \internal use x = ldlt_object.solve(x); | ||||
|   * | ||||
|   * This is the \em in-place version of solve(). | ||||
|   * | ||||
|   * \param bAndX represents both the right-hand side matrix b and result x. | ||||
|   * | ||||
|   * \returns true always! If you need to check for existence of solutions, use another decomposition like LU, QR, or SVD. | ||||
|   * | ||||
|   * This version avoids a copy when the right hand side matrix b is not | ||||
|   * needed anymore. | ||||
|   * | ||||
|   * \sa LDLT::solve(), MatrixBase::ldlt() | ||||
|   */ | ||||
| template<typename MatrixType,int _UpLo> | ||||
| template<typename Derived> | ||||
| bool LDLT<MatrixType,_UpLo>::solveInPlace(MatrixBase<Derived> &bAndX) const | ||||
| { | ||||
|   eigen_assert(m_isInitialized && "LDLT is not initialized."); | ||||
|   eigen_assert(m_matrix.rows() == bAndX.rows()); | ||||
|  | ||||
|   bAndX = this->solve(bAndX); | ||||
|  | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| /** \returns the matrix represented by the decomposition, | ||||
|  * i.e., it returns the product: P^T L D L^* P. | ||||
|  * This function is provided for debug purpose. */ | ||||
| template<typename MatrixType, int _UpLo> | ||||
| MatrixType LDLT<MatrixType,_UpLo>::reconstructedMatrix() const | ||||
| { | ||||
|   eigen_assert(m_isInitialized && "LDLT is not initialized."); | ||||
|   const Index size = m_matrix.rows(); | ||||
|   MatrixType res(size,size); | ||||
|  | ||||
|   // P | ||||
|   res.setIdentity(); | ||||
|   res = transpositionsP() * res; | ||||
|   // L^* P | ||||
|   res = matrixU() * res; | ||||
|   // D(L^*P) | ||||
|   res = vectorD().asDiagonal() * res; | ||||
|   // L(DL^*P) | ||||
|   res = matrixL() * res; | ||||
|   // P^T (LDL^*P) | ||||
|   res = transpositionsP().transpose() * res; | ||||
|  | ||||
|   return res; | ||||
| } | ||||
|  | ||||
| /** \cholesky_module | ||||
|   * \returns the Cholesky decomposition with full pivoting without square root of \c *this | ||||
|   */ | ||||
| template<typename MatrixType, unsigned int UpLo> | ||||
| inline const LDLT<typename SelfAdjointView<MatrixType, UpLo>::PlainObject, UpLo> | ||||
| SelfAdjointView<MatrixType, UpLo>::ldlt() const | ||||
| { | ||||
|   return LDLT<PlainObject,UpLo>(m_matrix); | ||||
| } | ||||
|  | ||||
| /** \cholesky_module | ||||
|   * \returns the Cholesky decomposition with full pivoting without square root of \c *this | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline const LDLT<typename MatrixBase<Derived>::PlainObject> | ||||
| MatrixBase<Derived>::ldlt() const | ||||
| { | ||||
|   return LDLT<PlainObject>(derived()); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_LDLT_H | ||||
							
								
								
									
										488
									
								
								latan/Eigen/src/Cholesky/LLT.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										488
									
								
								latan/Eigen/src/Cholesky/LLT.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,488 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_LLT_H | ||||
| #define EIGEN_LLT_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| namespace internal{ | ||||
| template<typename MatrixType, int UpLo> struct LLT_Traits; | ||||
| } | ||||
|  | ||||
| /** \ingroup Cholesky_Module | ||||
|   * | ||||
|   * \class LLT | ||||
|   * | ||||
|   * \brief Standard Cholesky decomposition (LL^T) of a matrix and associated features | ||||
|   * | ||||
|   * \param MatrixType the type of the matrix of which we are computing the LL^T Cholesky decomposition | ||||
|   * \param UpLo the triangular part that will be used for the decompositon: Lower (default) or Upper. | ||||
|   *             The other triangular part won't be read. | ||||
|   * | ||||
|   * This class performs a LL^T Cholesky decomposition of a symmetric, positive definite | ||||
|   * matrix A such that A = LL^* = U^*U, where L is lower triangular. | ||||
|   * | ||||
|   * While the Cholesky decomposition is particularly useful to solve selfadjoint problems like  D^*D x = b, | ||||
|   * for that purpose, we recommend the Cholesky decomposition without square root which is more stable | ||||
|   * and even faster. Nevertheless, this standard Cholesky decomposition remains useful in many other | ||||
|   * situations like generalised eigen problems with hermitian matrices. | ||||
|   * | ||||
|   * Remember that Cholesky decompositions are not rank-revealing. This LLT decomposition is only stable on positive definite matrices, | ||||
|   * use LDLT instead for the semidefinite case. Also, do not use a Cholesky decomposition to determine whether a system of equations | ||||
|   * has a solution. | ||||
|   * | ||||
|   * Example: \include LLT_example.cpp | ||||
|   * Output: \verbinclude LLT_example.out | ||||
|   *     | ||||
|   * \sa MatrixBase::llt(), class LDLT | ||||
|   */ | ||||
|  /* HEY THIS DOX IS DISABLED BECAUSE THERE's A BUG EITHER HERE OR IN LDLT ABOUT THAT (OR BOTH) | ||||
|   * Note that during the decomposition, only the upper triangular part of A is considered. Therefore, | ||||
|   * the strict lower part does not have to store correct values. | ||||
|   */ | ||||
| template<typename _MatrixType, int _UpLo> class LLT | ||||
| { | ||||
|   public: | ||||
|     typedef _MatrixType MatrixType; | ||||
|     enum { | ||||
|       RowsAtCompileTime = MatrixType::RowsAtCompileTime, | ||||
|       ColsAtCompileTime = MatrixType::ColsAtCompileTime, | ||||
|       Options = MatrixType::Options, | ||||
|       MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime | ||||
|     }; | ||||
|     typedef typename MatrixType::Scalar Scalar; | ||||
|     typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar; | ||||
|     typedef typename MatrixType::Index Index; | ||||
|  | ||||
|     enum { | ||||
|       PacketSize = internal::packet_traits<Scalar>::size, | ||||
|       AlignmentMask = int(PacketSize)-1, | ||||
|       UpLo = _UpLo | ||||
|     }; | ||||
|  | ||||
|     typedef internal::LLT_Traits<MatrixType,UpLo> Traits; | ||||
|  | ||||
|     /** | ||||
|       * \brief Default Constructor. | ||||
|       * | ||||
|       * The default constructor is useful in cases in which the user intends to | ||||
|       * perform decompositions via LLT::compute(const MatrixType&). | ||||
|       */ | ||||
|     LLT() : m_matrix(), m_isInitialized(false) {} | ||||
|  | ||||
|     /** \brief Default Constructor with memory preallocation | ||||
|       * | ||||
|       * Like the default constructor but with preallocation of the internal data | ||||
|       * according to the specified problem \a size. | ||||
|       * \sa LLT() | ||||
|       */ | ||||
|     LLT(Index size) : m_matrix(size, size), | ||||
|                     m_isInitialized(false) {} | ||||
|  | ||||
|     LLT(const MatrixType& matrix) | ||||
|       : m_matrix(matrix.rows(), matrix.cols()), | ||||
|         m_isInitialized(false) | ||||
|     { | ||||
|       compute(matrix); | ||||
|     } | ||||
|  | ||||
|     /** \returns a view of the upper triangular matrix U */ | ||||
|     inline typename Traits::MatrixU matrixU() const | ||||
|     { | ||||
|       eigen_assert(m_isInitialized && "LLT is not initialized."); | ||||
|       return Traits::getU(m_matrix); | ||||
|     } | ||||
|  | ||||
|     /** \returns a view of the lower triangular matrix L */ | ||||
|     inline typename Traits::MatrixL matrixL() const | ||||
|     { | ||||
|       eigen_assert(m_isInitialized && "LLT is not initialized."); | ||||
|       return Traits::getL(m_matrix); | ||||
|     } | ||||
|  | ||||
|     /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. | ||||
|       * | ||||
|       * Since this LLT class assumes anyway that the matrix A is invertible, the solution | ||||
|       * theoretically exists and is unique regardless of b. | ||||
|       * | ||||
|       * Example: \include LLT_solve.cpp | ||||
|       * Output: \verbinclude LLT_solve.out | ||||
|       * | ||||
|       * \sa solveInPlace(), MatrixBase::llt() | ||||
|       */ | ||||
|     template<typename Rhs> | ||||
|     inline const internal::solve_retval<LLT, Rhs> | ||||
|     solve(const MatrixBase<Rhs>& b) const | ||||
|     { | ||||
|       eigen_assert(m_isInitialized && "LLT is not initialized."); | ||||
|       eigen_assert(m_matrix.rows()==b.rows() | ||||
|                 && "LLT::solve(): invalid number of rows of the right hand side matrix b"); | ||||
|       return internal::solve_retval<LLT, Rhs>(*this, b.derived()); | ||||
|     } | ||||
|  | ||||
|     #ifdef EIGEN2_SUPPORT | ||||
|     template<typename OtherDerived, typename ResultType> | ||||
|     bool solve(const MatrixBase<OtherDerived>& b, ResultType *result) const | ||||
|     { | ||||
|       *result = this->solve(b); | ||||
|       return true; | ||||
|     } | ||||
|      | ||||
|     bool isPositiveDefinite() const { return true; } | ||||
|     #endif | ||||
|  | ||||
|     template<typename Derived> | ||||
|     void solveInPlace(MatrixBase<Derived> &bAndX) const; | ||||
|  | ||||
|     LLT& compute(const MatrixType& matrix); | ||||
|  | ||||
|     /** \returns the LLT decomposition matrix | ||||
|       * | ||||
|       * TODO: document the storage layout | ||||
|       */ | ||||
|     inline const MatrixType& matrixLLT() const | ||||
|     { | ||||
|       eigen_assert(m_isInitialized && "LLT is not initialized."); | ||||
|       return m_matrix; | ||||
|     } | ||||
|  | ||||
|     MatrixType reconstructedMatrix() const; | ||||
|  | ||||
|  | ||||
|     /** \brief Reports whether previous computation was successful. | ||||
|       * | ||||
|       * \returns \c Success if computation was succesful, | ||||
|       *          \c NumericalIssue if the matrix.appears to be negative. | ||||
|       */ | ||||
|     ComputationInfo info() const | ||||
|     { | ||||
|       eigen_assert(m_isInitialized && "LLT is not initialized."); | ||||
|       return m_info; | ||||
|     } | ||||
|  | ||||
|     inline Index rows() const { return m_matrix.rows(); } | ||||
|     inline Index cols() const { return m_matrix.cols(); } | ||||
|  | ||||
|     template<typename VectorType> | ||||
|     LLT rankUpdate(const VectorType& vec, const RealScalar& sigma = 1); | ||||
|  | ||||
|   protected: | ||||
|     /** \internal | ||||
|       * Used to compute and store L | ||||
|       * The strict upper part is not used and even not initialized. | ||||
|       */ | ||||
|     MatrixType m_matrix; | ||||
|     bool m_isInitialized; | ||||
|     ComputationInfo m_info; | ||||
| }; | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename Scalar, int UpLo> struct llt_inplace; | ||||
|  | ||||
| template<typename MatrixType, typename VectorType> | ||||
| static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) | ||||
| { | ||||
|   typedef typename MatrixType::Scalar Scalar; | ||||
|   typedef typename MatrixType::RealScalar RealScalar; | ||||
|   typedef typename MatrixType::Index Index; | ||||
|   typedef typename MatrixType::ColXpr ColXpr; | ||||
|   typedef typename internal::remove_all<ColXpr>::type ColXprCleaned; | ||||
|   typedef typename ColXprCleaned::SegmentReturnType ColXprSegment; | ||||
|   typedef Matrix<Scalar,Dynamic,1> TempVectorType; | ||||
|   typedef typename TempVectorType::SegmentReturnType TempVecSegment; | ||||
|  | ||||
|   int n = mat.cols(); | ||||
|   eigen_assert(mat.rows()==n && vec.size()==n); | ||||
|  | ||||
|   TempVectorType temp; | ||||
|  | ||||
|   if(sigma>0) | ||||
|   { | ||||
|     // This version is based on Givens rotations. | ||||
|     // It is faster than the other one below, but only works for updates, | ||||
|     // i.e., for sigma > 0 | ||||
|     temp = sqrt(sigma) * vec; | ||||
|  | ||||
|     for(int i=0; i<n; ++i) | ||||
|     { | ||||
|       JacobiRotation<Scalar> g; | ||||
|       g.makeGivens(mat(i,i), -temp(i), &mat(i,i)); | ||||
|  | ||||
|       int rs = n-i-1; | ||||
|       if(rs>0) | ||||
|       { | ||||
|         ColXprSegment x(mat.col(i).tail(rs)); | ||||
|         TempVecSegment y(temp.tail(rs)); | ||||
|         apply_rotation_in_the_plane(x, y, g); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     temp = vec; | ||||
|     RealScalar beta = 1; | ||||
|     for(int j=0; j<n; ++j) | ||||
|     { | ||||
|       RealScalar Ljj = real(mat.coeff(j,j)); | ||||
|       RealScalar dj = abs2(Ljj); | ||||
|       Scalar wj = temp.coeff(j); | ||||
|       RealScalar swj2 = sigma*abs2(wj); | ||||
|       RealScalar gamma = dj*beta + swj2; | ||||
|  | ||||
|       RealScalar x = dj + swj2/beta; | ||||
|       if (x<=RealScalar(0)) | ||||
|         return j; | ||||
|       RealScalar nLjj = sqrt(x); | ||||
|       mat.coeffRef(j,j) = nLjj; | ||||
|       beta += swj2/dj; | ||||
|  | ||||
|       // Update the terms of L | ||||
|       Index rs = n-j-1; | ||||
|       if(rs) | ||||
|       { | ||||
|         temp.tail(rs) -= (wj/Ljj) * mat.col(j).tail(rs); | ||||
|         if(gamma != 0) | ||||
|           mat.col(j).tail(rs) = (nLjj/Ljj) * mat.col(j).tail(rs) + (nLjj * sigma*conj(wj)/gamma)*temp.tail(rs); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return -1; | ||||
| } | ||||
|  | ||||
| template<typename Scalar> struct llt_inplace<Scalar, Lower> | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|   template<typename MatrixType> | ||||
|   static typename MatrixType::Index unblocked(MatrixType& mat) | ||||
|   { | ||||
|     typedef typename MatrixType::Index Index; | ||||
|      | ||||
|     eigen_assert(mat.rows()==mat.cols()); | ||||
|     const Index size = mat.rows(); | ||||
|     for(Index k = 0; k < size; ++k) | ||||
|     { | ||||
|       Index rs = size-k-1; // remaining size | ||||
|  | ||||
|       Block<MatrixType,Dynamic,1> A21(mat,k+1,k,rs,1); | ||||
|       Block<MatrixType,1,Dynamic> A10(mat,k,0,1,k); | ||||
|       Block<MatrixType,Dynamic,Dynamic> A20(mat,k+1,0,rs,k); | ||||
|  | ||||
|       RealScalar x = real(mat.coeff(k,k)); | ||||
|       if (k>0) x -= A10.squaredNorm(); | ||||
|       if (x<=RealScalar(0)) | ||||
|         return k; | ||||
|       mat.coeffRef(k,k) = x = sqrt(x); | ||||
|       if (k>0 && rs>0) A21.noalias() -= A20 * A10.adjoint(); | ||||
|       if (rs>0) A21 *= RealScalar(1)/x; | ||||
|     } | ||||
|     return -1; | ||||
|   } | ||||
|  | ||||
|   template<typename MatrixType> | ||||
|   static typename MatrixType::Index blocked(MatrixType& m) | ||||
|   { | ||||
|     typedef typename MatrixType::Index Index; | ||||
|     eigen_assert(m.rows()==m.cols()); | ||||
|     Index size = m.rows(); | ||||
|     if(size<32) | ||||
|       return unblocked(m); | ||||
|  | ||||
|     Index blockSize = size/8; | ||||
|     blockSize = (blockSize/16)*16; | ||||
|     blockSize = (std::min)((std::max)(blockSize,Index(8)), Index(128)); | ||||
|  | ||||
|     for (Index k=0; k<size; k+=blockSize) | ||||
|     { | ||||
|       // partition the matrix: | ||||
|       //       A00 |  -  |  - | ||||
|       // lu  = A10 | A11 |  - | ||||
|       //       A20 | A21 | A22 | ||||
|       Index bs = (std::min)(blockSize, size-k); | ||||
|       Index rs = size - k - bs; | ||||
|       Block<MatrixType,Dynamic,Dynamic> A11(m,k,   k,   bs,bs); | ||||
|       Block<MatrixType,Dynamic,Dynamic> A21(m,k+bs,k,   rs,bs); | ||||
|       Block<MatrixType,Dynamic,Dynamic> A22(m,k+bs,k+bs,rs,rs); | ||||
|  | ||||
|       Index ret; | ||||
|       if((ret=unblocked(A11))>=0) return k+ret; | ||||
|       if(rs>0) A11.adjoint().template triangularView<Upper>().template solveInPlace<OnTheRight>(A21); | ||||
|       if(rs>0) A22.template selfadjointView<Lower>().rankUpdate(A21,-1); // bottleneck | ||||
|     } | ||||
|     return -1; | ||||
|   } | ||||
|  | ||||
|   template<typename MatrixType, typename VectorType> | ||||
|   static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const RealScalar& sigma) | ||||
|   { | ||||
|     return Eigen::internal::llt_rank_update_lower(mat, vec, sigma); | ||||
|   } | ||||
| }; | ||||
|    | ||||
| template<typename Scalar> struct llt_inplace<Scalar, Upper> | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|  | ||||
|   template<typename MatrixType> | ||||
|   static EIGEN_STRONG_INLINE typename MatrixType::Index unblocked(MatrixType& mat) | ||||
|   { | ||||
|     Transpose<MatrixType> matt(mat); | ||||
|     return llt_inplace<Scalar, Lower>::unblocked(matt); | ||||
|   } | ||||
|   template<typename MatrixType> | ||||
|   static EIGEN_STRONG_INLINE typename MatrixType::Index blocked(MatrixType& mat) | ||||
|   { | ||||
|     Transpose<MatrixType> matt(mat); | ||||
|     return llt_inplace<Scalar, Lower>::blocked(matt); | ||||
|   } | ||||
|   template<typename MatrixType, typename VectorType> | ||||
|   static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const RealScalar& sigma) | ||||
|   { | ||||
|     Transpose<MatrixType> matt(mat); | ||||
|     return llt_inplace<Scalar, Lower>::rankUpdate(matt, vec.conjugate(), sigma); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename MatrixType> struct LLT_Traits<MatrixType,Lower> | ||||
| { | ||||
|   typedef const TriangularView<const MatrixType, Lower> MatrixL; | ||||
|   typedef const TriangularView<const typename MatrixType::AdjointReturnType, Upper> MatrixU; | ||||
|   static inline MatrixL getL(const MatrixType& m) { return m; } | ||||
|   static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); } | ||||
|   static bool inplace_decomposition(MatrixType& m) | ||||
|   { return llt_inplace<typename MatrixType::Scalar, Lower>::blocked(m)==-1; } | ||||
| }; | ||||
|  | ||||
| template<typename MatrixType> struct LLT_Traits<MatrixType,Upper> | ||||
| { | ||||
|   typedef const TriangularView<const typename MatrixType::AdjointReturnType, Lower> MatrixL; | ||||
|   typedef const TriangularView<const MatrixType, Upper> MatrixU; | ||||
|   static inline MatrixL getL(const MatrixType& m) { return m.adjoint(); } | ||||
|   static inline MatrixU getU(const MatrixType& m) { return m; } | ||||
|   static bool inplace_decomposition(MatrixType& m) | ||||
|   { return llt_inplace<typename MatrixType::Scalar, Upper>::blocked(m)==-1; } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /** Computes / recomputes the Cholesky decomposition A = LL^* = U^*U of \a matrix | ||||
|   * | ||||
|   * \returns a reference to *this | ||||
|   * | ||||
|   * Example: \include TutorialLinAlgComputeTwice.cpp | ||||
|   * Output: \verbinclude TutorialLinAlgComputeTwice.out | ||||
|   */ | ||||
| template<typename MatrixType, int _UpLo> | ||||
| LLT<MatrixType,_UpLo>& LLT<MatrixType,_UpLo>::compute(const MatrixType& a) | ||||
| { | ||||
|   eigen_assert(a.rows()==a.cols()); | ||||
|   const Index size = a.rows(); | ||||
|   m_matrix.resize(size, size); | ||||
|   m_matrix = a; | ||||
|  | ||||
|   m_isInitialized = true; | ||||
|   bool ok = Traits::inplace_decomposition(m_matrix); | ||||
|   m_info = ok ? Success : NumericalIssue; | ||||
|  | ||||
|   return *this; | ||||
| } | ||||
|  | ||||
| /** Performs a rank one update (or dowdate) of the current decomposition. | ||||
|   * If A = LL^* before the rank one update, | ||||
|   * then after it we have LL^* = A + sigma * v v^* where \a v must be a vector | ||||
|   * of same dimension. | ||||
|   */ | ||||
| template<typename _MatrixType, int _UpLo> | ||||
| template<typename VectorType> | ||||
| LLT<_MatrixType,_UpLo> LLT<_MatrixType,_UpLo>::rankUpdate(const VectorType& v, const RealScalar& sigma) | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorType); | ||||
|   eigen_assert(v.size()==m_matrix.cols()); | ||||
|   eigen_assert(m_isInitialized); | ||||
|   if(internal::llt_inplace<typename MatrixType::Scalar, UpLo>::rankUpdate(m_matrix,v,sigma)>=0) | ||||
|     m_info = NumericalIssue; | ||||
|   else | ||||
|     m_info = Success; | ||||
|  | ||||
|   return *this; | ||||
| } | ||||
|      | ||||
| namespace internal { | ||||
| template<typename _MatrixType, int UpLo, typename Rhs> | ||||
| struct solve_retval<LLT<_MatrixType, UpLo>, Rhs> | ||||
|   : solve_retval_base<LLT<_MatrixType, UpLo>, Rhs> | ||||
| { | ||||
|   typedef LLT<_MatrixType,UpLo> LLTType; | ||||
|   EIGEN_MAKE_SOLVE_HELPERS(LLTType,Rhs) | ||||
|  | ||||
|   template<typename Dest> void evalTo(Dest& dst) const | ||||
|   { | ||||
|     dst = rhs(); | ||||
|     dec().solveInPlace(dst); | ||||
|   } | ||||
| }; | ||||
| } | ||||
|  | ||||
| /** \internal use x = llt_object.solve(x); | ||||
|   *  | ||||
|   * This is the \em in-place version of solve(). | ||||
|   * | ||||
|   * \param bAndX represents both the right-hand side matrix b and result x. | ||||
|   * | ||||
|   * \returns true always! If you need to check for existence of solutions, use another decomposition like LU, QR, or SVD. | ||||
|   * | ||||
|   * This version avoids a copy when the right hand side matrix b is not | ||||
|   * needed anymore. | ||||
|   * | ||||
|   * \sa LLT::solve(), MatrixBase::llt() | ||||
|   */ | ||||
| template<typename MatrixType, int _UpLo> | ||||
| template<typename Derived> | ||||
| void LLT<MatrixType,_UpLo>::solveInPlace(MatrixBase<Derived> &bAndX) const | ||||
| { | ||||
|   eigen_assert(m_isInitialized && "LLT is not initialized."); | ||||
|   eigen_assert(m_matrix.rows()==bAndX.rows()); | ||||
|   matrixL().solveInPlace(bAndX); | ||||
|   matrixU().solveInPlace(bAndX); | ||||
| } | ||||
|  | ||||
| /** \returns the matrix represented by the decomposition, | ||||
|  * i.e., it returns the product: L L^*. | ||||
|  * This function is provided for debug purpose. */ | ||||
| template<typename MatrixType, int _UpLo> | ||||
| MatrixType LLT<MatrixType,_UpLo>::reconstructedMatrix() const | ||||
| { | ||||
|   eigen_assert(m_isInitialized && "LLT is not initialized."); | ||||
|   return matrixL() * matrixL().adjoint().toDenseMatrix(); | ||||
| } | ||||
|  | ||||
| /** \cholesky_module | ||||
|   * \returns the LLT decomposition of \c *this | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline const LLT<typename MatrixBase<Derived>::PlainObject> | ||||
| MatrixBase<Derived>::llt() const | ||||
| { | ||||
|   return LLT<PlainObject>(derived()); | ||||
| } | ||||
|  | ||||
| /** \cholesky_module | ||||
|   * \returns the LLT decomposition of \c *this | ||||
|   */ | ||||
| template<typename MatrixType, unsigned int UpLo> | ||||
| inline const LLT<typename SelfAdjointView<MatrixType, UpLo>::PlainObject, UpLo> | ||||
| SelfAdjointView<MatrixType, UpLo>::llt() const | ||||
| { | ||||
|   return LLT<PlainObject,UpLo>(m_matrix); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_LLT_H | ||||
							
								
								
									
										102
									
								
								latan/Eigen/src/Cholesky/LLT_MKL.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								latan/Eigen/src/Cholesky/LLT_MKL.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| /* | ||||
|  Copyright (c) 2011, Intel Corporation. All rights reserved. | ||||
|  | ||||
|  Redistribution and use in source and binary forms, with or without modification, | ||||
|  are permitted provided that the following conditions are met: | ||||
|  | ||||
|  * Redistributions of source code must retain the above copyright notice, this | ||||
|    list of conditions and the following disclaimer. | ||||
|  * Redistributions in binary form must reproduce the above copyright notice, | ||||
|    this list of conditions and the following disclaimer in the documentation | ||||
|    and/or other materials provided with the distribution. | ||||
|  * Neither the name of Intel Corporation nor the names of its contributors may | ||||
|    be used to endorse or promote products derived from this software without | ||||
|    specific prior written permission. | ||||
|  | ||||
|  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||||
|  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
|  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
|  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||||
|  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
|  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
|  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||||
|  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
|  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
|  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  | ||||
|  ******************************************************************************** | ||||
|  *   Content : Eigen bindings to Intel(R) MKL | ||||
|  *     LLt decomposition based on LAPACKE_?potrf function. | ||||
|  ******************************************************************************** | ||||
| */ | ||||
|  | ||||
| #ifndef EIGEN_LLT_MKL_H | ||||
| #define EIGEN_LLT_MKL_H | ||||
|  | ||||
| #include "Eigen/src/Core/util/MKL_support.h" | ||||
| #include <iostream> | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename Scalar> struct mkl_llt; | ||||
|  | ||||
| #define EIGEN_MKL_LLT(EIGTYPE, MKLTYPE, MKLPREFIX) \ | ||||
| template<> struct mkl_llt<EIGTYPE> \ | ||||
| { \ | ||||
|   template<typename MatrixType> \ | ||||
|   static inline typename MatrixType::Index potrf(MatrixType& m, char uplo) \ | ||||
|   { \ | ||||
|     lapack_int matrix_order; \ | ||||
|     lapack_int size, lda, info, StorageOrder; \ | ||||
|     EIGTYPE* a; \ | ||||
|     eigen_assert(m.rows()==m.cols()); \ | ||||
|     /* Set up parameters for ?potrf */ \ | ||||
|     size = m.rows(); \ | ||||
|     StorageOrder = MatrixType::Flags&RowMajorBit?RowMajor:ColMajor; \ | ||||
|     matrix_order = StorageOrder==RowMajor ? LAPACK_ROW_MAJOR : LAPACK_COL_MAJOR; \ | ||||
|     a = &(m.coeffRef(0,0)); \ | ||||
|     lda = m.outerStride(); \ | ||||
| \ | ||||
|     info = LAPACKE_##MKLPREFIX##potrf( matrix_order, uplo, size, (MKLTYPE*)a, lda ); \ | ||||
|     info = (info==0) ? Success : NumericalIssue; \ | ||||
|     return info; \ | ||||
|   } \ | ||||
| }; \ | ||||
| template<> struct llt_inplace<EIGTYPE, Lower> \ | ||||
| { \ | ||||
|   template<typename MatrixType> \ | ||||
|   static typename MatrixType::Index blocked(MatrixType& m) \ | ||||
|   { \ | ||||
|     return mkl_llt<EIGTYPE>::potrf(m, 'L'); \ | ||||
|   } \ | ||||
|   template<typename MatrixType, typename VectorType> \ | ||||
|   static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) \ | ||||
|   { return Eigen::internal::llt_rank_update_lower(mat, vec, sigma); } \ | ||||
| }; \ | ||||
| template<> struct llt_inplace<EIGTYPE, Upper> \ | ||||
| { \ | ||||
|   template<typename MatrixType> \ | ||||
|   static typename MatrixType::Index blocked(MatrixType& m) \ | ||||
|   { \ | ||||
|     return mkl_llt<EIGTYPE>::potrf(m, 'U'); \ | ||||
|   } \ | ||||
|   template<typename MatrixType, typename VectorType> \ | ||||
|   static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) \ | ||||
|   { \ | ||||
|     Transpose<MatrixType> matt(mat); \ | ||||
|     return llt_inplace<EIGTYPE, Lower>::rankUpdate(matt, vec.conjugate(), sigma); \ | ||||
|   } \ | ||||
| }; | ||||
|  | ||||
| EIGEN_MKL_LLT(double, double, d) | ||||
| EIGEN_MKL_LLT(float, float, s) | ||||
| EIGEN_MKL_LLT(dcomplex, MKL_Complex16, z) | ||||
| EIGEN_MKL_LLT(scomplex, MKL_Complex8, c) | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_LLT_MKL_H | ||||
							
								
								
									
										579
									
								
								latan/Eigen/src/CholmodSupport/CholmodSupport.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										579
									
								
								latan/Eigen/src/CholmodSupport/CholmodSupport.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,579 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_CHOLMODSUPPORT_H | ||||
| #define EIGEN_CHOLMODSUPPORT_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename Scalar, typename CholmodType> | ||||
| void cholmod_configure_matrix(CholmodType& mat) | ||||
| { | ||||
|   if (internal::is_same<Scalar,float>::value) | ||||
|   { | ||||
|     mat.xtype = CHOLMOD_REAL; | ||||
|     mat.dtype = CHOLMOD_SINGLE; | ||||
|   } | ||||
|   else if (internal::is_same<Scalar,double>::value) | ||||
|   { | ||||
|     mat.xtype = CHOLMOD_REAL; | ||||
|     mat.dtype = CHOLMOD_DOUBLE; | ||||
|   } | ||||
|   else if (internal::is_same<Scalar,std::complex<float> >::value) | ||||
|   { | ||||
|     mat.xtype = CHOLMOD_COMPLEX; | ||||
|     mat.dtype = CHOLMOD_SINGLE; | ||||
|   } | ||||
|   else if (internal::is_same<Scalar,std::complex<double> >::value) | ||||
|   { | ||||
|     mat.xtype = CHOLMOD_COMPLEX; | ||||
|     mat.dtype = CHOLMOD_DOUBLE; | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     eigen_assert(false && "Scalar type not supported by CHOLMOD"); | ||||
|   } | ||||
| } | ||||
|  | ||||
| } // namespace internal | ||||
|  | ||||
| /** Wraps the Eigen sparse matrix \a mat into a Cholmod sparse matrix object. | ||||
|   * Note that the data are shared. | ||||
|   */ | ||||
| template<typename _Scalar, int _Options, typename _Index> | ||||
| cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_Index>& mat) | ||||
| { | ||||
|   typedef SparseMatrix<_Scalar,_Options,_Index> MatrixType; | ||||
|   cholmod_sparse res; | ||||
|   res.nzmax   = mat.nonZeros(); | ||||
|   res.nrow    = mat.rows();; | ||||
|   res.ncol    = mat.cols(); | ||||
|   res.p       = mat.outerIndexPtr(); | ||||
|   res.i       = mat.innerIndexPtr(); | ||||
|   res.x       = mat.valuePtr(); | ||||
|   res.sorted  = 1; | ||||
|   if(mat.isCompressed()) | ||||
|   { | ||||
|     res.packed  = 1; | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     res.packed  = 0; | ||||
|     res.nz = mat.innerNonZeroPtr(); | ||||
|   } | ||||
|  | ||||
|   res.dtype   = 0; | ||||
|   res.stype   = -1; | ||||
|    | ||||
|   if (internal::is_same<_Index,int>::value) | ||||
|   { | ||||
|     res.itype = CHOLMOD_INT; | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     eigen_assert(false && "Index type different than int is not supported yet"); | ||||
|   } | ||||
|  | ||||
|   // setup res.xtype | ||||
|   internal::cholmod_configure_matrix<_Scalar>(res); | ||||
|    | ||||
|   res.stype = 0; | ||||
|    | ||||
|   return res; | ||||
| } | ||||
|  | ||||
| template<typename _Scalar, int _Options, typename _Index> | ||||
| const cholmod_sparse viewAsCholmod(const SparseMatrix<_Scalar,_Options,_Index>& mat) | ||||
| { | ||||
|   cholmod_sparse res = viewAsCholmod(mat.const_cast_derived()); | ||||
|   return res; | ||||
| } | ||||
|  | ||||
| /** Returns a view of the Eigen sparse matrix \a mat as Cholmod sparse matrix. | ||||
|   * The data are not copied but shared. */ | ||||
| template<typename _Scalar, int _Options, typename _Index, unsigned int UpLo> | ||||
| cholmod_sparse viewAsCholmod(const SparseSelfAdjointView<SparseMatrix<_Scalar,_Options,_Index>, UpLo>& mat) | ||||
| { | ||||
|   cholmod_sparse res = viewAsCholmod(mat.matrix().const_cast_derived()); | ||||
|    | ||||
|   if(UpLo==Upper) res.stype =  1; | ||||
|   if(UpLo==Lower) res.stype = -1; | ||||
|  | ||||
|   return res; | ||||
| } | ||||
|  | ||||
| /** Returns a view of the Eigen \b dense matrix \a mat as Cholmod dense matrix. | ||||
|   * The data are not copied but shared. */ | ||||
| template<typename Derived> | ||||
| cholmod_dense viewAsCholmod(MatrixBase<Derived>& mat) | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT((internal::traits<Derived>::Flags&RowMajorBit)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES); | ||||
|   typedef typename Derived::Scalar Scalar; | ||||
|  | ||||
|   cholmod_dense res; | ||||
|   res.nrow   = mat.rows(); | ||||
|   res.ncol   = mat.cols(); | ||||
|   res.nzmax  = res.nrow * res.ncol; | ||||
|   res.d      = Derived::IsVectorAtCompileTime ? mat.derived().size() : mat.derived().outerStride(); | ||||
|   res.x      = mat.derived().data(); | ||||
|   res.z      = 0; | ||||
|  | ||||
|   internal::cholmod_configure_matrix<Scalar>(res); | ||||
|  | ||||
|   return res; | ||||
| } | ||||
|  | ||||
| /** Returns a view of the Cholmod sparse matrix \a cm as an Eigen sparse matrix. | ||||
|   * The data are not copied but shared. */ | ||||
| template<typename Scalar, int Flags, typename Index> | ||||
| MappedSparseMatrix<Scalar,Flags,Index> viewAsEigen(cholmod_sparse& cm) | ||||
| { | ||||
|   return MappedSparseMatrix<Scalar,Flags,Index> | ||||
|          (cm.nrow, cm.ncol, reinterpret_cast<Index*>(cm.p)[cm.ncol], | ||||
|           reinterpret_cast<Index*>(cm.p), reinterpret_cast<Index*>(cm.i),reinterpret_cast<Scalar*>(cm.x) ); | ||||
| } | ||||
|  | ||||
| enum CholmodMode { | ||||
|   CholmodAuto, CholmodSimplicialLLt, CholmodSupernodalLLt, CholmodLDLt | ||||
| }; | ||||
|  | ||||
|  | ||||
| /** \ingroup CholmodSupport_Module | ||||
|   * \class CholmodBase | ||||
|   * \brief The base class for the direct Cholesky factorization of Cholmod | ||||
|   * \sa class CholmodSupernodalLLT, class CholmodSimplicialLDLT, class CholmodSimplicialLLT | ||||
|   */ | ||||
| template<typename _MatrixType, int _UpLo, typename Derived> | ||||
| class CholmodBase : internal::noncopyable | ||||
| { | ||||
|   public: | ||||
|     typedef _MatrixType MatrixType; | ||||
|     enum { UpLo = _UpLo }; | ||||
|     typedef typename MatrixType::Scalar Scalar; | ||||
|     typedef typename MatrixType::RealScalar RealScalar; | ||||
|     typedef MatrixType CholMatrixType; | ||||
|     typedef typename MatrixType::Index Index; | ||||
|  | ||||
|   public: | ||||
|  | ||||
|     CholmodBase() | ||||
|       : m_cholmodFactor(0), m_info(Success), m_isInitialized(false) | ||||
|     { | ||||
|       cholmod_start(&m_cholmod); | ||||
|     } | ||||
|  | ||||
|     CholmodBase(const MatrixType& matrix) | ||||
|       : m_cholmodFactor(0), m_info(Success), m_isInitialized(false) | ||||
|     { | ||||
|       cholmod_start(&m_cholmod); | ||||
|       compute(matrix); | ||||
|     } | ||||
|  | ||||
|     ~CholmodBase() | ||||
|     { | ||||
|       if(m_cholmodFactor) | ||||
|         cholmod_free_factor(&m_cholmodFactor, &m_cholmod); | ||||
|       cholmod_finish(&m_cholmod); | ||||
|     } | ||||
|      | ||||
|     inline Index cols() const { return m_cholmodFactor->n; } | ||||
|     inline Index rows() const { return m_cholmodFactor->n; } | ||||
|      | ||||
|     Derived& derived() { return *static_cast<Derived*>(this); } | ||||
|     const Derived& derived() const { return *static_cast<const Derived*>(this); } | ||||
|      | ||||
|     /** \brief Reports whether previous computation was successful. | ||||
|       * | ||||
|       * \returns \c Success if computation was succesful, | ||||
|       *          \c NumericalIssue if the matrix.appears to be negative. | ||||
|       */ | ||||
|     ComputationInfo info() const | ||||
|     { | ||||
|       eigen_assert(m_isInitialized && "Decomposition is not initialized."); | ||||
|       return m_info; | ||||
|     } | ||||
|  | ||||
|     /** Computes the sparse Cholesky decomposition of \a matrix */ | ||||
|     Derived& compute(const MatrixType& matrix) | ||||
|     { | ||||
|       analyzePattern(matrix); | ||||
|       factorize(matrix); | ||||
|       return derived(); | ||||
|     } | ||||
|      | ||||
|     /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. | ||||
|       * | ||||
|       * \sa compute() | ||||
|       */ | ||||
|     template<typename Rhs> | ||||
|     inline const internal::solve_retval<CholmodBase, Rhs> | ||||
|     solve(const MatrixBase<Rhs>& b) const | ||||
|     { | ||||
|       eigen_assert(m_isInitialized && "LLT is not initialized."); | ||||
|       eigen_assert(rows()==b.rows() | ||||
|                 && "CholmodDecomposition::solve(): invalid number of rows of the right hand side matrix b"); | ||||
|       return internal::solve_retval<CholmodBase, Rhs>(*this, b.derived()); | ||||
|     } | ||||
|      | ||||
|     /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. | ||||
|       * | ||||
|       * \sa compute() | ||||
|       */ | ||||
|     template<typename Rhs> | ||||
|     inline const internal::sparse_solve_retval<CholmodBase, Rhs> | ||||
|     solve(const SparseMatrixBase<Rhs>& b) const | ||||
|     { | ||||
|       eigen_assert(m_isInitialized && "LLT is not initialized."); | ||||
|       eigen_assert(rows()==b.rows() | ||||
|                 && "CholmodDecomposition::solve(): invalid number of rows of the right hand side matrix b"); | ||||
|       return internal::sparse_solve_retval<CholmodBase, Rhs>(*this, b.derived()); | ||||
|     } | ||||
|      | ||||
|     /** Performs a symbolic decomposition on the sparcity of \a matrix. | ||||
|       * | ||||
|       * This function is particularly useful when solving for several problems having the same structure. | ||||
|       *  | ||||
|       * \sa factorize() | ||||
|       */ | ||||
|     void analyzePattern(const MatrixType& matrix) | ||||
|     { | ||||
|       if(m_cholmodFactor) | ||||
|       { | ||||
|         cholmod_free_factor(&m_cholmodFactor, &m_cholmod); | ||||
|         m_cholmodFactor = 0; | ||||
|       } | ||||
|       cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>()); | ||||
|       m_cholmodFactor = cholmod_analyze(&A, &m_cholmod); | ||||
|        | ||||
|       this->m_isInitialized = true; | ||||
|       this->m_info = Success; | ||||
|       m_analysisIsOk = true; | ||||
|       m_factorizationIsOk = false; | ||||
|     } | ||||
|      | ||||
|     /** Performs a numeric decomposition of \a matrix | ||||
|       * | ||||
|       * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. | ||||
|       * | ||||
|       * \sa analyzePattern() | ||||
|       */ | ||||
|     void factorize(const MatrixType& matrix) | ||||
|     { | ||||
|       eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); | ||||
|       cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>()); | ||||
|       cholmod_factorize(&A, m_cholmodFactor, &m_cholmod); | ||||
|        | ||||
|       this->m_info = Success; | ||||
|       m_factorizationIsOk = true; | ||||
|     } | ||||
|      | ||||
|     /** Returns a reference to the Cholmod's configuration structure to get a full control over the performed operations. | ||||
|      *  See the Cholmod user guide for details. */ | ||||
|     cholmod_common& cholmod() { return m_cholmod; } | ||||
|      | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /** \internal */ | ||||
|     template<typename Rhs,typename Dest> | ||||
|     void _solve(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const | ||||
|     { | ||||
|       eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); | ||||
|       const Index size = m_cholmodFactor->n; | ||||
|       eigen_assert(size==b.rows()); | ||||
|  | ||||
|       // note: cd stands for Cholmod Dense | ||||
|       cholmod_dense b_cd = viewAsCholmod(b.const_cast_derived()); | ||||
|       cholmod_dense* x_cd = cholmod_solve(CHOLMOD_A, m_cholmodFactor, &b_cd, &m_cholmod); | ||||
|       if(!x_cd) | ||||
|       { | ||||
|         this->m_info = NumericalIssue; | ||||
|       } | ||||
|       // TODO optimize this copy by swapping when possible (be carreful with alignment, etc.) | ||||
|       dest = Matrix<Scalar,Dest::RowsAtCompileTime,Dest::ColsAtCompileTime>::Map(reinterpret_cast<Scalar*>(x_cd->x),b.rows(),b.cols()); | ||||
|       cholmod_free_dense(&x_cd, &m_cholmod); | ||||
|     } | ||||
|      | ||||
|     /** \internal */ | ||||
|     template<typename RhsScalar, int RhsOptions, typename RhsIndex, typename DestScalar, int DestOptions, typename DestIndex> | ||||
|     void _solve(const SparseMatrix<RhsScalar,RhsOptions,RhsIndex> &b, SparseMatrix<DestScalar,DestOptions,DestIndex> &dest) const | ||||
|     { | ||||
|       eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); | ||||
|       const Index size = m_cholmodFactor->n; | ||||
|       eigen_assert(size==b.rows()); | ||||
|  | ||||
|       // note: cs stands for Cholmod Sparse | ||||
|       cholmod_sparse b_cs = viewAsCholmod(b); | ||||
|       cholmod_sparse* x_cs = cholmod_spsolve(CHOLMOD_A, m_cholmodFactor, &b_cs, &m_cholmod); | ||||
|       if(!x_cs) | ||||
|       { | ||||
|         this->m_info = NumericalIssue; | ||||
|       } | ||||
|       // TODO optimize this copy by swapping when possible (be carreful with alignment, etc.) | ||||
|       dest = viewAsEigen<DestScalar,DestOptions,DestIndex>(*x_cs); | ||||
|       cholmod_free_sparse(&x_cs, &m_cholmod); | ||||
|     } | ||||
|     #endif // EIGEN_PARSED_BY_DOXYGEN | ||||
|      | ||||
|     template<typename Stream> | ||||
|     void dumpMemory(Stream& s) | ||||
|     {} | ||||
|      | ||||
|   protected: | ||||
|     mutable cholmod_common m_cholmod; | ||||
|     cholmod_factor* m_cholmodFactor; | ||||
|     mutable ComputationInfo m_info; | ||||
|     bool m_isInitialized; | ||||
|     int m_factorizationIsOk; | ||||
|     int m_analysisIsOk; | ||||
| }; | ||||
|  | ||||
| /** \ingroup CholmodSupport_Module | ||||
|   * \class CholmodSimplicialLLT | ||||
|   * \brief A simplicial direct Cholesky (LLT) factorization and solver based on Cholmod | ||||
|   * | ||||
|   * This class allows to solve for A.X = B sparse linear problems via a simplicial LL^T Cholesky factorization | ||||
|   * using the Cholmod library. | ||||
|   * This simplicial variant is equivalent to Eigen's built-in SimplicialLLT class. Thefore, it has little practical interest. | ||||
|   * The sparse matrix A must be selfajoint and positive definite. The vectors or matrices | ||||
|   * X and B can be either dense or sparse. | ||||
|   * | ||||
|   * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> | ||||
|   * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower | ||||
|   *               or Upper. Default is Lower. | ||||
|   * | ||||
|   * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. | ||||
|   * | ||||
|   * \sa \ref TutorialSparseDirectSolvers, class CholmodSupernodalLLT, class SimplicialLLT | ||||
|   */ | ||||
| template<typename _MatrixType, int _UpLo = Lower> | ||||
| class CholmodSimplicialLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLLT<_MatrixType, _UpLo> > | ||||
| { | ||||
|     typedef CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLLT> Base; | ||||
|     using Base::m_cholmod; | ||||
|      | ||||
|   public: | ||||
|      | ||||
|     typedef _MatrixType MatrixType; | ||||
|      | ||||
|     CholmodSimplicialLLT() : Base() { init(); } | ||||
|  | ||||
|     CholmodSimplicialLLT(const MatrixType& matrix) : Base() | ||||
|     { | ||||
|       init(); | ||||
|       compute(matrix); | ||||
|     } | ||||
|  | ||||
|     ~CholmodSimplicialLLT() {} | ||||
|   protected: | ||||
|     void init() | ||||
|     { | ||||
|       m_cholmod.final_asis = 0; | ||||
|       m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; | ||||
|       m_cholmod.final_ll = 1; | ||||
|     } | ||||
| }; | ||||
|  | ||||
|  | ||||
| /** \ingroup CholmodSupport_Module | ||||
|   * \class CholmodSimplicialLDLT | ||||
|   * \brief A simplicial direct Cholesky (LDLT) factorization and solver based on Cholmod | ||||
|   * | ||||
|   * This class allows to solve for A.X = B sparse linear problems via a simplicial LDL^T Cholesky factorization | ||||
|   * using the Cholmod library. | ||||
|   * This simplicial variant is equivalent to Eigen's built-in SimplicialLDLT class. Thefore, it has little practical interest. | ||||
|   * The sparse matrix A must be selfajoint and positive definite. The vectors or matrices | ||||
|   * X and B can be either dense or sparse. | ||||
|   * | ||||
|   * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> | ||||
|   * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower | ||||
|   *               or Upper. Default is Lower. | ||||
|   * | ||||
|   * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. | ||||
|   * | ||||
|   * \sa \ref TutorialSparseDirectSolvers, class CholmodSupernodalLLT, class SimplicialLDLT | ||||
|   */ | ||||
| template<typename _MatrixType, int _UpLo = Lower> | ||||
| class CholmodSimplicialLDLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLDLT<_MatrixType, _UpLo> > | ||||
| { | ||||
|     typedef CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLDLT> Base; | ||||
|     using Base::m_cholmod; | ||||
|      | ||||
|   public: | ||||
|      | ||||
|     typedef _MatrixType MatrixType; | ||||
|      | ||||
|     CholmodSimplicialLDLT() : Base() { init(); } | ||||
|  | ||||
|     CholmodSimplicialLDLT(const MatrixType& matrix) : Base() | ||||
|     { | ||||
|       init(); | ||||
|       compute(matrix); | ||||
|     } | ||||
|  | ||||
|     ~CholmodSimplicialLDLT() {} | ||||
|   protected: | ||||
|     void init() | ||||
|     { | ||||
|       m_cholmod.final_asis = 1; | ||||
|       m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| /** \ingroup CholmodSupport_Module | ||||
|   * \class CholmodSupernodalLLT | ||||
|   * \brief A supernodal Cholesky (LLT) factorization and solver based on Cholmod | ||||
|   * | ||||
|   * This class allows to solve for A.X = B sparse linear problems via a supernodal LL^T Cholesky factorization | ||||
|   * using the Cholmod library. | ||||
|   * This supernodal variant performs best on dense enough problems, e.g., 3D FEM, or very high order 2D FEM. | ||||
|   * The sparse matrix A must be selfajoint and positive definite. The vectors or matrices | ||||
|   * X and B can be either dense or sparse. | ||||
|   * | ||||
|   * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> | ||||
|   * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower | ||||
|   *               or Upper. Default is Lower. | ||||
|   * | ||||
|   * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. | ||||
|   * | ||||
|   * \sa \ref TutorialSparseDirectSolvers | ||||
|   */ | ||||
| template<typename _MatrixType, int _UpLo = Lower> | ||||
| class CholmodSupernodalLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSupernodalLLT<_MatrixType, _UpLo> > | ||||
| { | ||||
|     typedef CholmodBase<_MatrixType, _UpLo, CholmodSupernodalLLT> Base; | ||||
|     using Base::m_cholmod; | ||||
|      | ||||
|   public: | ||||
|      | ||||
|     typedef _MatrixType MatrixType; | ||||
|      | ||||
|     CholmodSupernodalLLT() : Base() { init(); } | ||||
|  | ||||
|     CholmodSupernodalLLT(const MatrixType& matrix) : Base() | ||||
|     { | ||||
|       init(); | ||||
|       compute(matrix); | ||||
|     } | ||||
|  | ||||
|     ~CholmodSupernodalLLT() {} | ||||
|   protected: | ||||
|     void init() | ||||
|     { | ||||
|       m_cholmod.final_asis = 1; | ||||
|       m_cholmod.supernodal = CHOLMOD_SUPERNODAL; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| /** \ingroup CholmodSupport_Module | ||||
|   * \class CholmodDecomposition | ||||
|   * \brief A general Cholesky factorization and solver based on Cholmod | ||||
|   * | ||||
|   * This class allows to solve for A.X = B sparse linear problems via a LL^T or LDL^T Cholesky factorization | ||||
|   * using the Cholmod library. The sparse matrix A must be selfajoint and positive definite. The vectors or matrices | ||||
|   * X and B can be either dense or sparse. | ||||
|   * | ||||
|   * This variant permits to change the underlying Cholesky method at runtime. | ||||
|   * On the other hand, it does not provide access to the result of the factorization. | ||||
|   * The default is to let Cholmod automatically choose between a simplicial and supernodal factorization. | ||||
|   * | ||||
|   * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> | ||||
|   * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower | ||||
|   *               or Upper. Default is Lower. | ||||
|   * | ||||
|   * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. | ||||
|   * | ||||
|   * \sa \ref TutorialSparseDirectSolvers | ||||
|   */ | ||||
| template<typename _MatrixType, int _UpLo = Lower> | ||||
| class CholmodDecomposition : public CholmodBase<_MatrixType, _UpLo, CholmodDecomposition<_MatrixType, _UpLo> > | ||||
| { | ||||
|     typedef CholmodBase<_MatrixType, _UpLo, CholmodDecomposition> Base; | ||||
|     using Base::m_cholmod; | ||||
|      | ||||
|   public: | ||||
|      | ||||
|     typedef _MatrixType MatrixType; | ||||
|      | ||||
|     CholmodDecomposition() : Base() { init(); } | ||||
|  | ||||
|     CholmodDecomposition(const MatrixType& matrix) : Base() | ||||
|     { | ||||
|       init(); | ||||
|       compute(matrix); | ||||
|     } | ||||
|  | ||||
|     ~CholmodDecomposition() {} | ||||
|      | ||||
|     void setMode(CholmodMode mode) | ||||
|     { | ||||
|       switch(mode) | ||||
|       { | ||||
|         case CholmodAuto: | ||||
|           m_cholmod.final_asis = 1; | ||||
|           m_cholmod.supernodal = CHOLMOD_AUTO; | ||||
|           break; | ||||
|         case CholmodSimplicialLLt: | ||||
|           m_cholmod.final_asis = 0; | ||||
|           m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; | ||||
|           m_cholmod.final_ll = 1; | ||||
|           break; | ||||
|         case CholmodSupernodalLLt: | ||||
|           m_cholmod.final_asis = 1; | ||||
|           m_cholmod.supernodal = CHOLMOD_SUPERNODAL; | ||||
|           break; | ||||
|         case CholmodLDLt: | ||||
|           m_cholmod.final_asis = 1; | ||||
|           m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; | ||||
|           break; | ||||
|         default: | ||||
|           break; | ||||
|       } | ||||
|     } | ||||
|   protected: | ||||
|     void init() | ||||
|     { | ||||
|       m_cholmod.final_asis = 1; | ||||
|       m_cholmod.supernodal = CHOLMOD_AUTO; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| namespace internal { | ||||
|    | ||||
| template<typename _MatrixType, int _UpLo, typename Derived, typename Rhs> | ||||
| struct solve_retval<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs> | ||||
|   : solve_retval_base<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs> | ||||
| { | ||||
|   typedef CholmodBase<_MatrixType,_UpLo,Derived> Dec; | ||||
|   EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) | ||||
|  | ||||
|   template<typename Dest> void evalTo(Dest& dst) const | ||||
|   { | ||||
|     dec()._solve(rhs(),dst); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename _MatrixType, int _UpLo, typename Derived, typename Rhs> | ||||
| struct sparse_solve_retval<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs> | ||||
|   : sparse_solve_retval_base<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs> | ||||
| { | ||||
|   typedef CholmodBase<_MatrixType,_UpLo,Derived> Dec; | ||||
|   EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) | ||||
|  | ||||
|   template<typename Dest> void evalTo(Dest& dst) const | ||||
|   { | ||||
|     dec()._solve(rhs(),dst); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_CHOLMODSUPPORT_H | ||||
							
								
								
									
										308
									
								
								latan/Eigen/src/Core/Array.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										308
									
								
								latan/Eigen/src/Core/Array.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,308 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_ARRAY_H | ||||
| #define EIGEN_ARRAY_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| /** \class Array  | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief General-purpose arrays with easy API for coefficient-wise operations | ||||
|   * | ||||
|   * The %Array class is very similar to the Matrix class. It provides | ||||
|   * general-purpose one- and two-dimensional arrays. The difference between the | ||||
|   * %Array and the %Matrix class is primarily in the API: the API for the | ||||
|   * %Array class provides easy access to coefficient-wise operations, while the | ||||
|   * API for the %Matrix class provides easy access to linear-algebra | ||||
|   * operations. | ||||
|   * | ||||
|   * This class can be extended with the help of the plugin mechanism described on the page | ||||
|   * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_ARRAY_PLUGIN. | ||||
|   * | ||||
|   * \sa \ref TutorialArrayClass, \ref TopicClassHierarchy | ||||
|   */ | ||||
| namespace internal { | ||||
| template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> | ||||
| struct traits<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > : traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > | ||||
| { | ||||
|   typedef ArrayXpr XprKind; | ||||
|   typedef ArrayBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > XprBase; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> | ||||
| class Array | ||||
|   : public PlainObjectBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef PlainObjectBase<Array> Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(Array) | ||||
|  | ||||
|     enum { Options = _Options }; | ||||
|     typedef typename Base::PlainObject PlainObject; | ||||
|  | ||||
|   protected: | ||||
|     template <typename Derived, typename OtherDerived, bool IsVector> | ||||
|     friend struct internal::conservative_resize_like_impl; | ||||
|  | ||||
|     using Base::m_storage; | ||||
|  | ||||
|   public: | ||||
|  | ||||
|     using Base::base; | ||||
|     using Base::coeff; | ||||
|     using Base::coeffRef; | ||||
|  | ||||
|     /** | ||||
|       * The usage of | ||||
|       *   using Base::operator=; | ||||
|       * fails on MSVC. Since the code below is working with GCC and MSVC, we skipped | ||||
|       * the usage of 'using'. This should be done only for operator=. | ||||
|       */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE Array& operator=(const EigenBase<OtherDerived> &other) | ||||
|     { | ||||
|       return Base::operator=(other); | ||||
|     } | ||||
|  | ||||
|     /** Copies the value of the expression \a other into \c *this with automatic resizing. | ||||
|       * | ||||
|       * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), | ||||
|       * it will be initialized. | ||||
|       * | ||||
|       * Note that copying a row-vector into a vector (and conversely) is allowed. | ||||
|       * The resizing, if any, is then done in the appropriate way so that row-vectors | ||||
|       * remain row-vectors and vectors remain vectors. | ||||
|       */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE Array& operator=(const ArrayBase<OtherDerived>& other) | ||||
|     { | ||||
|       return Base::_set(other); | ||||
|     } | ||||
|  | ||||
|     /** This is a special case of the templated operator=. Its purpose is to | ||||
|       * prevent a default operator= from hiding the templated operator=. | ||||
|       */ | ||||
|     EIGEN_STRONG_INLINE Array& operator=(const Array& other) | ||||
|     { | ||||
|       return Base::_set(other); | ||||
|     } | ||||
|  | ||||
|     /** Default constructor. | ||||
|       * | ||||
|       * For fixed-size matrices, does nothing. | ||||
|       * | ||||
|       * For dynamic-size matrices, creates an empty matrix of size 0. Does not allocate any array. Such a matrix | ||||
|       * is called a null matrix. This constructor is the unique way to create null matrices: resizing | ||||
|       * a matrix to 0 is not supported. | ||||
|       * | ||||
|       * \sa resize(Index,Index) | ||||
|       */ | ||||
|     EIGEN_STRONG_INLINE explicit Array() : Base() | ||||
|     { | ||||
|       Base::_check_template_params(); | ||||
|       EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED | ||||
|     } | ||||
|  | ||||
| #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     // FIXME is it still needed ?? | ||||
|     /** \internal */ | ||||
|     Array(internal::constructor_without_unaligned_array_assert) | ||||
|       : Base(internal::constructor_without_unaligned_array_assert()) | ||||
|     { | ||||
|       Base::_check_template_params(); | ||||
|       EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|     /** Constructs a vector or row-vector with given dimension. \only_for_vectors | ||||
|       * | ||||
|       * Note that this is only useful for dynamic-size vectors. For fixed-size vectors, | ||||
|       * it is redundant to pass the dimension here, so it makes more sense to use the default | ||||
|       * constructor Matrix() instead. | ||||
|       */ | ||||
|     EIGEN_STRONG_INLINE explicit Array(Index dim) | ||||
|       : Base(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim) | ||||
|     { | ||||
|       Base::_check_template_params(); | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_ONLY(Array) | ||||
|       eigen_assert(dim >= 0); | ||||
|       eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim); | ||||
|       EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED | ||||
|     } | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     template<typename T0, typename T1> | ||||
|     EIGEN_STRONG_INLINE Array(const T0& x, const T1& y) | ||||
|     { | ||||
|       Base::_check_template_params(); | ||||
|       this->template _init2<T0,T1>(x, y); | ||||
|     } | ||||
|     #else | ||||
|     /** constructs an uninitialized matrix with \a rows rows and \a cols columns. | ||||
|       * | ||||
|       * This is useful for dynamic-size matrices. For fixed-size matrices, | ||||
|       * it is redundant to pass these parameters, so one should use the default constructor | ||||
|       * Matrix() instead. */ | ||||
|     Array(Index rows, Index cols); | ||||
|     /** constructs an initialized 2D vector with given coefficients */ | ||||
|     Array(const Scalar& x, const Scalar& y); | ||||
|     #endif | ||||
|  | ||||
|     /** constructs an initialized 3D vector with given coefficients */ | ||||
|     EIGEN_STRONG_INLINE Array(const Scalar& x, const Scalar& y, const Scalar& z) | ||||
|     { | ||||
|       Base::_check_template_params(); | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 3) | ||||
|       m_storage.data()[0] = x; | ||||
|       m_storage.data()[1] = y; | ||||
|       m_storage.data()[2] = z; | ||||
|     } | ||||
|     /** constructs an initialized 4D vector with given coefficients */ | ||||
|     EIGEN_STRONG_INLINE Array(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w) | ||||
|     { | ||||
|       Base::_check_template_params(); | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 4) | ||||
|       m_storage.data()[0] = x; | ||||
|       m_storage.data()[1] = y; | ||||
|       m_storage.data()[2] = z; | ||||
|       m_storage.data()[3] = w; | ||||
|     } | ||||
|  | ||||
|     explicit Array(const Scalar *data); | ||||
|  | ||||
|     /** Constructor copying the value of the expression \a other */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE Array(const ArrayBase<OtherDerived>& other) | ||||
|              : Base(other.rows() * other.cols(), other.rows(), other.cols()) | ||||
|     { | ||||
|       Base::_check_template_params(); | ||||
|       Base::_set_noalias(other); | ||||
|     } | ||||
|     /** Copy constructor */ | ||||
|     EIGEN_STRONG_INLINE Array(const Array& other) | ||||
|             : Base(other.rows() * other.cols(), other.rows(), other.cols()) | ||||
|     { | ||||
|       Base::_check_template_params(); | ||||
|       Base::_set_noalias(other); | ||||
|     } | ||||
|     /** Copy constructor with in-place evaluation */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE Array(const ReturnByValue<OtherDerived>& other) | ||||
|     { | ||||
|       Base::_check_template_params(); | ||||
|       Base::resize(other.rows(), other.cols()); | ||||
|       other.evalTo(*this); | ||||
|     } | ||||
|  | ||||
|     /** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE Array(const EigenBase<OtherDerived> &other) | ||||
|       : Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) | ||||
|     { | ||||
|       Base::_check_template_params(); | ||||
|       Base::resize(other.rows(), other.cols()); | ||||
|       *this = other; | ||||
|     } | ||||
|  | ||||
|     /** Override MatrixBase::swap() since for dynamic-sized matrices of same type it is enough to swap the | ||||
|       * data pointers. | ||||
|       */ | ||||
|     template<typename OtherDerived> | ||||
|     void swap(ArrayBase<OtherDerived> const & other) | ||||
|     { this->_swap(other.derived()); } | ||||
|  | ||||
|     inline Index innerStride() const { return 1; } | ||||
|     inline Index outerStride() const { return this->innerSize(); } | ||||
|  | ||||
|     #ifdef EIGEN_ARRAY_PLUGIN | ||||
|     #include EIGEN_ARRAY_PLUGIN | ||||
|     #endif | ||||
|  | ||||
|   private: | ||||
|  | ||||
|     template<typename MatrixType, typename OtherDerived, bool SwapPointers> | ||||
|     friend struct internal::matrix_swap_impl; | ||||
| }; | ||||
|  | ||||
| /** \defgroup arraytypedefs Global array typedefs | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * Eigen defines several typedef shortcuts for most common 1D and 2D array types. | ||||
|   * | ||||
|   * The general patterns are the following: | ||||
|   * | ||||
|   * \c ArrayRowsColsType where \c Rows and \c Cols can be \c 2,\c 3,\c 4 for fixed size square matrices or \c X for dynamic size, | ||||
|   * and where \c Type can be \c i for integer, \c f for float, \c d for double, \c cf for complex float, \c cd | ||||
|   * for complex double. | ||||
|   * | ||||
|   * For example, \c Array33d is a fixed-size 3x3 array type of doubles, and \c ArrayXXf is a dynamic-size matrix of floats. | ||||
|   * | ||||
|   * There are also \c ArraySizeType which are self-explanatory. For example, \c Array4cf is | ||||
|   * a fixed-size 1D array of 4 complex floats. | ||||
|   * | ||||
|   * \sa class Array | ||||
|   */ | ||||
|  | ||||
| #define EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix)   \ | ||||
| /** \ingroup arraytypedefs */                                    \ | ||||
| typedef Array<Type, Size, Size> Array##SizeSuffix##SizeSuffix##TypeSuffix;  \ | ||||
| /** \ingroup arraytypedefs */                                    \ | ||||
| typedef Array<Type, Size, 1>    Array##SizeSuffix##TypeSuffix; | ||||
|  | ||||
| #define EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, Size)         \ | ||||
| /** \ingroup arraytypedefs */                                    \ | ||||
| typedef Array<Type, Size, Dynamic> Array##Size##X##TypeSuffix;  \ | ||||
| /** \ingroup arraytypedefs */                                    \ | ||||
| typedef Array<Type, Dynamic, Size> Array##X##Size##TypeSuffix; | ||||
|  | ||||
| #define EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \ | ||||
| EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 2, 2) \ | ||||
| EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 3, 3) \ | ||||
| EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 4, 4) \ | ||||
| EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Dynamic, X) \ | ||||
| EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 2) \ | ||||
| EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 3) \ | ||||
| EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 4) | ||||
|  | ||||
| EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(int,                  i) | ||||
| EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(float,                f) | ||||
| EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(double,               d) | ||||
| EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<float>,  cf) | ||||
| EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<double>, cd) | ||||
|  | ||||
| #undef EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES | ||||
| #undef EIGEN_MAKE_ARRAY_TYPEDEFS | ||||
|  | ||||
| #undef EIGEN_MAKE_ARRAY_TYPEDEFS_LARGE | ||||
|  | ||||
| #define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \ | ||||
| using Eigen::Matrix##SizeSuffix##TypeSuffix; \ | ||||
| using Eigen::Vector##SizeSuffix##TypeSuffix; \ | ||||
| using Eigen::RowVector##SizeSuffix##TypeSuffix; | ||||
|  | ||||
| #define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(TypeSuffix) \ | ||||
| EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \ | ||||
| EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \ | ||||
| EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \ | ||||
| EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \ | ||||
|  | ||||
| #define EIGEN_USING_ARRAY_TYPEDEFS \ | ||||
| EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(i) \ | ||||
| EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(f) \ | ||||
| EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(d) \ | ||||
| EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cf) \ | ||||
| EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cd) | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_ARRAY_H | ||||
							
								
								
									
										228
									
								
								latan/Eigen/src/Core/ArrayBase.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										228
									
								
								latan/Eigen/src/Core/ArrayBase.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,228 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_ARRAYBASE_H | ||||
| #define EIGEN_ARRAYBASE_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| template<typename ExpressionType> class MatrixWrapper; | ||||
|  | ||||
| /** \class ArrayBase | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Base class for all 1D and 2D array, and related expressions | ||||
|   * | ||||
|   * An array is similar to a dense vector or matrix. While matrices are mathematical | ||||
|   * objects with well defined linear algebra operators, an array is just a collection | ||||
|   * of scalar values arranged in a one or two dimensionnal fashion. As the main consequence, | ||||
|   * all operations applied to an array are performed coefficient wise. Furthermore, | ||||
|   * arrays support scalar math functions of the c++ standard library (e.g., std::sin(x)), and convenient | ||||
|   * constructors allowing to easily write generic code working for both scalar values | ||||
|   * and arrays. | ||||
|   * | ||||
|   * This class is the base that is inherited by all array expression types. | ||||
|   * | ||||
|   * \tparam Derived is the derived type, e.g., an array or an expression type. | ||||
|   * | ||||
|   * This class can be extended with the help of the plugin mechanism described on the page | ||||
|   * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_ARRAYBASE_PLUGIN. | ||||
|   * | ||||
|   * \sa class MatrixBase, \ref TopicClassHierarchy | ||||
|   */ | ||||
| template<typename Derived> class ArrayBase | ||||
|   : public DenseBase<Derived> | ||||
| { | ||||
|   public: | ||||
| #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /** The base class for a given storage type. */ | ||||
|     typedef ArrayBase StorageBaseType; | ||||
|  | ||||
|     typedef ArrayBase Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl; | ||||
|  | ||||
|     using internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar, | ||||
|                 typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>::operator*; | ||||
|  | ||||
|     typedef typename internal::traits<Derived>::StorageKind StorageKind; | ||||
|     typedef typename internal::traits<Derived>::Index Index; | ||||
|     typedef typename internal::traits<Derived>::Scalar Scalar; | ||||
|     typedef typename internal::packet_traits<Scalar>::type PacketScalar; | ||||
|     typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|  | ||||
|     typedef DenseBase<Derived> Base; | ||||
|     using Base::RowsAtCompileTime; | ||||
|     using Base::ColsAtCompileTime; | ||||
|     using Base::SizeAtCompileTime; | ||||
|     using Base::MaxRowsAtCompileTime; | ||||
|     using Base::MaxColsAtCompileTime; | ||||
|     using Base::MaxSizeAtCompileTime; | ||||
|     using Base::IsVectorAtCompileTime; | ||||
|     using Base::Flags; | ||||
|     using Base::CoeffReadCost; | ||||
|  | ||||
|     using Base::derived; | ||||
|     using Base::const_cast_derived; | ||||
|     using Base::rows; | ||||
|     using Base::cols; | ||||
|     using Base::size; | ||||
|     using Base::coeff; | ||||
|     using Base::coeffRef; | ||||
|     using Base::lazyAssign; | ||||
|     using Base::operator=; | ||||
|     using Base::operator+=; | ||||
|     using Base::operator-=; | ||||
|     using Base::operator*=; | ||||
|     using Base::operator/=; | ||||
|  | ||||
|     typedef typename Base::CoeffReturnType CoeffReturnType; | ||||
|  | ||||
| #endif // not EIGEN_PARSED_BY_DOXYGEN | ||||
|  | ||||
| #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /** \internal the plain matrix type corresponding to this expression. Note that is not necessarily | ||||
|       * exactly the return type of eval(): in the case of plain matrices, the return type of eval() is a const | ||||
|       * reference to a matrix, not a matrix! It is however guaranteed that the return type of eval() is either | ||||
|       * PlainObject or const PlainObject&. | ||||
|       */ | ||||
|     typedef Array<typename internal::traits<Derived>::Scalar, | ||||
|                 internal::traits<Derived>::RowsAtCompileTime, | ||||
|                 internal::traits<Derived>::ColsAtCompileTime, | ||||
|                 AutoAlign | (internal::traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor), | ||||
|                 internal::traits<Derived>::MaxRowsAtCompileTime, | ||||
|                 internal::traits<Derived>::MaxColsAtCompileTime | ||||
|           > PlainObject; | ||||
|  | ||||
|  | ||||
|     /** \internal Represents a matrix with all coefficients equal to one another*/ | ||||
|     typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Derived> ConstantReturnType; | ||||
| #endif // not EIGEN_PARSED_BY_DOXYGEN | ||||
|  | ||||
| #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::ArrayBase | ||||
| #   include "../plugins/CommonCwiseUnaryOps.h" | ||||
| #   include "../plugins/MatrixCwiseUnaryOps.h" | ||||
| #   include "../plugins/ArrayCwiseUnaryOps.h" | ||||
| #   include "../plugins/CommonCwiseBinaryOps.h" | ||||
| #   include "../plugins/MatrixCwiseBinaryOps.h" | ||||
| #   include "../plugins/ArrayCwiseBinaryOps.h" | ||||
| #   ifdef EIGEN_ARRAYBASE_PLUGIN | ||||
| #     include EIGEN_ARRAYBASE_PLUGIN | ||||
| #   endif | ||||
| #undef EIGEN_CURRENT_STORAGE_BASE_CLASS | ||||
|  | ||||
|     /** Special case of the template operator=, in order to prevent the compiler | ||||
|       * from generating a default operator= (issue hit with g++ 4.1) | ||||
|       */ | ||||
|     Derived& operator=(const ArrayBase& other) | ||||
|     { | ||||
|       return internal::assign_selector<Derived,Derived>::run(derived(), other.derived()); | ||||
|     } | ||||
|  | ||||
|     Derived& operator+=(const Scalar& scalar) | ||||
|     { return *this = derived() + scalar; } | ||||
|     Derived& operator-=(const Scalar& scalar) | ||||
|     { return *this = derived() - scalar; } | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     Derived& operator+=(const ArrayBase<OtherDerived>& other); | ||||
|     template<typename OtherDerived> | ||||
|     Derived& operator-=(const ArrayBase<OtherDerived>& other); | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     Derived& operator*=(const ArrayBase<OtherDerived>& other); | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     Derived& operator/=(const ArrayBase<OtherDerived>& other); | ||||
|  | ||||
|   public: | ||||
|     ArrayBase<Derived>& array() { return *this; } | ||||
|     const ArrayBase<Derived>& array() const { return *this; } | ||||
|  | ||||
|     /** \returns an \link MatrixBase Matrix \endlink expression of this array | ||||
|       * \sa MatrixBase::array() */ | ||||
|     MatrixWrapper<Derived> matrix() { return derived(); } | ||||
|     const MatrixWrapper<const Derived> matrix() const { return derived(); } | ||||
|  | ||||
| //     template<typename Dest> | ||||
| //     inline void evalTo(Dest& dst) const { dst = matrix(); } | ||||
|  | ||||
|   protected: | ||||
|     ArrayBase() : Base() {} | ||||
|  | ||||
|   private: | ||||
|     explicit ArrayBase(Index); | ||||
|     ArrayBase(Index,Index); | ||||
|     template<typename OtherDerived> explicit ArrayBase(const ArrayBase<OtherDerived>&); | ||||
|   protected: | ||||
|     // mixing arrays and matrices is not legal | ||||
|     template<typename OtherDerived> Derived& operator+=(const MatrixBase<OtherDerived>& ) | ||||
|     {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} | ||||
|     // mixing arrays and matrices is not legal | ||||
|     template<typename OtherDerived> Derived& operator-=(const MatrixBase<OtherDerived>& ) | ||||
|     {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} | ||||
| }; | ||||
|  | ||||
| /** replaces \c *this by \c *this - \a other. | ||||
|   * | ||||
|   * \returns a reference to \c *this | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| EIGEN_STRONG_INLINE Derived & | ||||
| ArrayBase<Derived>::operator-=(const ArrayBase<OtherDerived> &other) | ||||
| { | ||||
|   SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, Derived, OtherDerived> tmp(derived()); | ||||
|   tmp = other.derived(); | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| /** replaces \c *this by \c *this + \a other. | ||||
|   * | ||||
|   * \returns a reference to \c *this | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| EIGEN_STRONG_INLINE Derived & | ||||
| ArrayBase<Derived>::operator+=(const ArrayBase<OtherDerived>& other) | ||||
| { | ||||
|   SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, Derived, OtherDerived> tmp(derived()); | ||||
|   tmp = other.derived(); | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| /** replaces \c *this by \c *this * \a other coefficient wise. | ||||
|   * | ||||
|   * \returns a reference to \c *this | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| EIGEN_STRONG_INLINE Derived & | ||||
| ArrayBase<Derived>::operator*=(const ArrayBase<OtherDerived>& other) | ||||
| { | ||||
|   SelfCwiseBinaryOp<internal::scalar_product_op<Scalar>, Derived, OtherDerived> tmp(derived()); | ||||
|   tmp = other.derived(); | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| /** replaces \c *this by \c *this / \a other coefficient wise. | ||||
|   * | ||||
|   * \returns a reference to \c *this | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| EIGEN_STRONG_INLINE Derived & | ||||
| ArrayBase<Derived>::operator/=(const ArrayBase<OtherDerived>& other) | ||||
| { | ||||
|   SelfCwiseBinaryOp<internal::scalar_quotient_op<Scalar>, Derived, OtherDerived> tmp(derived()); | ||||
|   tmp = other.derived(); | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_ARRAYBASE_H | ||||
							
								
								
									
										254
									
								
								latan/Eigen/src/Core/ArrayWrapper.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										254
									
								
								latan/Eigen/src/Core/ArrayWrapper.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,254 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_ARRAYWRAPPER_H | ||||
| #define EIGEN_ARRAYWRAPPER_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class ArrayWrapper | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Expression of a mathematical vector or matrix as an array object | ||||
|   * | ||||
|   * This class is the return type of MatrixBase::array(), and most of the time | ||||
|   * this is the only way it is use. | ||||
|   * | ||||
|   * \sa MatrixBase::array(), class MatrixWrapper | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename ExpressionType> | ||||
| struct traits<ArrayWrapper<ExpressionType> > | ||||
|   : public traits<typename remove_all<typename ExpressionType::Nested>::type > | ||||
| { | ||||
|   typedef ArrayXpr XprKind; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename ExpressionType> | ||||
| class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> > | ||||
| { | ||||
|   public: | ||||
|     typedef ArrayBase<ArrayWrapper> Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper) | ||||
|     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ArrayWrapper) | ||||
|  | ||||
|     typedef typename internal::conditional< | ||||
|                        internal::is_lvalue<ExpressionType>::value, | ||||
|                        Scalar, | ||||
|                        const Scalar | ||||
|                      >::type ScalarWithConstIfNotLvalue; | ||||
|  | ||||
|     typedef typename internal::nested<ExpressionType>::type NestedExpressionType; | ||||
|  | ||||
|     inline ArrayWrapper(ExpressionType& matrix) : m_expression(matrix) {} | ||||
|  | ||||
|     inline Index rows() const { return m_expression.rows(); } | ||||
|     inline Index cols() const { return m_expression.cols(); } | ||||
|     inline Index outerStride() const { return m_expression.outerStride(); } | ||||
|     inline Index innerStride() const { return m_expression.innerStride(); } | ||||
|  | ||||
|     inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); } | ||||
|     inline const Scalar* data() const { return m_expression.data(); } | ||||
|  | ||||
|     inline CoeffReturnType coeff(Index row, Index col) const | ||||
|     { | ||||
|       return m_expression.coeff(row, col); | ||||
|     } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index row, Index col) | ||||
|     { | ||||
|       return m_expression.const_cast_derived().coeffRef(row, col); | ||||
|     } | ||||
|  | ||||
|     inline const Scalar& coeffRef(Index row, Index col) const | ||||
|     { | ||||
|       return m_expression.const_cast_derived().coeffRef(row, col); | ||||
|     } | ||||
|  | ||||
|     inline CoeffReturnType coeff(Index index) const | ||||
|     { | ||||
|       return m_expression.coeff(index); | ||||
|     } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index index) | ||||
|     { | ||||
|       return m_expression.const_cast_derived().coeffRef(index); | ||||
|     } | ||||
|  | ||||
|     inline const Scalar& coeffRef(Index index) const | ||||
|     { | ||||
|       return m_expression.const_cast_derived().coeffRef(index); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline const PacketScalar packet(Index row, Index col) const | ||||
|     { | ||||
|       return m_expression.template packet<LoadMode>(row, col); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline void writePacket(Index row, Index col, const PacketScalar& x) | ||||
|     { | ||||
|       m_expression.const_cast_derived().template writePacket<LoadMode>(row, col, x); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline const PacketScalar packet(Index index) const | ||||
|     { | ||||
|       return m_expression.template packet<LoadMode>(index); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline void writePacket(Index index, const PacketScalar& x) | ||||
|     { | ||||
|       m_expression.const_cast_derived().template writePacket<LoadMode>(index, x); | ||||
|     } | ||||
|  | ||||
|     template<typename Dest> | ||||
|     inline void evalTo(Dest& dst) const { dst = m_expression; } | ||||
|  | ||||
|     const typename internal::remove_all<NestedExpressionType>::type&  | ||||
|     nestedExpression() const  | ||||
|     { | ||||
|       return m_expression; | ||||
|     } | ||||
|  | ||||
|     /** Forwards the resizing request to the nested expression | ||||
|       * \sa DenseBase::resize(Index)  */ | ||||
|     void resize(Index newSize) { m_expression.const_cast_derived().resize(newSize); } | ||||
|     /** Forwards the resizing request to the nested expression | ||||
|       * \sa DenseBase::resize(Index,Index)*/ | ||||
|     void resize(Index nbRows, Index nbCols) { m_expression.const_cast_derived().resize(nbRows,nbCols); } | ||||
|  | ||||
|   protected: | ||||
|     NestedExpressionType m_expression; | ||||
| }; | ||||
|  | ||||
| /** \class MatrixWrapper | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Expression of an array as a mathematical vector or matrix | ||||
|   * | ||||
|   * This class is the return type of ArrayBase::matrix(), and most of the time | ||||
|   * this is the only way it is use. | ||||
|   * | ||||
|   * \sa MatrixBase::matrix(), class ArrayWrapper | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename ExpressionType> | ||||
| struct traits<MatrixWrapper<ExpressionType> > | ||||
|  : public traits<typename remove_all<typename ExpressionType::Nested>::type > | ||||
| { | ||||
|   typedef MatrixXpr XprKind; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename ExpressionType> | ||||
| class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> > | ||||
| { | ||||
|   public: | ||||
|     typedef MatrixBase<MatrixWrapper<ExpressionType> > Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(MatrixWrapper) | ||||
|     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper) | ||||
|  | ||||
|     typedef typename internal::conditional< | ||||
|                        internal::is_lvalue<ExpressionType>::value, | ||||
|                        Scalar, | ||||
|                        const Scalar | ||||
|                      >::type ScalarWithConstIfNotLvalue; | ||||
|  | ||||
|     typedef typename internal::nested<ExpressionType>::type NestedExpressionType; | ||||
|  | ||||
|     inline MatrixWrapper(ExpressionType& matrix) : m_expression(matrix) {} | ||||
|  | ||||
|     inline Index rows() const { return m_expression.rows(); } | ||||
|     inline Index cols() const { return m_expression.cols(); } | ||||
|     inline Index outerStride() const { return m_expression.outerStride(); } | ||||
|     inline Index innerStride() const { return m_expression.innerStride(); } | ||||
|  | ||||
|     inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); } | ||||
|     inline const Scalar* data() const { return m_expression.data(); } | ||||
|  | ||||
|     inline CoeffReturnType coeff(Index row, Index col) const | ||||
|     { | ||||
|       return m_expression.coeff(row, col); | ||||
|     } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index row, Index col) | ||||
|     { | ||||
|       return m_expression.const_cast_derived().coeffRef(row, col); | ||||
|     } | ||||
|  | ||||
|     inline const Scalar& coeffRef(Index row, Index col) const | ||||
|     { | ||||
|       return m_expression.derived().coeffRef(row, col); | ||||
|     } | ||||
|  | ||||
|     inline CoeffReturnType coeff(Index index) const | ||||
|     { | ||||
|       return m_expression.coeff(index); | ||||
|     } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index index) | ||||
|     { | ||||
|       return m_expression.const_cast_derived().coeffRef(index); | ||||
|     } | ||||
|  | ||||
|     inline const Scalar& coeffRef(Index index) const | ||||
|     { | ||||
|       return m_expression.const_cast_derived().coeffRef(index); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline const PacketScalar packet(Index row, Index col) const | ||||
|     { | ||||
|       return m_expression.template packet<LoadMode>(row, col); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline void writePacket(Index row, Index col, const PacketScalar& x) | ||||
|     { | ||||
|       m_expression.const_cast_derived().template writePacket<LoadMode>(row, col, x); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline const PacketScalar packet(Index index) const | ||||
|     { | ||||
|       return m_expression.template packet<LoadMode>(index); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline void writePacket(Index index, const PacketScalar& x) | ||||
|     { | ||||
|       m_expression.const_cast_derived().template writePacket<LoadMode>(index, x); | ||||
|     } | ||||
|  | ||||
|     const typename internal::remove_all<NestedExpressionType>::type&  | ||||
|     nestedExpression() const  | ||||
|     { | ||||
|       return m_expression; | ||||
|     } | ||||
|  | ||||
|     /** Forwards the resizing request to the nested expression | ||||
|       * \sa DenseBase::resize(Index)  */ | ||||
|     void resize(Index newSize) { m_expression.const_cast_derived().resize(newSize); } | ||||
|     /** Forwards the resizing request to the nested expression | ||||
|       * \sa DenseBase::resize(Index,Index)*/ | ||||
|     void resize(Index nbRows, Index nbCols) { m_expression.const_cast_derived().resize(nbRows,nbCols); } | ||||
|  | ||||
|   protected: | ||||
|     NestedExpressionType m_expression; | ||||
| }; | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_ARRAYWRAPPER_H | ||||
							
								
								
									
										583
									
								
								latan/Eigen/src/Core/Assign.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										583
									
								
								latan/Eigen/src/Core/Assign.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,583 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2007 Michael Olbrich <michael.olbrich@gmx.net> | ||||
| // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_ASSIGN_H | ||||
| #define EIGEN_ASSIGN_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| /*************************************************************************** | ||||
| * Part 1 : the logic deciding a strategy for traversal and unrolling       * | ||||
| ***************************************************************************/ | ||||
|  | ||||
| template <typename Derived, typename OtherDerived> | ||||
| struct assign_traits | ||||
| { | ||||
| public: | ||||
|   enum { | ||||
|     DstIsAligned = Derived::Flags & AlignedBit, | ||||
|     DstHasDirectAccess = Derived::Flags & DirectAccessBit, | ||||
|     SrcIsAligned = OtherDerived::Flags & AlignedBit, | ||||
|     JointAlignment = bool(DstIsAligned) && bool(SrcIsAligned) ? Aligned : Unaligned | ||||
|   }; | ||||
|  | ||||
| private: | ||||
|   enum { | ||||
|     InnerSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::SizeAtCompileTime) | ||||
|               : int(Derived::Flags)&RowMajorBit ? int(Derived::ColsAtCompileTime) | ||||
|               : int(Derived::RowsAtCompileTime), | ||||
|     InnerMaxSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::MaxSizeAtCompileTime) | ||||
|               : int(Derived::Flags)&RowMajorBit ? int(Derived::MaxColsAtCompileTime) | ||||
|               : int(Derived::MaxRowsAtCompileTime), | ||||
|     MaxSizeAtCompileTime = Derived::SizeAtCompileTime, | ||||
|     PacketSize = packet_traits<typename Derived::Scalar>::size | ||||
|   }; | ||||
|  | ||||
|   enum { | ||||
|     StorageOrdersAgree = (int(Derived::IsRowMajor) == int(OtherDerived::IsRowMajor)), | ||||
|     MightVectorize = StorageOrdersAgree | ||||
|                   && (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit), | ||||
|     MayInnerVectorize  = MightVectorize && int(InnerSize)!=Dynamic && int(InnerSize)%int(PacketSize)==0 | ||||
|                        && int(DstIsAligned) && int(SrcIsAligned), | ||||
|     MayLinearize = StorageOrdersAgree && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit), | ||||
|     MayLinearVectorize = MightVectorize && MayLinearize && DstHasDirectAccess | ||||
|                        && (DstIsAligned || MaxSizeAtCompileTime == Dynamic), | ||||
|       /* If the destination isn't aligned, we have to do runtime checks and we don't unroll, | ||||
|          so it's only good for large enough sizes. */ | ||||
|     MaySliceVectorize  = MightVectorize && DstHasDirectAccess | ||||
|                        && (int(InnerMaxSize)==Dynamic || int(InnerMaxSize)>=3*PacketSize) | ||||
|       /* slice vectorization can be slow, so we only want it if the slices are big, which is | ||||
|          indicated by InnerMaxSize rather than InnerSize, think of the case of a dynamic block | ||||
|          in a fixed-size matrix */ | ||||
|   }; | ||||
|  | ||||
| public: | ||||
|   enum { | ||||
|     Traversal = int(MayInnerVectorize)  ? int(InnerVectorizedTraversal) | ||||
|               : int(MayLinearVectorize) ? int(LinearVectorizedTraversal) | ||||
|               : int(MaySliceVectorize)  ? int(SliceVectorizedTraversal) | ||||
|               : int(MayLinearize)       ? int(LinearTraversal) | ||||
|                                         : int(DefaultTraversal), | ||||
|     Vectorized = int(Traversal) == InnerVectorizedTraversal | ||||
|               || int(Traversal) == LinearVectorizedTraversal | ||||
|               || int(Traversal) == SliceVectorizedTraversal | ||||
|   }; | ||||
|  | ||||
| private: | ||||
|   enum { | ||||
|     UnrollingLimit      = EIGEN_UNROLLING_LIMIT * (Vectorized ? int(PacketSize) : 1), | ||||
|     MayUnrollCompletely = int(Derived::SizeAtCompileTime) != Dynamic | ||||
|                        && int(OtherDerived::CoeffReadCost) != Dynamic | ||||
|                        && int(Derived::SizeAtCompileTime) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit), | ||||
|     MayUnrollInner      = int(InnerSize) != Dynamic | ||||
|                        && int(OtherDerived::CoeffReadCost) != Dynamic | ||||
|                        && int(InnerSize) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit) | ||||
|   }; | ||||
|  | ||||
| public: | ||||
|   enum { | ||||
|     Unrolling = (int(Traversal) == int(InnerVectorizedTraversal) || int(Traversal) == int(DefaultTraversal)) | ||||
|                 ? ( | ||||
|                     int(MayUnrollCompletely) ? int(CompleteUnrolling) | ||||
|                   : int(MayUnrollInner)      ? int(InnerUnrolling) | ||||
|                                              : int(NoUnrolling) | ||||
|                   ) | ||||
|               : int(Traversal) == int(LinearVectorizedTraversal) | ||||
|                 ? ( bool(MayUnrollCompletely) && bool(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) ) | ||||
|               : int(Traversal) == int(LinearTraversal) | ||||
|                 ? ( bool(MayUnrollCompletely) ? int(CompleteUnrolling) : int(NoUnrolling) ) | ||||
|               : int(NoUnrolling) | ||||
|   }; | ||||
|  | ||||
| #ifdef EIGEN_DEBUG_ASSIGN | ||||
|   static void debug() | ||||
|   { | ||||
|     EIGEN_DEBUG_VAR(DstIsAligned) | ||||
|     EIGEN_DEBUG_VAR(SrcIsAligned) | ||||
|     EIGEN_DEBUG_VAR(JointAlignment) | ||||
|     EIGEN_DEBUG_VAR(InnerSize) | ||||
|     EIGEN_DEBUG_VAR(InnerMaxSize) | ||||
|     EIGEN_DEBUG_VAR(PacketSize) | ||||
|     EIGEN_DEBUG_VAR(StorageOrdersAgree) | ||||
|     EIGEN_DEBUG_VAR(MightVectorize) | ||||
|     EIGEN_DEBUG_VAR(MayLinearize) | ||||
|     EIGEN_DEBUG_VAR(MayInnerVectorize) | ||||
|     EIGEN_DEBUG_VAR(MayLinearVectorize) | ||||
|     EIGEN_DEBUG_VAR(MaySliceVectorize) | ||||
|     EIGEN_DEBUG_VAR(Traversal) | ||||
|     EIGEN_DEBUG_VAR(UnrollingLimit) | ||||
|     EIGEN_DEBUG_VAR(MayUnrollCompletely) | ||||
|     EIGEN_DEBUG_VAR(MayUnrollInner) | ||||
|     EIGEN_DEBUG_VAR(Unrolling) | ||||
|   } | ||||
| #endif | ||||
| }; | ||||
|  | ||||
| /*************************************************************************** | ||||
| * Part 2 : meta-unrollers | ||||
| ***************************************************************************/ | ||||
|  | ||||
| /************************ | ||||
| *** Default traversal *** | ||||
| ************************/ | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Index, int Stop> | ||||
| struct assign_DefaultTraversal_CompleteUnrolling | ||||
| { | ||||
|   enum { | ||||
|     outer = Index / Derived1::InnerSizeAtCompileTime, | ||||
|     inner = Index % Derived1::InnerSizeAtCompileTime | ||||
|   }; | ||||
|  | ||||
|   static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     dst.copyCoeffByOuterInner(outer, inner, src); | ||||
|     assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Stop> | ||||
| struct assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop> | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {} | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Index, int Stop> | ||||
| struct assign_DefaultTraversal_InnerUnrolling | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, int outer) | ||||
|   { | ||||
|     dst.copyCoeffByOuterInner(outer, Index, src); | ||||
|     assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src, outer); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Stop> | ||||
| struct assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Stop, Stop> | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, int) {} | ||||
| }; | ||||
|  | ||||
| /*********************** | ||||
| *** Linear traversal *** | ||||
| ***********************/ | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Index, int Stop> | ||||
| struct assign_LinearTraversal_CompleteUnrolling | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     dst.copyCoeff(Index, src); | ||||
|     assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Stop> | ||||
| struct assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop> | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {} | ||||
| }; | ||||
|  | ||||
| /************************** | ||||
| *** Inner vectorization *** | ||||
| **************************/ | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Index, int Stop> | ||||
| struct assign_innervec_CompleteUnrolling | ||||
| { | ||||
|   enum { | ||||
|     outer = Index / Derived1::InnerSizeAtCompileTime, | ||||
|     inner = Index % Derived1::InnerSizeAtCompileTime, | ||||
|     JointAlignment = assign_traits<Derived1,Derived2>::JointAlignment | ||||
|   }; | ||||
|  | ||||
|   static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     dst.template copyPacketByOuterInner<Derived2, Aligned, JointAlignment>(outer, inner, src); | ||||
|     assign_innervec_CompleteUnrolling<Derived1, Derived2, | ||||
|       Index+packet_traits<typename Derived1::Scalar>::size, Stop>::run(dst, src); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Stop> | ||||
| struct assign_innervec_CompleteUnrolling<Derived1, Derived2, Stop, Stop> | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {} | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Index, int Stop> | ||||
| struct assign_innervec_InnerUnrolling | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, int outer) | ||||
|   { | ||||
|     dst.template copyPacketByOuterInner<Derived2, Aligned, Aligned>(outer, Index, src); | ||||
|     assign_innervec_InnerUnrolling<Derived1, Derived2, | ||||
|       Index+packet_traits<typename Derived1::Scalar>::size, Stop>::run(dst, src, outer); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Stop> | ||||
| struct assign_innervec_InnerUnrolling<Derived1, Derived2, Stop, Stop> | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, int) {} | ||||
| }; | ||||
|  | ||||
| /*************************************************************************** | ||||
| * Part 3 : implementation of all cases | ||||
| ***************************************************************************/ | ||||
|  | ||||
| template<typename Derived1, typename Derived2, | ||||
|          int Traversal = assign_traits<Derived1, Derived2>::Traversal, | ||||
|          int Unrolling = assign_traits<Derived1, Derived2>::Unrolling, | ||||
|          int Version = Specialized> | ||||
| struct assign_impl; | ||||
|  | ||||
| /************************ | ||||
| *** Default traversal *** | ||||
| ************************/ | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Unrolling, int Version> | ||||
| struct assign_impl<Derived1, Derived2, InvalidTraversal, Unrolling, Version> | ||||
| { | ||||
|   static inline void run(Derived1 &, const Derived2 &) { } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Version> | ||||
| struct assign_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling, Version> | ||||
| { | ||||
|   typedef typename Derived1::Index Index; | ||||
|   static inline void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     const Index innerSize = dst.innerSize(); | ||||
|     const Index outerSize = dst.outerSize(); | ||||
|     for(Index outer = 0; outer < outerSize; ++outer) | ||||
|       for(Index inner = 0; inner < innerSize; ++inner) | ||||
|         dst.copyCoeffByOuterInner(outer, inner, src); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Version> | ||||
| struct assign_impl<Derived1, Derived2, DefaultTraversal, CompleteUnrolling, Version> | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime> | ||||
|       ::run(dst, src); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Version> | ||||
| struct assign_impl<Derived1, Derived2, DefaultTraversal, InnerUnrolling, Version> | ||||
| { | ||||
|   typedef typename Derived1::Index Index; | ||||
|   static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     const Index outerSize = dst.outerSize(); | ||||
|     for(Index outer = 0; outer < outerSize; ++outer) | ||||
|       assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, 0, Derived1::InnerSizeAtCompileTime> | ||||
|         ::run(dst, src, outer); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /*********************** | ||||
| *** Linear traversal *** | ||||
| ***********************/ | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Version> | ||||
| struct assign_impl<Derived1, Derived2, LinearTraversal, NoUnrolling, Version> | ||||
| { | ||||
|   typedef typename Derived1::Index Index; | ||||
|   static inline void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     const Index size = dst.size(); | ||||
|     for(Index i = 0; i < size; ++i) | ||||
|       dst.copyCoeff(i, src); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Version> | ||||
| struct assign_impl<Derived1, Derived2, LinearTraversal, CompleteUnrolling, Version> | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime> | ||||
|       ::run(dst, src); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /************************** | ||||
| *** Inner vectorization *** | ||||
| **************************/ | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Version> | ||||
| struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, NoUnrolling, Version> | ||||
| { | ||||
|   typedef typename Derived1::Index Index; | ||||
|   static inline void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     const Index innerSize = dst.innerSize(); | ||||
|     const Index outerSize = dst.outerSize(); | ||||
|     const Index packetSize = packet_traits<typename Derived1::Scalar>::size; | ||||
|     for(Index outer = 0; outer < outerSize; ++outer) | ||||
|       for(Index inner = 0; inner < innerSize; inner+=packetSize) | ||||
|         dst.template copyPacketByOuterInner<Derived2, Aligned, Aligned>(outer, inner, src); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Version> | ||||
| struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, CompleteUnrolling, Version> | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime> | ||||
|       ::run(dst, src); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Version> | ||||
| struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, InnerUnrolling, Version> | ||||
| { | ||||
|   typedef typename Derived1::Index Index; | ||||
|   static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     const Index outerSize = dst.outerSize(); | ||||
|     for(Index outer = 0; outer < outerSize; ++outer) | ||||
|       assign_innervec_InnerUnrolling<Derived1, Derived2, 0, Derived1::InnerSizeAtCompileTime> | ||||
|         ::run(dst, src, outer); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /*************************** | ||||
| *** Linear vectorization *** | ||||
| ***************************/ | ||||
|  | ||||
| template <bool IsAligned = false> | ||||
| struct unaligned_assign_impl | ||||
| { | ||||
|   template <typename Derived, typename OtherDerived> | ||||
|   static EIGEN_STRONG_INLINE void run(const Derived&, OtherDerived&, typename Derived::Index, typename Derived::Index) {} | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct unaligned_assign_impl<false> | ||||
| { | ||||
|   // MSVC must not inline this functions. If it does, it fails to optimize the | ||||
|   // packet access path. | ||||
| #ifdef _MSC_VER | ||||
|   template <typename Derived, typename OtherDerived> | ||||
|   static EIGEN_DONT_INLINE void run(const Derived& src, OtherDerived& dst, typename Derived::Index start, typename Derived::Index end) | ||||
| #else | ||||
|   template <typename Derived, typename OtherDerived> | ||||
|   static EIGEN_STRONG_INLINE void run(const Derived& src, OtherDerived& dst, typename Derived::Index start, typename Derived::Index end) | ||||
| #endif | ||||
|   { | ||||
|     for (typename Derived::Index index = start; index < end; ++index) | ||||
|       dst.copyCoeff(index, src); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Version> | ||||
| struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling, Version> | ||||
| { | ||||
|   typedef typename Derived1::Index Index; | ||||
|   static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     const Index size = dst.size(); | ||||
|     typedef packet_traits<typename Derived1::Scalar> PacketTraits; | ||||
|     enum { | ||||
|       packetSize = PacketTraits::size, | ||||
|       dstAlignment = PacketTraits::AlignedOnScalar ? Aligned : int(assign_traits<Derived1,Derived2>::DstIsAligned) , | ||||
|       srcAlignment = assign_traits<Derived1,Derived2>::JointAlignment | ||||
|     }; | ||||
|     const Index alignedStart = assign_traits<Derived1,Derived2>::DstIsAligned ? 0 | ||||
|                              : internal::first_aligned(&dst.coeffRef(0), size); | ||||
|     const Index alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize; | ||||
|  | ||||
|     unaligned_assign_impl<assign_traits<Derived1,Derived2>::DstIsAligned!=0>::run(src,dst,0,alignedStart); | ||||
|  | ||||
|     for(Index index = alignedStart; index < alignedEnd; index += packetSize) | ||||
|     { | ||||
|       dst.template copyPacket<Derived2, dstAlignment, srcAlignment>(index, src); | ||||
|     } | ||||
|  | ||||
|     unaligned_assign_impl<>::run(src,dst,alignedEnd,size); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Version> | ||||
| struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, CompleteUnrolling, Version> | ||||
| { | ||||
|   typedef typename Derived1::Index Index; | ||||
|   static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     enum { size = Derived1::SizeAtCompileTime, | ||||
|            packetSize = packet_traits<typename Derived1::Scalar>::size, | ||||
|            alignedSize = (size/packetSize)*packetSize }; | ||||
|  | ||||
|     assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, alignedSize>::run(dst, src); | ||||
|     assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, alignedSize, size>::run(dst, src); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /************************** | ||||
| *** Slice vectorization *** | ||||
| ***************************/ | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int Version> | ||||
| struct assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling, Version> | ||||
| { | ||||
|   typedef typename Derived1::Index Index; | ||||
|   static inline void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     typedef packet_traits<typename Derived1::Scalar> PacketTraits; | ||||
|     enum { | ||||
|       packetSize = PacketTraits::size, | ||||
|       alignable = PacketTraits::AlignedOnScalar, | ||||
|       dstAlignment = alignable ? Aligned : int(assign_traits<Derived1,Derived2>::DstIsAligned) , | ||||
|       srcAlignment = assign_traits<Derived1,Derived2>::JointAlignment | ||||
|     }; | ||||
|     const Index packetAlignedMask = packetSize - 1; | ||||
|     const Index innerSize = dst.innerSize(); | ||||
|     const Index outerSize = dst.outerSize(); | ||||
|     const Index alignedStep = alignable ? (packetSize - dst.outerStride() % packetSize) & packetAlignedMask : 0; | ||||
|     Index alignedStart = ((!alignable) || assign_traits<Derived1,Derived2>::DstIsAligned) ? 0 | ||||
|                        : internal::first_aligned(&dst.coeffRef(0,0), innerSize); | ||||
|  | ||||
|     for(Index outer = 0; outer < outerSize; ++outer) | ||||
|     { | ||||
|       const Index alignedEnd = alignedStart + ((innerSize-alignedStart) & ~packetAlignedMask); | ||||
|       // do the non-vectorizable part of the assignment | ||||
|       for(Index inner = 0; inner<alignedStart ; ++inner) | ||||
|         dst.copyCoeffByOuterInner(outer, inner, src); | ||||
|  | ||||
|       // do the vectorizable part of the assignment | ||||
|       for(Index inner = alignedStart; inner<alignedEnd; inner+=packetSize) | ||||
|         dst.template copyPacketByOuterInner<Derived2, dstAlignment, Unaligned>(outer, inner, src); | ||||
|  | ||||
|       // do the non-vectorizable part of the assignment | ||||
|       for(Index inner = alignedEnd; inner<innerSize ; ++inner) | ||||
|         dst.copyCoeffByOuterInner(outer, inner, src); | ||||
|  | ||||
|       alignedStart = std::min<Index>((alignedStart+alignedStep)%packetSize, innerSize); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /*************************************************************************** | ||||
| * Part 4 : implementation of DenseBase methods | ||||
| ***************************************************************************/ | ||||
|  | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| EIGEN_STRONG_INLINE Derived& DenseBase<Derived> | ||||
|   ::lazyAssign(const DenseBase<OtherDerived>& other) | ||||
| { | ||||
|   enum{ | ||||
|     SameType = internal::is_same<typename Derived::Scalar,typename OtherDerived::Scalar>::value | ||||
|   }; | ||||
|  | ||||
|   EIGEN_STATIC_ASSERT_LVALUE(Derived) | ||||
|   EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived) | ||||
|   EIGEN_STATIC_ASSERT(SameType,YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) | ||||
|  | ||||
| #ifdef EIGEN_DEBUG_ASSIGN | ||||
|   internal::assign_traits<Derived, OtherDerived>::debug(); | ||||
| #endif | ||||
|   eigen_assert(rows() == other.rows() && cols() == other.cols()); | ||||
|   internal::assign_impl<Derived, OtherDerived, int(SameType) ? int(internal::assign_traits<Derived, OtherDerived>::Traversal) | ||||
|                                                        : int(InvalidTraversal)>::run(derived(),other.derived()); | ||||
| #ifndef EIGEN_NO_DEBUG | ||||
|   checkTransposeAliasing(other.derived()); | ||||
| #endif | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename Derived, typename OtherDerived, | ||||
|          bool EvalBeforeAssigning = (int(OtherDerived::Flags) & EvalBeforeAssigningBit) != 0, | ||||
|          bool NeedToTranspose = Derived::IsVectorAtCompileTime | ||||
|                 && OtherDerived::IsVectorAtCompileTime | ||||
|                 && ((int(Derived::RowsAtCompileTime) == 1 && int(OtherDerived::ColsAtCompileTime) == 1) | ||||
|                       |  // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&". | ||||
|                          // revert to || as soon as not needed anymore. | ||||
|                     (int(Derived::ColsAtCompileTime) == 1 && int(OtherDerived::RowsAtCompileTime) == 1)) | ||||
|                 && int(Derived::SizeAtCompileTime) != 1> | ||||
| struct assign_selector; | ||||
|  | ||||
| template<typename Derived, typename OtherDerived> | ||||
| struct assign_selector<Derived,OtherDerived,false,false> { | ||||
|   static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); } | ||||
| }; | ||||
| template<typename Derived, typename OtherDerived> | ||||
| struct assign_selector<Derived,OtherDerived,true,false> { | ||||
|   static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); } | ||||
| }; | ||||
| template<typename Derived, typename OtherDerived> | ||||
| struct assign_selector<Derived,OtherDerived,false,true> { | ||||
|   static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); } | ||||
| }; | ||||
| template<typename Derived, typename OtherDerived> | ||||
| struct assign_selector<Derived,OtherDerived,true,true> { | ||||
|   static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase<OtherDerived>& other) | ||||
| { | ||||
|   return internal::assign_selector<Derived,OtherDerived>::run(derived(), other.derived()); | ||||
| } | ||||
|  | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase& other) | ||||
| { | ||||
|   return internal::assign_selector<Derived,Derived>::run(derived(), other.derived()); | ||||
| } | ||||
|  | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const MatrixBase& other) | ||||
| { | ||||
|   return internal::assign_selector<Derived,Derived>::run(derived(), other.derived()); | ||||
| } | ||||
|  | ||||
| template<typename Derived> | ||||
| template <typename OtherDerived> | ||||
| EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const DenseBase<OtherDerived>& other) | ||||
| { | ||||
|   return internal::assign_selector<Derived,OtherDerived>::run(derived(), other.derived()); | ||||
| } | ||||
|  | ||||
| template<typename Derived> | ||||
| template <typename OtherDerived> | ||||
| EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const EigenBase<OtherDerived>& other) | ||||
| { | ||||
|   other.derived().evalTo(derived()); | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other) | ||||
| { | ||||
|   other.evalTo(derived()); | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_ASSIGN_H | ||||
							
								
								
									
										224
									
								
								latan/Eigen/src/Core/Assign_MKL.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								latan/Eigen/src/Core/Assign_MKL.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,224 @@ | ||||
| /* | ||||
|  Copyright (c) 2011, Intel Corporation. All rights reserved. | ||||
|  | ||||
|  Redistribution and use in source and binary forms, with or without modification, | ||||
|  are permitted provided that the following conditions are met: | ||||
|  | ||||
|  * Redistributions of source code must retain the above copyright notice, this | ||||
|    list of conditions and the following disclaimer. | ||||
|  * Redistributions in binary form must reproduce the above copyright notice, | ||||
|    this list of conditions and the following disclaimer in the documentation | ||||
|    and/or other materials provided with the distribution. | ||||
|  * Neither the name of Intel Corporation nor the names of its contributors may | ||||
|    be used to endorse or promote products derived from this software without | ||||
|    specific prior written permission. | ||||
|  | ||||
|  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||||
|  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
|  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
|  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||||
|  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
|  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
|  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||||
|  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
|  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
|  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  | ||||
|  ******************************************************************************** | ||||
|  *   Content : Eigen bindings to Intel(R) MKL | ||||
|  *   MKL VML support for coefficient-wise unary Eigen expressions like a=b.sin() | ||||
|  ******************************************************************************** | ||||
| */ | ||||
|  | ||||
| #ifndef EIGEN_ASSIGN_VML_H | ||||
| #define EIGEN_ASSIGN_VML_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename Op> struct vml_call | ||||
| { enum { IsSupported = 0 }; }; | ||||
|  | ||||
| template<typename Dst, typename Src, typename UnaryOp> | ||||
| class vml_assign_traits | ||||
| { | ||||
|   private: | ||||
|     enum { | ||||
|       DstHasDirectAccess = Dst::Flags & DirectAccessBit, | ||||
|       SrcHasDirectAccess = Src::Flags & DirectAccessBit, | ||||
|  | ||||
|       StorageOrdersAgree = (int(Dst::IsRowMajor) == int(Src::IsRowMajor)), | ||||
|       InnerSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::SizeAtCompileTime) | ||||
|                 : int(Dst::Flags)&RowMajorBit ? int(Dst::ColsAtCompileTime) | ||||
|                 : int(Dst::RowsAtCompileTime), | ||||
|       InnerMaxSize  = int(Dst::IsVectorAtCompileTime) ? int(Dst::MaxSizeAtCompileTime) | ||||
|                     : int(Dst::Flags)&RowMajorBit ? int(Dst::MaxColsAtCompileTime) | ||||
|                     : int(Dst::MaxRowsAtCompileTime), | ||||
|       MaxSizeAtCompileTime = Dst::SizeAtCompileTime, | ||||
|  | ||||
|       MightEnableVml =  vml_call<UnaryOp>::IsSupported && StorageOrdersAgree && DstHasDirectAccess && SrcHasDirectAccess | ||||
|                      && Src::InnerStrideAtCompileTime==1 && Dst::InnerStrideAtCompileTime==1, | ||||
|       MightLinearize = MightEnableVml && (int(Dst::Flags) & int(Src::Flags) & LinearAccessBit), | ||||
|       VmlSize = MightLinearize ? MaxSizeAtCompileTime : InnerMaxSize, | ||||
|       LargeEnough = VmlSize==Dynamic || VmlSize>=EIGEN_MKL_VML_THRESHOLD, | ||||
|       MayEnableVml = MightEnableVml && LargeEnough, | ||||
|       MayLinearize = MayEnableVml && MightLinearize | ||||
|     }; | ||||
|   public: | ||||
|     enum { | ||||
|       Traversal = MayLinearize ? LinearVectorizedTraversal | ||||
|                 : MayEnableVml ? InnerVectorizedTraversal | ||||
|                 : DefaultTraversal | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, typename UnaryOp, int Traversal, int Unrolling, | ||||
|          int VmlTraversal = vml_assign_traits<Derived1, Derived2, UnaryOp>::Traversal > | ||||
| struct vml_assign_impl | ||||
|   : assign_impl<Derived1, Eigen::CwiseUnaryOp<UnaryOp, Derived2>,Traversal,Unrolling,BuiltIn> | ||||
| { | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, typename UnaryOp, int Traversal, int Unrolling> | ||||
| struct vml_assign_impl<Derived1, Derived2, UnaryOp, Traversal, Unrolling, InnerVectorizedTraversal> | ||||
| { | ||||
|   typedef typename Derived1::Scalar Scalar; | ||||
|   typedef typename Derived1::Index Index; | ||||
|   static inline void run(Derived1& dst, const CwiseUnaryOp<UnaryOp, Derived2>& src) | ||||
|   { | ||||
|     // in case we want to (or have to) skip VML at runtime we can call: | ||||
|     // assign_impl<Derived1,Eigen::CwiseUnaryOp<UnaryOp, Derived2>,Traversal,Unrolling,BuiltIn>::run(dst,src); | ||||
|     const Index innerSize = dst.innerSize(); | ||||
|     const Index outerSize = dst.outerSize(); | ||||
|     for(Index outer = 0; outer < outerSize; ++outer) { | ||||
|       const Scalar *src_ptr = src.IsRowMajor ?  &(src.nestedExpression().coeffRef(outer,0)) : | ||||
|                                                 &(src.nestedExpression().coeffRef(0, outer)); | ||||
|       Scalar *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer,0)) : &(dst.coeffRef(0, outer)); | ||||
|       vml_call<UnaryOp>::run(src.functor(), innerSize, src_ptr, dst_ptr ); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, typename UnaryOp, int Traversal, int Unrolling> | ||||
| struct vml_assign_impl<Derived1, Derived2, UnaryOp, Traversal, Unrolling, LinearVectorizedTraversal> | ||||
| { | ||||
|   static inline void run(Derived1& dst, const CwiseUnaryOp<UnaryOp, Derived2>& src) | ||||
|   { | ||||
|     // in case we want to (or have to) skip VML at runtime we can call: | ||||
|     // assign_impl<Derived1,Eigen::CwiseUnaryOp<UnaryOp, Derived2>,Traversal,Unrolling,BuiltIn>::run(dst,src); | ||||
|     vml_call<UnaryOp>::run(src.functor(), dst.size(), src.nestedExpression().data(), dst.data() ); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // Macroses | ||||
|  | ||||
| #define EIGEN_MKL_VML_SPECIALIZE_ASSIGN(TRAVERSAL,UNROLLING) \ | ||||
|   template<typename Derived1, typename Derived2, typename UnaryOp> \ | ||||
|   struct assign_impl<Derived1, Eigen::CwiseUnaryOp<UnaryOp, Derived2>, TRAVERSAL, UNROLLING, Specialized>  {  \ | ||||
|     static inline void run(Derived1 &dst, const Eigen::CwiseUnaryOp<UnaryOp, Derived2> &src) { \ | ||||
|       vml_assign_impl<Derived1,Derived2,UnaryOp,TRAVERSAL,UNROLLING>::run(dst, src); \ | ||||
|     } \ | ||||
|   }; | ||||
|  | ||||
| EIGEN_MKL_VML_SPECIALIZE_ASSIGN(DefaultTraversal,NoUnrolling) | ||||
| EIGEN_MKL_VML_SPECIALIZE_ASSIGN(DefaultTraversal,CompleteUnrolling) | ||||
| EIGEN_MKL_VML_SPECIALIZE_ASSIGN(DefaultTraversal,InnerUnrolling) | ||||
| EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearTraversal,NoUnrolling) | ||||
| EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearTraversal,CompleteUnrolling) | ||||
| EIGEN_MKL_VML_SPECIALIZE_ASSIGN(InnerVectorizedTraversal,NoUnrolling) | ||||
| EIGEN_MKL_VML_SPECIALIZE_ASSIGN(InnerVectorizedTraversal,CompleteUnrolling) | ||||
| EIGEN_MKL_VML_SPECIALIZE_ASSIGN(InnerVectorizedTraversal,InnerUnrolling) | ||||
| EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearVectorizedTraversal,CompleteUnrolling) | ||||
| EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearVectorizedTraversal,NoUnrolling) | ||||
| EIGEN_MKL_VML_SPECIALIZE_ASSIGN(SliceVectorizedTraversal,NoUnrolling) | ||||
|  | ||||
|  | ||||
| #if !defined (EIGEN_FAST_MATH) || (EIGEN_FAST_MATH != 1) | ||||
| #define  EIGEN_MKL_VML_MODE VML_HA | ||||
| #else | ||||
| #define  EIGEN_MKL_VML_MODE VML_LA | ||||
| #endif | ||||
|  | ||||
| #define EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE)     \ | ||||
|   template<> struct vml_call< scalar_##EIGENOP##_op<EIGENTYPE> > {               \ | ||||
|     enum { IsSupported = 1 };                                                    \ | ||||
|     static inline void run( const scalar_##EIGENOP##_op<EIGENTYPE>& /*func*/,        \ | ||||
|                             int size, const EIGENTYPE* src, EIGENTYPE* dst) {    \ | ||||
|       VMLOP(size, (const VMLTYPE*)src, (VMLTYPE*)dst);                           \ | ||||
|     }                                                                            \ | ||||
|   }; | ||||
|  | ||||
| #define EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE)  \ | ||||
|   template<> struct vml_call< scalar_##EIGENOP##_op<EIGENTYPE> > {               \ | ||||
|     enum { IsSupported = 1 };                                                    \ | ||||
|     static inline void run( const scalar_##EIGENOP##_op<EIGENTYPE>& /*func*/,        \ | ||||
|                             int size, const EIGENTYPE* src, EIGENTYPE* dst) {    \ | ||||
|       MKL_INT64 vmlMode = EIGEN_MKL_VML_MODE;                                    \ | ||||
|       VMLOP(size, (const VMLTYPE*)src, (VMLTYPE*)dst, vmlMode);                  \ | ||||
|     }                                                                            \ | ||||
|   }; | ||||
|  | ||||
| #define EIGEN_MKL_VML_DECLARE_POW_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE)       \ | ||||
|   template<> struct vml_call< scalar_##EIGENOP##_op<EIGENTYPE> > {               \ | ||||
|     enum { IsSupported = 1 };                                                    \ | ||||
|     static inline void run( const scalar_##EIGENOP##_op<EIGENTYPE>& func,        \ | ||||
|                           int size, const EIGENTYPE* src, EIGENTYPE* dst) {      \ | ||||
|       EIGENTYPE exponent = func.m_exponent;                                      \ | ||||
|       MKL_INT64 vmlMode = EIGEN_MKL_VML_MODE;                                    \ | ||||
|       VMLOP(&size, (const VMLTYPE*)src, (const VMLTYPE*)&exponent,               \ | ||||
|                         (VMLTYPE*)dst, &vmlMode);                                \ | ||||
|     }                                                                            \ | ||||
|   }; | ||||
|  | ||||
| #define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP)                   \ | ||||
|   EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vs##VMLOP, float, float)             \ | ||||
|   EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vd##VMLOP, double, double) | ||||
|  | ||||
| #define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX(EIGENOP, VMLOP)                \ | ||||
|   EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vc##VMLOP, scomplex, MKL_Complex8)   \ | ||||
|   EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vz##VMLOP, dcomplex, MKL_Complex16) | ||||
|  | ||||
| #define EIGEN_MKL_VML_DECLARE_UNARY_CALLS(EIGENOP, VMLOP)                        \ | ||||
|   EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP)                         \ | ||||
|   EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX(EIGENOP, VMLOP) | ||||
|  | ||||
|  | ||||
| #define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL_LA(EIGENOP, VMLOP)                \ | ||||
|   EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vms##VMLOP, float, float)         \ | ||||
|   EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vmd##VMLOP, double, double) | ||||
|  | ||||
| #define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX_LA(EIGENOP, VMLOP)             \ | ||||
|   EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vmc##VMLOP, scomplex, MKL_Complex8)  \ | ||||
|   EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vmz##VMLOP, dcomplex, MKL_Complex16) | ||||
|  | ||||
| #define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(EIGENOP, VMLOP)                     \ | ||||
|   EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL_LA(EIGENOP, VMLOP)                      \ | ||||
|   EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX_LA(EIGENOP, VMLOP) | ||||
|  | ||||
|  | ||||
| EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sin,  Sin) | ||||
| EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(asin, Asin) | ||||
| EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(cos,  Cos) | ||||
| EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(acos, Acos) | ||||
| EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(tan,  Tan) | ||||
| //EIGEN_MKL_VML_DECLARE_UNARY_CALLS(abs,  Abs) | ||||
| EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(exp,  Exp) | ||||
| EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(log,  Ln) | ||||
| EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sqrt, Sqrt) | ||||
|  | ||||
| EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr) | ||||
|  | ||||
| // The vm*powx functions are not avaibale in the windows version of MKL. | ||||
| #ifdef _WIN32 | ||||
| EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmspowx_, float, float) | ||||
| EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmdpowx_, double, double) | ||||
| EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmcpowx_, scomplex, MKL_Complex8) | ||||
| EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmzpowx_, dcomplex, MKL_Complex16) | ||||
| #endif | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_ASSIGN_VML_H | ||||
							
								
								
									
										334
									
								
								latan/Eigen/src/Core/BandMatrix.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										334
									
								
								latan/Eigen/src/Core/BandMatrix.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,334 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_BANDMATRIX_H | ||||
| #define EIGEN_BANDMATRIX_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename Derived> | ||||
| class BandMatrixBase : public EigenBase<Derived> | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     enum { | ||||
|       Flags = internal::traits<Derived>::Flags, | ||||
|       CoeffReadCost = internal::traits<Derived>::CoeffReadCost, | ||||
|       RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime, | ||||
|       ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime, | ||||
|       MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime, | ||||
|       MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime, | ||||
|       Supers = internal::traits<Derived>::Supers, | ||||
|       Subs   = internal::traits<Derived>::Subs, | ||||
|       Options = internal::traits<Derived>::Options | ||||
|     }; | ||||
|     typedef typename internal::traits<Derived>::Scalar Scalar; | ||||
|     typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> DenseMatrixType; | ||||
|     typedef typename DenseMatrixType::Index Index; | ||||
|     typedef typename internal::traits<Derived>::CoefficientsType CoefficientsType; | ||||
|     typedef EigenBase<Derived> Base; | ||||
|  | ||||
|   protected: | ||||
|     enum { | ||||
|       DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) | ||||
|                             ? 1 + Supers + Subs | ||||
|                             : Dynamic, | ||||
|       SizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime) | ||||
|     }; | ||||
|  | ||||
|   public: | ||||
|      | ||||
|     using Base::derived; | ||||
|     using Base::rows; | ||||
|     using Base::cols; | ||||
|  | ||||
|     /** \returns the number of super diagonals */ | ||||
|     inline Index supers() const { return derived().supers(); } | ||||
|  | ||||
|     /** \returns the number of sub diagonals */ | ||||
|     inline Index subs() const { return derived().subs(); } | ||||
|      | ||||
|     /** \returns an expression of the underlying coefficient matrix */ | ||||
|     inline const CoefficientsType& coeffs() const { return derived().coeffs(); } | ||||
|      | ||||
|     /** \returns an expression of the underlying coefficient matrix */ | ||||
|     inline CoefficientsType& coeffs() { return derived().coeffs(); } | ||||
|  | ||||
|     /** \returns a vector expression of the \a i -th column, | ||||
|       * only the meaningful part is returned. | ||||
|       * \warning the internal storage must be column major. */ | ||||
|     inline Block<CoefficientsType,Dynamic,1> col(Index i) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT((Options&RowMajor)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES); | ||||
|       Index start = 0; | ||||
|       Index len = coeffs().rows(); | ||||
|       if (i<=supers()) | ||||
|       { | ||||
|         start = supers()-i; | ||||
|         len = (std::min)(rows(),std::max<Index>(0,coeffs().rows() - (supers()-i))); | ||||
|       } | ||||
|       else if (i>=rows()-subs()) | ||||
|         len = std::max<Index>(0,coeffs().rows() - (i + 1 - rows() + subs())); | ||||
|       return Block<CoefficientsType,Dynamic,1>(coeffs(), start, i, len, 1); | ||||
|     } | ||||
|  | ||||
|     /** \returns a vector expression of the main diagonal */ | ||||
|     inline Block<CoefficientsType,1,SizeAtCompileTime> diagonal() | ||||
|     { return Block<CoefficientsType,1,SizeAtCompileTime>(coeffs(),supers(),0,1,(std::min)(rows(),cols())); } | ||||
|  | ||||
|     /** \returns a vector expression of the main diagonal (const version) */ | ||||
|     inline const Block<const CoefficientsType,1,SizeAtCompileTime> diagonal() const | ||||
|     { return Block<const CoefficientsType,1,SizeAtCompileTime>(coeffs(),supers(),0,1,(std::min)(rows(),cols())); } | ||||
|  | ||||
|     template<int Index> struct DiagonalIntReturnType { | ||||
|       enum { | ||||
|         ReturnOpposite = (Options&SelfAdjoint) && (((Index)>0 && Supers==0) || ((Index)<0 && Subs==0)), | ||||
|         Conjugate = ReturnOpposite && NumTraits<Scalar>::IsComplex, | ||||
|         ActualIndex = ReturnOpposite ? -Index : Index, | ||||
|         DiagonalSize = (RowsAtCompileTime==Dynamic || ColsAtCompileTime==Dynamic) | ||||
|                      ? Dynamic | ||||
|                      : (ActualIndex<0 | ||||
|                      ? EIGEN_SIZE_MIN_PREFER_DYNAMIC(ColsAtCompileTime, RowsAtCompileTime + ActualIndex) | ||||
|                      : EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime, ColsAtCompileTime - ActualIndex)) | ||||
|       }; | ||||
|       typedef Block<CoefficientsType,1, DiagonalSize> BuildType; | ||||
|       typedef typename internal::conditional<Conjugate, | ||||
|                  CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>,BuildType >, | ||||
|                  BuildType>::type Type; | ||||
|     }; | ||||
|  | ||||
|     /** \returns a vector expression of the \a N -th sub or super diagonal */ | ||||
|     template<int N> inline typename DiagonalIntReturnType<N>::Type diagonal() | ||||
|     { | ||||
|       return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N)); | ||||
|     } | ||||
|  | ||||
|     /** \returns a vector expression of the \a N -th sub or super diagonal */ | ||||
|     template<int N> inline const typename DiagonalIntReturnType<N>::Type diagonal() const | ||||
|     { | ||||
|       return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N)); | ||||
|     } | ||||
|  | ||||
|     /** \returns a vector expression of the \a i -th sub or super diagonal */ | ||||
|     inline Block<CoefficientsType,1,Dynamic> diagonal(Index i) | ||||
|     { | ||||
|       eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers())); | ||||
|       return Block<CoefficientsType,1,Dynamic>(coeffs(), supers()-i, std::max<Index>(0,i), 1, diagonalLength(i)); | ||||
|     } | ||||
|  | ||||
|     /** \returns a vector expression of the \a i -th sub or super diagonal */ | ||||
|     inline const Block<const CoefficientsType,1,Dynamic> diagonal(Index i) const | ||||
|     { | ||||
|       eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers())); | ||||
|       return Block<const CoefficientsType,1,Dynamic>(coeffs(), supers()-i, std::max<Index>(0,i), 1, diagonalLength(i)); | ||||
|     } | ||||
|      | ||||
|     template<typename Dest> inline void evalTo(Dest& dst) const | ||||
|     { | ||||
|       dst.resize(rows(),cols()); | ||||
|       dst.setZero(); | ||||
|       dst.diagonal() = diagonal(); | ||||
|       for (Index i=1; i<=supers();++i) | ||||
|         dst.diagonal(i) = diagonal(i); | ||||
|       for (Index i=1; i<=subs();++i) | ||||
|         dst.diagonal(-i) = diagonal(-i); | ||||
|     } | ||||
|  | ||||
|     DenseMatrixType toDenseMatrix() const | ||||
|     { | ||||
|       DenseMatrixType res(rows(),cols()); | ||||
|       evalTo(res); | ||||
|       return res; | ||||
|     } | ||||
|  | ||||
|   protected: | ||||
|  | ||||
|     inline Index diagonalLength(Index i) const | ||||
|     { return i<0 ? (std::min)(cols(),rows()+i) : (std::min)(rows(),cols()-i); } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|   * \class BandMatrix | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Represents a rectangular matrix with a banded storage | ||||
|   * | ||||
|   * \param _Scalar Numeric type, i.e. float, double, int | ||||
|   * \param Rows Number of rows, or \b Dynamic | ||||
|   * \param Cols Number of columns, or \b Dynamic | ||||
|   * \param Supers Number of super diagonal | ||||
|   * \param Subs Number of sub diagonal | ||||
|   * \param _Options A combination of either \b #RowMajor or \b #ColMajor, and of \b #SelfAdjoint | ||||
|   *                 The former controls \ref TopicStorageOrders "storage order", and defaults to | ||||
|   *                 column-major. The latter controls whether the matrix represents a selfadjoint  | ||||
|   *                 matrix in which case either Supers of Subs have to be null. | ||||
|   * | ||||
|   * \sa class TridiagonalMatrix | ||||
|   */ | ||||
|  | ||||
| template<typename _Scalar, int _Rows, int _Cols, int _Supers, int _Subs, int _Options> | ||||
| struct traits<BandMatrix<_Scalar,_Rows,_Cols,_Supers,_Subs,_Options> > | ||||
| { | ||||
|   typedef _Scalar Scalar; | ||||
|   typedef Dense StorageKind; | ||||
|   typedef DenseIndex Index; | ||||
|   enum { | ||||
|     CoeffReadCost = NumTraits<Scalar>::ReadCost, | ||||
|     RowsAtCompileTime = _Rows, | ||||
|     ColsAtCompileTime = _Cols, | ||||
|     MaxRowsAtCompileTime = _Rows, | ||||
|     MaxColsAtCompileTime = _Cols, | ||||
|     Flags = LvalueBit, | ||||
|     Supers = _Supers, | ||||
|     Subs = _Subs, | ||||
|     Options = _Options, | ||||
|     DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic | ||||
|   }; | ||||
|   typedef Matrix<Scalar,DataRowsAtCompileTime,ColsAtCompileTime,Options&RowMajor?RowMajor:ColMajor> CoefficientsType; | ||||
| }; | ||||
|  | ||||
| template<typename _Scalar, int Rows, int Cols, int Supers, int Subs, int Options> | ||||
| class BandMatrix : public BandMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs,Options> > | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef typename internal::traits<BandMatrix>::Scalar Scalar; | ||||
|     typedef typename internal::traits<BandMatrix>::Index Index; | ||||
|     typedef typename internal::traits<BandMatrix>::CoefficientsType CoefficientsType; | ||||
|  | ||||
|     inline BandMatrix(Index rows=Rows, Index cols=Cols, Index supers=Supers, Index subs=Subs) | ||||
|       : m_coeffs(1+supers+subs,cols), | ||||
|         m_rows(rows), m_supers(supers), m_subs(subs) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     /** \returns the number of columns */ | ||||
|     inline Index rows() const { return m_rows.value(); } | ||||
|  | ||||
|     /** \returns the number of rows */ | ||||
|     inline Index cols() const { return m_coeffs.cols(); } | ||||
|  | ||||
|     /** \returns the number of super diagonals */ | ||||
|     inline Index supers() const { return m_supers.value(); } | ||||
|  | ||||
|     /** \returns the number of sub diagonals */ | ||||
|     inline Index subs() const { return m_subs.value(); } | ||||
|  | ||||
|     inline const CoefficientsType& coeffs() const { return m_coeffs; } | ||||
|     inline CoefficientsType& coeffs() { return m_coeffs; } | ||||
|  | ||||
|   protected: | ||||
|  | ||||
|     CoefficientsType m_coeffs; | ||||
|     internal::variable_if_dynamic<Index, Rows>   m_rows; | ||||
|     internal::variable_if_dynamic<Index, Supers> m_supers; | ||||
|     internal::variable_if_dynamic<Index, Subs>   m_subs; | ||||
| }; | ||||
|  | ||||
| template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options> | ||||
| class BandMatrixWrapper; | ||||
|  | ||||
| template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options> | ||||
| struct traits<BandMatrixWrapper<_CoefficientsType,_Rows,_Cols,_Supers,_Subs,_Options> > | ||||
| { | ||||
|   typedef typename _CoefficientsType::Scalar Scalar; | ||||
|   typedef typename _CoefficientsType::StorageKind StorageKind; | ||||
|   typedef typename _CoefficientsType::Index Index; | ||||
|   enum { | ||||
|     CoeffReadCost = internal::traits<_CoefficientsType>::CoeffReadCost, | ||||
|     RowsAtCompileTime = _Rows, | ||||
|     ColsAtCompileTime = _Cols, | ||||
|     MaxRowsAtCompileTime = _Rows, | ||||
|     MaxColsAtCompileTime = _Cols, | ||||
|     Flags = LvalueBit, | ||||
|     Supers = _Supers, | ||||
|     Subs = _Subs, | ||||
|     Options = _Options, | ||||
|     DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic | ||||
|   }; | ||||
|   typedef _CoefficientsType CoefficientsType; | ||||
| }; | ||||
|  | ||||
| template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options> | ||||
| class BandMatrixWrapper : public BandMatrixBase<BandMatrixWrapper<_CoefficientsType,_Rows,_Cols,_Supers,_Subs,_Options> > | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef typename internal::traits<BandMatrixWrapper>::Scalar Scalar; | ||||
|     typedef typename internal::traits<BandMatrixWrapper>::CoefficientsType CoefficientsType; | ||||
|     typedef typename internal::traits<BandMatrixWrapper>::Index Index; | ||||
|  | ||||
|     inline BandMatrixWrapper(const CoefficientsType& coeffs, Index rows=_Rows, Index cols=_Cols, Index supers=_Supers, Index subs=_Subs) | ||||
|       : m_coeffs(coeffs), | ||||
|         m_rows(rows), m_supers(supers), m_subs(subs) | ||||
|     { | ||||
|       EIGEN_UNUSED_VARIABLE(cols); | ||||
|       //internal::assert(coeffs.cols()==cols() && (supers()+subs()+1)==coeffs.rows()); | ||||
|     } | ||||
|  | ||||
|     /** \returns the number of columns */ | ||||
|     inline Index rows() const { return m_rows.value(); } | ||||
|  | ||||
|     /** \returns the number of rows */ | ||||
|     inline Index cols() const { return m_coeffs.cols(); } | ||||
|  | ||||
|     /** \returns the number of super diagonals */ | ||||
|     inline Index supers() const { return m_supers.value(); } | ||||
|  | ||||
|     /** \returns the number of sub diagonals */ | ||||
|     inline Index subs() const { return m_subs.value(); } | ||||
|  | ||||
|     inline const CoefficientsType& coeffs() const { return m_coeffs; } | ||||
|  | ||||
|   protected: | ||||
|  | ||||
|     const CoefficientsType& m_coeffs; | ||||
|     internal::variable_if_dynamic<Index, _Rows>   m_rows; | ||||
|     internal::variable_if_dynamic<Index, _Supers> m_supers; | ||||
|     internal::variable_if_dynamic<Index, _Subs>   m_subs; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|   * \class TridiagonalMatrix | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Represents a tridiagonal matrix with a compact banded storage | ||||
|   * | ||||
|   * \param _Scalar Numeric type, i.e. float, double, int | ||||
|   * \param Size Number of rows and cols, or \b Dynamic | ||||
|   * \param _Options Can be 0 or \b SelfAdjoint | ||||
|   * | ||||
|   * \sa class BandMatrix | ||||
|   */ | ||||
| template<typename Scalar, int Size, int Options> | ||||
| class TridiagonalMatrix : public BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor> | ||||
| { | ||||
|     typedef BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor> Base; | ||||
|     typedef typename Base::Index Index; | ||||
|   public: | ||||
|     TridiagonalMatrix(Index size = Size) : Base(size,size,Options&SelfAdjoint?0:1,1) {} | ||||
|  | ||||
|     inline typename Base::template DiagonalIntReturnType<1>::Type super() | ||||
|     { return Base::template diagonal<1>(); } | ||||
|     inline const typename Base::template DiagonalIntReturnType<1>::Type super() const | ||||
|     { return Base::template diagonal<1>(); } | ||||
|     inline typename Base::template DiagonalIntReturnType<-1>::Type sub() | ||||
|     { return Base::template diagonal<-1>(); } | ||||
|     inline const typename Base::template DiagonalIntReturnType<-1>::Type sub() const | ||||
|     { return Base::template diagonal<-1>(); } | ||||
|   protected: | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_BANDMATRIX_H | ||||
							
								
								
									
										357
									
								
								latan/Eigen/src/Core/Block.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										357
									
								
								latan/Eigen/src/Core/Block.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,357 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_BLOCK_H | ||||
| #define EIGEN_BLOCK_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class Block | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Expression of a fixed-size or dynamic-size block | ||||
|   * | ||||
|   * \param XprType the type of the expression in which we are taking a block | ||||
|   * \param BlockRows the number of rows of the block we are taking at compile time (optional) | ||||
|   * \param BlockCols the number of columns of the block we are taking at compile time (optional) | ||||
|   * \param _DirectAccessStatus \internal used for partial specialization | ||||
|   * | ||||
|   * This class represents an expression of either a fixed-size or dynamic-size block. It is the return | ||||
|   * type of DenseBase::block(Index,Index,Index,Index) and DenseBase::block<int,int>(Index,Index) and | ||||
|   * most of the time this is the only way it is used. | ||||
|   * | ||||
|   * However, if you want to directly maniputate block expressions, | ||||
|   * for instance if you want to write a function returning such an expression, you | ||||
|   * will need to use this class. | ||||
|   * | ||||
|   * Here is an example illustrating the dynamic case: | ||||
|   * \include class_Block.cpp | ||||
|   * Output: \verbinclude class_Block.out | ||||
|   * | ||||
|   * \note Even though this expression has dynamic size, in the case where \a XprType | ||||
|   * has fixed size, this expression inherits a fixed maximal size which means that evaluating | ||||
|   * it does not cause a dynamic memory allocation. | ||||
|   * | ||||
|   * Here is an example illustrating the fixed-size case: | ||||
|   * \include class_FixedBlock.cpp | ||||
|   * Output: \verbinclude class_FixedBlock.out | ||||
|   * | ||||
|   * \sa DenseBase::block(Index,Index,Index,Index), DenseBase::block(Index,Index), class VectorBlock | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess> | ||||
| struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel, HasDirectAccess> > : traits<XprType> | ||||
| { | ||||
|   typedef typename traits<XprType>::Scalar Scalar; | ||||
|   typedef typename traits<XprType>::StorageKind StorageKind; | ||||
|   typedef typename traits<XprType>::XprKind XprKind; | ||||
|   typedef typename nested<XprType>::type XprTypeNested; | ||||
|   typedef typename remove_reference<XprTypeNested>::type _XprTypeNested; | ||||
|   enum{ | ||||
|     MatrixRows = traits<XprType>::RowsAtCompileTime, | ||||
|     MatrixCols = traits<XprType>::ColsAtCompileTime, | ||||
|     RowsAtCompileTime = MatrixRows == 0 ? 0 : BlockRows, | ||||
|     ColsAtCompileTime = MatrixCols == 0 ? 0 : BlockCols, | ||||
|     MaxRowsAtCompileTime = BlockRows==0 ? 0 | ||||
|                          : RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime) | ||||
|                          : int(traits<XprType>::MaxRowsAtCompileTime), | ||||
|     MaxColsAtCompileTime = BlockCols==0 ? 0 | ||||
|                          : ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime) | ||||
|                          : int(traits<XprType>::MaxColsAtCompileTime), | ||||
|     XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0, | ||||
|     IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1 | ||||
|                : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0 | ||||
|                : XprTypeIsRowMajor, | ||||
|     HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor), | ||||
|     InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime), | ||||
|     InnerStrideAtCompileTime = HasSameStorageOrderAsXprType | ||||
|                              ? int(inner_stride_at_compile_time<XprType>::ret) | ||||
|                              : int(outer_stride_at_compile_time<XprType>::ret), | ||||
|     OuterStrideAtCompileTime = HasSameStorageOrderAsXprType | ||||
|                              ? int(outer_stride_at_compile_time<XprType>::ret) | ||||
|                              : int(inner_stride_at_compile_time<XprType>::ret), | ||||
|     MaskPacketAccessBit = (InnerSize == Dynamic || (InnerSize % packet_traits<Scalar>::size) == 0) | ||||
|                        && (InnerStrideAtCompileTime == 1) | ||||
|                         ? PacketAccessBit : 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, | ||||
|     Flags0 = traits<XprType>::Flags & ( (HereditaryBits & ~RowMajorBit) | | ||||
|                                         DirectAccessBit | | ||||
|                                         MaskPacketAccessBit | | ||||
|                                         MaskAlignedBit), | ||||
|     Flags = Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess> class Block | ||||
|   : public internal::dense_xpr_base<Block<XprType, BlockRows, BlockCols, InnerPanel, HasDirectAccess> >::type | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef typename internal::dense_xpr_base<Block>::type Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(Block) | ||||
|  | ||||
|     class InnerIterator; | ||||
|  | ||||
|     /** Column or Row constructor | ||||
|       */ | ||||
|     inline Block(XprType& xpr, Index i) | ||||
|       : m_xpr(xpr), | ||||
|         // It is a row if and only if BlockRows==1 and BlockCols==XprType::ColsAtCompileTime, | ||||
|         // and it is a column if and only if BlockRows==XprType::RowsAtCompileTime and BlockCols==1, | ||||
|         // all other cases are invalid. | ||||
|         // The case a 1x1 matrix seems ambiguous, but the result is the same anyway. | ||||
|         m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0), | ||||
|         m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0), | ||||
|         m_blockRows(BlockRows==1 ? 1 : xpr.rows()), | ||||
|         m_blockCols(BlockCols==1 ? 1 : xpr.cols()) | ||||
|     { | ||||
|       eigen_assert( (i>=0) && ( | ||||
|           ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows()) | ||||
|         ||((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && i<xpr.cols()))); | ||||
|     } | ||||
|  | ||||
|     /** Fixed-size constructor | ||||
|       */ | ||||
|     inline Block(XprType& xpr, Index startRow, Index startCol) | ||||
|       : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol), | ||||
|         m_blockRows(BlockRows), m_blockCols(BlockCols) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE) | ||||
|       eigen_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= xpr.rows() | ||||
|              && startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= xpr.cols()); | ||||
|     } | ||||
|  | ||||
|     /** Dynamic-size constructor | ||||
|       */ | ||||
|     inline Block(XprType& xpr, | ||||
|           Index startRow, Index startCol, | ||||
|           Index blockRows, Index blockCols) | ||||
|       : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol), | ||||
|                           m_blockRows(blockRows), m_blockCols(blockCols) | ||||
|     { | ||||
|       eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows) | ||||
|           && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols)); | ||||
|       eigen_assert(startRow >= 0 && blockRows >= 0 && startRow + blockRows <= xpr.rows() | ||||
|           && startCol >= 0 && blockCols >= 0 && startCol + blockCols <= xpr.cols()); | ||||
|     } | ||||
|  | ||||
|     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block) | ||||
|  | ||||
|     inline Index rows() const { return m_blockRows.value(); } | ||||
|     inline Index cols() const { return m_blockCols.value(); } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index row, Index col) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_LVALUE(XprType) | ||||
|       return m_xpr.const_cast_derived() | ||||
|                .coeffRef(row + m_startRow.value(), col + m_startCol.value()); | ||||
|     } | ||||
|  | ||||
|     inline const Scalar& coeffRef(Index row, Index col) const | ||||
|     { | ||||
|       return m_xpr.derived() | ||||
|                .coeffRef(row + m_startRow.value(), col + m_startCol.value()); | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index row, Index col) const | ||||
|     { | ||||
|       return m_xpr.coeff(row + m_startRow.value(), col + m_startCol.value()); | ||||
|     } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index index) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_LVALUE(XprType) | ||||
|       return m_xpr.const_cast_derived() | ||||
|              .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), | ||||
|                        m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); | ||||
|     } | ||||
|  | ||||
|     inline const Scalar& coeffRef(Index index) const | ||||
|     { | ||||
|       return m_xpr.const_cast_derived() | ||||
|              .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), | ||||
|                        m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); | ||||
|     } | ||||
|  | ||||
|     inline const CoeffReturnType coeff(Index index) const | ||||
|     { | ||||
|       return m_xpr | ||||
|              .coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), | ||||
|                     m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline PacketScalar packet(Index row, Index col) const | ||||
|     { | ||||
|       return m_xpr.template packet<Unaligned> | ||||
|               (row + m_startRow.value(), col + m_startCol.value()); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline void writePacket(Index row, Index col, const PacketScalar& x) | ||||
|     { | ||||
|       m_xpr.const_cast_derived().template writePacket<Unaligned> | ||||
|               (row + m_startRow.value(), col + m_startCol.value(), x); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline PacketScalar packet(Index index) const | ||||
|     { | ||||
|       return m_xpr.template packet<Unaligned> | ||||
|               (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), | ||||
|                m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline void writePacket(Index index, const PacketScalar& x) | ||||
|     { | ||||
|       m_xpr.const_cast_derived().template writePacket<Unaligned> | ||||
|          (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), | ||||
|           m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), x); | ||||
|     } | ||||
|  | ||||
|     #ifdef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /** \sa MapBase::data() */ | ||||
|     inline const Scalar* data() const; | ||||
|     inline Index innerStride() const; | ||||
|     inline Index outerStride() const; | ||||
|     #endif | ||||
|  | ||||
|     const typename internal::remove_all<typename XprType::Nested>::type& nestedExpression() const  | ||||
|     {  | ||||
|       return m_xpr;  | ||||
|     } | ||||
|        | ||||
|     Index startRow() const  | ||||
|     {  | ||||
|       return m_startRow.value();  | ||||
|     } | ||||
|        | ||||
|     Index startCol() const  | ||||
|     {  | ||||
|       return m_startCol.value();  | ||||
|     } | ||||
|  | ||||
|   protected: | ||||
|  | ||||
|     const typename XprType::Nested m_xpr; | ||||
|     const internal::variable_if_dynamic<Index, XprType::RowsAtCompileTime == 1 ? 0 : Dynamic> m_startRow; | ||||
|     const internal::variable_if_dynamic<Index, XprType::ColsAtCompileTime == 1 ? 0 : Dynamic> m_startCol; | ||||
|     const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_blockRows; | ||||
|     const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_blockCols; | ||||
| }; | ||||
|  | ||||
| /** \internal */ | ||||
| template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> | ||||
| class Block<XprType,BlockRows,BlockCols, InnerPanel,true> | ||||
|   : public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel, true> > | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef MapBase<Block> Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(Block) | ||||
|  | ||||
|     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block) | ||||
|  | ||||
|     /** Column or Row constructor | ||||
|       */ | ||||
|     inline Block(XprType& xpr, Index i) | ||||
|       : Base(internal::const_cast_ptr(&xpr.coeffRef( | ||||
|               (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0, | ||||
|               (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0)), | ||||
|              BlockRows==1 ? 1 : xpr.rows(), | ||||
|              BlockCols==1 ? 1 : xpr.cols()), | ||||
|         m_xpr(xpr) | ||||
|     { | ||||
|       eigen_assert( (i>=0) && ( | ||||
|           ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows()) | ||||
|         ||((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && i<xpr.cols()))); | ||||
|       init(); | ||||
|     } | ||||
|  | ||||
|     /** Fixed-size constructor | ||||
|       */ | ||||
|     inline Block(XprType& xpr, Index startRow, Index startCol) | ||||
|       : Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol))), m_xpr(xpr) | ||||
|     { | ||||
|       eigen_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= xpr.rows() | ||||
|              && startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= xpr.cols()); | ||||
|       init(); | ||||
|     } | ||||
|  | ||||
|     /** Dynamic-size constructor | ||||
|       */ | ||||
|     inline Block(XprType& xpr, | ||||
|           Index startRow, Index startCol, | ||||
|           Index blockRows, Index blockCols) | ||||
|       : Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol)), blockRows, blockCols), | ||||
|         m_xpr(xpr) | ||||
|     { | ||||
|       eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows) | ||||
|              && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols)); | ||||
|       eigen_assert(startRow >= 0 && blockRows >= 0 && startRow + blockRows <= xpr.rows() | ||||
|              && startCol >= 0 && blockCols >= 0 && startCol + blockCols <= xpr.cols()); | ||||
|       init(); | ||||
|     } | ||||
|  | ||||
|     const typename internal::remove_all<typename XprType::Nested>::type& nestedExpression() const  | ||||
|     {  | ||||
|       return m_xpr;  | ||||
|     } | ||||
|        | ||||
|     /** \sa MapBase::innerStride() */ | ||||
|     inline Index innerStride() const | ||||
|     { | ||||
|       return internal::traits<Block>::HasSameStorageOrderAsXprType | ||||
|              ? m_xpr.innerStride() | ||||
|              : m_xpr.outerStride(); | ||||
|     } | ||||
|  | ||||
|     /** \sa MapBase::outerStride() */ | ||||
|     inline Index outerStride() const | ||||
|     { | ||||
|       return m_outerStride; | ||||
|     } | ||||
|  | ||||
|   #ifndef __SUNPRO_CC | ||||
|   // FIXME sunstudio is not friendly with the above friend... | ||||
|   // META-FIXME there is no 'friend' keyword around here. Is this obsolete? | ||||
|   protected: | ||||
|   #endif | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /** \internal used by allowAligned() */ | ||||
|     inline Block(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols) | ||||
|       : Base(data, blockRows, blockCols), m_xpr(xpr) | ||||
|     { | ||||
|       init(); | ||||
|     } | ||||
|     #endif | ||||
|  | ||||
|   protected: | ||||
|     void init() | ||||
|     { | ||||
|       m_outerStride = internal::traits<Block>::HasSameStorageOrderAsXprType | ||||
|                     ? m_xpr.outerStride() | ||||
|                     : m_xpr.innerStride(); | ||||
|     } | ||||
|  | ||||
|     typename XprType::Nested m_xpr; | ||||
|     Index m_outerStride; | ||||
| }; | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_BLOCK_H | ||||
							
								
								
									
										138
									
								
								latan/Eigen/src/Core/BooleanRedux.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								latan/Eigen/src/Core/BooleanRedux.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_ALLANDANY_H | ||||
| #define EIGEN_ALLANDANY_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename Derived, int UnrollCount> | ||||
| struct all_unroller | ||||
| { | ||||
|   enum { | ||||
|     col = (UnrollCount-1) / Derived::RowsAtCompileTime, | ||||
|     row = (UnrollCount-1) % Derived::RowsAtCompileTime | ||||
|   }; | ||||
|  | ||||
|   static inline bool run(const Derived &mat) | ||||
|   { | ||||
|     return all_unroller<Derived, UnrollCount-1>::run(mat) && mat.coeff(row, col); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived> | ||||
| struct all_unroller<Derived, 1> | ||||
| { | ||||
|   static inline bool run(const Derived &mat) { return mat.coeff(0, 0); } | ||||
| }; | ||||
|  | ||||
| template<typename Derived> | ||||
| struct all_unroller<Derived, Dynamic> | ||||
| { | ||||
|   static inline bool run(const Derived &) { return false; } | ||||
| }; | ||||
|  | ||||
| template<typename Derived, int UnrollCount> | ||||
| struct any_unroller | ||||
| { | ||||
|   enum { | ||||
|     col = (UnrollCount-1) / Derived::RowsAtCompileTime, | ||||
|     row = (UnrollCount-1) % Derived::RowsAtCompileTime | ||||
|   }; | ||||
|  | ||||
|   static inline bool run(const Derived &mat) | ||||
|   { | ||||
|     return any_unroller<Derived, UnrollCount-1>::run(mat) || mat.coeff(row, col); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived> | ||||
| struct any_unroller<Derived, 1> | ||||
| { | ||||
|   static inline bool run(const Derived &mat) { return mat.coeff(0, 0); } | ||||
| }; | ||||
|  | ||||
| template<typename Derived> | ||||
| struct any_unroller<Derived, Dynamic> | ||||
| { | ||||
|   static inline bool run(const Derived &) { return false; } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /** \returns true if all coefficients are true | ||||
|   * | ||||
|   * Example: \include MatrixBase_all.cpp | ||||
|   * Output: \verbinclude MatrixBase_all.out | ||||
|   * | ||||
|   * \sa any(), Cwise::operator<() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline bool DenseBase<Derived>::all() const | ||||
| { | ||||
|   enum { | ||||
|     unroll = SizeAtCompileTime != Dynamic | ||||
|           && CoeffReadCost != Dynamic | ||||
|           && NumTraits<Scalar>::AddCost != Dynamic | ||||
|           && SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT | ||||
|   }; | ||||
|   if(unroll) | ||||
|     return internal::all_unroller<Derived, | ||||
|                            unroll ? int(SizeAtCompileTime) : Dynamic | ||||
|      >::run(derived()); | ||||
|   else | ||||
|   { | ||||
|     for(Index j = 0; j < cols(); ++j) | ||||
|       for(Index i = 0; i < rows(); ++i) | ||||
|         if (!coeff(i, j)) return false; | ||||
|     return true; | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** \returns true if at least one coefficient is true | ||||
|   * | ||||
|   * \sa all() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline bool DenseBase<Derived>::any() const | ||||
| { | ||||
|   enum { | ||||
|     unroll = SizeAtCompileTime != Dynamic | ||||
|           && CoeffReadCost != Dynamic | ||||
|           && NumTraits<Scalar>::AddCost != Dynamic | ||||
|           && SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT | ||||
|   }; | ||||
|   if(unroll) | ||||
|     return internal::any_unroller<Derived, | ||||
|                            unroll ? int(SizeAtCompileTime) : Dynamic | ||||
|            >::run(derived()); | ||||
|   else | ||||
|   { | ||||
|     for(Index j = 0; j < cols(); ++j) | ||||
|       for(Index i = 0; i < rows(); ++i) | ||||
|         if (coeff(i, j)) return true; | ||||
|     return false; | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** \returns the number of coefficients which evaluate to true | ||||
|   * | ||||
|   * \sa all(), any() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline typename DenseBase<Derived>::Index DenseBase<Derived>::count() const | ||||
| { | ||||
|   return derived().template cast<bool>().template cast<Index>().sum(); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_ALLANDANY_H | ||||
							
								
								
									
										141
									
								
								latan/Eigen/src/Core/CommaInitializer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								latan/Eigen/src/Core/CommaInitializer.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,141 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_COMMAINITIALIZER_H | ||||
| #define EIGEN_COMMAINITIALIZER_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class CommaInitializer | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Helper class used by the comma initializer operator | ||||
|   * | ||||
|   * This class is internally used to implement the comma initializer feature. It is | ||||
|   * the return type of MatrixBase::operator<<, and most of the time this is the only | ||||
|   * way it is used. | ||||
|   * | ||||
|   * \sa \ref MatrixBaseCommaInitRef "MatrixBase::operator<<", CommaInitializer::finished() | ||||
|   */ | ||||
| template<typename XprType> | ||||
| struct CommaInitializer | ||||
| { | ||||
|   typedef typename XprType::Scalar Scalar; | ||||
|   typedef typename XprType::Index Index; | ||||
|  | ||||
|   inline CommaInitializer(XprType& xpr, const Scalar& s) | ||||
|     : m_xpr(xpr), m_row(0), m_col(1), m_currentBlockRows(1) | ||||
|   { | ||||
|     m_xpr.coeffRef(0,0) = s; | ||||
|   } | ||||
|  | ||||
|   template<typename OtherDerived> | ||||
|   inline CommaInitializer(XprType& xpr, const DenseBase<OtherDerived>& other) | ||||
|     : m_xpr(xpr), m_row(0), m_col(other.cols()), m_currentBlockRows(other.rows()) | ||||
|   { | ||||
|     m_xpr.block(0, 0, other.rows(), other.cols()) = other; | ||||
|   } | ||||
|  | ||||
|   /* inserts a scalar value in the target matrix */ | ||||
|   CommaInitializer& operator,(const Scalar& s) | ||||
|   { | ||||
|     if (m_col==m_xpr.cols()) | ||||
|     { | ||||
|       m_row+=m_currentBlockRows; | ||||
|       m_col = 0; | ||||
|       m_currentBlockRows = 1; | ||||
|       eigen_assert(m_row<m_xpr.rows() | ||||
|         && "Too many rows passed to comma initializer (operator<<)"); | ||||
|     } | ||||
|     eigen_assert(m_col<m_xpr.cols() | ||||
|       && "Too many coefficients passed to comma initializer (operator<<)"); | ||||
|     eigen_assert(m_currentBlockRows==1); | ||||
|     m_xpr.coeffRef(m_row, m_col++) = s; | ||||
|     return *this; | ||||
|   } | ||||
|  | ||||
|   /* inserts a matrix expression in the target matrix */ | ||||
|   template<typename OtherDerived> | ||||
|   CommaInitializer& operator,(const DenseBase<OtherDerived>& other) | ||||
|   { | ||||
|     if(other.cols()==0 || other.rows()==0) | ||||
|       return *this; | ||||
|     if (m_col==m_xpr.cols()) | ||||
|     { | ||||
|       m_row+=m_currentBlockRows; | ||||
|       m_col = 0; | ||||
|       m_currentBlockRows = other.rows(); | ||||
|       eigen_assert(m_row+m_currentBlockRows<=m_xpr.rows() | ||||
|         && "Too many rows passed to comma initializer (operator<<)"); | ||||
|     } | ||||
|     eigen_assert(m_col<m_xpr.cols() | ||||
|       && "Too many coefficients passed to comma initializer (operator<<)"); | ||||
|     eigen_assert(m_currentBlockRows==other.rows()); | ||||
|     if (OtherDerived::SizeAtCompileTime != Dynamic) | ||||
|       m_xpr.template block<OtherDerived::RowsAtCompileTime != Dynamic ? OtherDerived::RowsAtCompileTime : 1, | ||||
|                               OtherDerived::ColsAtCompileTime != Dynamic ? OtherDerived::ColsAtCompileTime : 1> | ||||
|                     (m_row, m_col) = other; | ||||
|     else | ||||
|       m_xpr.block(m_row, m_col, other.rows(), other.cols()) = other; | ||||
|     m_col += other.cols(); | ||||
|     return *this; | ||||
|   } | ||||
|  | ||||
|   inline ~CommaInitializer() | ||||
|   { | ||||
|     eigen_assert((m_row+m_currentBlockRows) == m_xpr.rows() | ||||
|          && m_col == m_xpr.cols() | ||||
|          && "Too few coefficients passed to comma initializer (operator<<)"); | ||||
|   } | ||||
|  | ||||
|   /** \returns the built matrix once all its coefficients have been set. | ||||
|     * Calling finished is 100% optional. Its purpose is to write expressions | ||||
|     * like this: | ||||
|     * \code | ||||
|     * quaternion.fromRotationMatrix((Matrix3f() << axis0, axis1, axis2).finished()); | ||||
|     * \endcode | ||||
|     */ | ||||
|   inline XprType& finished() { return m_xpr; } | ||||
|  | ||||
|   XprType& m_xpr;   // target expression | ||||
|   Index m_row;              // current row id | ||||
|   Index m_col;              // current col id | ||||
|   Index m_currentBlockRows; // current block height | ||||
| }; | ||||
|  | ||||
| /** \anchor MatrixBaseCommaInitRef | ||||
|   * Convenient operator to set the coefficients of a matrix. | ||||
|   * | ||||
|   * The coefficients must be provided in a row major order and exactly match | ||||
|   * the size of the matrix. Otherwise an assertion is raised. | ||||
|   * | ||||
|   * Example: \include MatrixBase_set.cpp | ||||
|   * Output: \verbinclude MatrixBase_set.out | ||||
|   * | ||||
|   * \sa CommaInitializer::finished(), class CommaInitializer | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline CommaInitializer<Derived> DenseBase<Derived>::operator<< (const Scalar& s) | ||||
| { | ||||
|   return CommaInitializer<Derived>(*static_cast<Derived*>(this), s); | ||||
| } | ||||
|  | ||||
| /** \sa operator<<(const Scalar&) */ | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| inline CommaInitializer<Derived> | ||||
| DenseBase<Derived>::operator<<(const DenseBase<OtherDerived>& other) | ||||
| { | ||||
|   return CommaInitializer<Derived>(*static_cast<Derived *>(this), other); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_COMMAINITIALIZER_H | ||||
							
								
								
									
										229
									
								
								latan/Eigen/src/Core/CwiseBinaryOp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										229
									
								
								latan/Eigen/src/Core/CwiseBinaryOp.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,229 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_CWISE_BINARY_OP_H | ||||
| #define EIGEN_CWISE_BINARY_OP_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| /** \class CwiseBinaryOp | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Generic expression where a coefficient-wise binary operator is applied to two expressions | ||||
|   * | ||||
|   * \param BinaryOp template functor implementing the operator | ||||
|   * \param Lhs the type of the left-hand side | ||||
|   * \param Rhs the type of the right-hand side | ||||
|   * | ||||
|   * This class represents an expression  where a coefficient-wise binary operator is applied to two expressions. | ||||
|   * It is the return type of binary operators, by which we mean only those binary operators where | ||||
|   * both the left-hand side and the right-hand side are Eigen expressions. | ||||
|   * For example, the return type of matrix1+matrix2 is a CwiseBinaryOp. | ||||
|   * | ||||
|   * Most of the time, this is the only way that it is used, so you typically don't have to name | ||||
|   * CwiseBinaryOp types explicitly. | ||||
|   * | ||||
|   * \sa MatrixBase::binaryExpr(const MatrixBase<OtherDerived> &,const CustomBinaryOp &) const, class CwiseUnaryOp, class CwiseNullaryOp | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename BinaryOp, typename Lhs, typename Rhs> | ||||
| struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > | ||||
| { | ||||
|   // we must not inherit from traits<Lhs> since it has | ||||
|   // the potential to cause problems with MSVC | ||||
|   typedef typename remove_all<Lhs>::type Ancestor; | ||||
|   typedef typename traits<Ancestor>::XprKind XprKind; | ||||
|   enum { | ||||
|     RowsAtCompileTime = traits<Ancestor>::RowsAtCompileTime, | ||||
|     ColsAtCompileTime = traits<Ancestor>::ColsAtCompileTime, | ||||
|     MaxRowsAtCompileTime = traits<Ancestor>::MaxRowsAtCompileTime, | ||||
|     MaxColsAtCompileTime = traits<Ancestor>::MaxColsAtCompileTime | ||||
|   }; | ||||
|  | ||||
|   // even though we require Lhs and Rhs to have the same scalar type (see CwiseBinaryOp constructor), | ||||
|   // we still want to handle the case when the result type is different. | ||||
|   typedef typename result_of< | ||||
|                      BinaryOp( | ||||
|                        typename Lhs::Scalar, | ||||
|                        typename Rhs::Scalar | ||||
|                      ) | ||||
|                    >::type Scalar; | ||||
|   typedef typename promote_storage_type<typename traits<Lhs>::StorageKind, | ||||
|                                            typename traits<Rhs>::StorageKind>::ret StorageKind; | ||||
|   typedef typename promote_index_type<typename traits<Lhs>::Index, | ||||
|                                          typename traits<Rhs>::Index>::type Index; | ||||
|   typedef typename Lhs::Nested LhsNested; | ||||
|   typedef typename Rhs::Nested RhsNested; | ||||
|   typedef typename remove_reference<LhsNested>::type _LhsNested; | ||||
|   typedef typename remove_reference<RhsNested>::type _RhsNested; | ||||
|   enum { | ||||
|     LhsCoeffReadCost = _LhsNested::CoeffReadCost, | ||||
|     RhsCoeffReadCost = _RhsNested::CoeffReadCost, | ||||
|     LhsFlags = _LhsNested::Flags, | ||||
|     RhsFlags = _RhsNested::Flags, | ||||
|     SameType = is_same<typename _LhsNested::Scalar,typename _RhsNested::Scalar>::value, | ||||
|     StorageOrdersAgree = (int(Lhs::Flags)&RowMajorBit)==(int(Rhs::Flags)&RowMajorBit), | ||||
|     Flags0 = (int(LhsFlags) | int(RhsFlags)) & ( | ||||
|         HereditaryBits | ||||
|       | (int(LhsFlags) & int(RhsFlags) & | ||||
|            ( AlignedBit | ||||
|            | (StorageOrdersAgree ? LinearAccessBit : 0) | ||||
|            | (functor_traits<BinaryOp>::PacketAccess && StorageOrdersAgree && SameType ? PacketAccessBit : 0) | ||||
|            ) | ||||
|         ) | ||||
|      ), | ||||
|     Flags = (Flags0 & ~RowMajorBit) | (LhsFlags & RowMajorBit), | ||||
|     CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + functor_traits<BinaryOp>::Cost | ||||
|   }; | ||||
| }; | ||||
| } // end namespace internal | ||||
|  | ||||
| // we require Lhs and Rhs to have the same scalar type. Currently there is no example of a binary functor | ||||
| // that would take two operands of different types. If there were such an example, then this check should be | ||||
| // moved to the BinaryOp functors, on a per-case basis. This would however require a change in the BinaryOp functors, as | ||||
| // currently they take only one typename Scalar template parameter. | ||||
| // It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths. | ||||
| // So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to | ||||
| // add together a float matrix and a double matrix. | ||||
| #define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \ | ||||
|   EIGEN_STATIC_ASSERT((internal::functor_allows_mixing_real_and_complex<BINOP>::ret \ | ||||
|                         ? int(internal::is_same<typename NumTraits<LHS>::Real, typename NumTraits<RHS>::Real>::value) \ | ||||
|                         : int(internal::is_same<LHS, RHS>::value)), \ | ||||
|     YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) | ||||
|  | ||||
| template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind> | ||||
| class CwiseBinaryOpImpl; | ||||
|  | ||||
| template<typename BinaryOp, typename Lhs, typename Rhs> | ||||
| class CwiseBinaryOp : internal::no_assignment_operator, | ||||
|   public CwiseBinaryOpImpl< | ||||
|           BinaryOp, Lhs, Rhs, | ||||
|           typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind, | ||||
|                                            typename internal::traits<Rhs>::StorageKind>::ret> | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef typename CwiseBinaryOpImpl< | ||||
|         BinaryOp, Lhs, Rhs, | ||||
|         typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind, | ||||
|                                          typename internal::traits<Rhs>::StorageKind>::ret>::Base Base; | ||||
|     EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp) | ||||
|  | ||||
|     typedef typename internal::nested<Lhs>::type LhsNested; | ||||
|     typedef typename internal::nested<Rhs>::type RhsNested; | ||||
|     typedef typename internal::remove_reference<LhsNested>::type _LhsNested; | ||||
|     typedef typename internal::remove_reference<RhsNested>::type _RhsNested; | ||||
|  | ||||
|     EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& lhs, const Rhs& rhs, const BinaryOp& func = BinaryOp()) | ||||
|       : m_lhs(lhs), m_rhs(rhs), m_functor(func) | ||||
|     { | ||||
|       EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar); | ||||
|       // require the sizes to match | ||||
|       EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs) | ||||
|       eigen_assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols()); | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Index rows() const { | ||||
|       // return the fixed size type if available to enable compile time optimizations | ||||
|       if (internal::traits<typename internal::remove_all<LhsNested>::type>::RowsAtCompileTime==Dynamic) | ||||
|         return m_rhs.rows(); | ||||
|       else | ||||
|         return m_lhs.rows(); | ||||
|     } | ||||
|     EIGEN_STRONG_INLINE Index cols() const { | ||||
|       // return the fixed size type if available to enable compile time optimizations | ||||
|       if (internal::traits<typename internal::remove_all<LhsNested>::type>::ColsAtCompileTime==Dynamic) | ||||
|         return m_rhs.cols(); | ||||
|       else | ||||
|         return m_lhs.cols(); | ||||
|     } | ||||
|  | ||||
|     /** \returns the left hand side nested expression */ | ||||
|     const _LhsNested& lhs() const { return m_lhs; } | ||||
|     /** \returns the right hand side nested expression */ | ||||
|     const _RhsNested& rhs() const { return m_rhs; } | ||||
|     /** \returns the functor representing the binary operation */ | ||||
|     const BinaryOp& functor() const { return m_functor; } | ||||
|  | ||||
|   protected: | ||||
|     LhsNested m_lhs; | ||||
|     RhsNested m_rhs; | ||||
|     const BinaryOp m_functor; | ||||
| }; | ||||
|  | ||||
| template<typename BinaryOp, typename Lhs, typename Rhs> | ||||
| class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Dense> | ||||
|   : public internal::dense_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type | ||||
| { | ||||
|     typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived; | ||||
|   public: | ||||
|  | ||||
|     typedef typename internal::dense_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE( Derived ) | ||||
|  | ||||
|     EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const | ||||
|     { | ||||
|       return derived().functor()(derived().lhs().coeff(row, col), | ||||
|                                  derived().rhs().coeff(row, col)); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const | ||||
|     { | ||||
|       return derived().functor().packetOp(derived().lhs().template packet<LoadMode>(row, col), | ||||
|                                           derived().rhs().template packet<LoadMode>(row, col)); | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE const Scalar coeff(Index index) const | ||||
|     { | ||||
|       return derived().functor()(derived().lhs().coeff(index), | ||||
|                                  derived().rhs().coeff(index)); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     EIGEN_STRONG_INLINE PacketScalar packet(Index index) const | ||||
|     { | ||||
|       return derived().functor().packetOp(derived().lhs().template packet<LoadMode>(index), | ||||
|                                           derived().rhs().template packet<LoadMode>(index)); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| /** replaces \c *this by \c *this - \a other. | ||||
|   * | ||||
|   * \returns a reference to \c *this | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| EIGEN_STRONG_INLINE Derived & | ||||
| MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other) | ||||
| { | ||||
|   SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, Derived, OtherDerived> tmp(derived()); | ||||
|   tmp = other.derived(); | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| /** replaces \c *this by \c *this + \a other. | ||||
|   * | ||||
|   * \returns a reference to \c *this | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| EIGEN_STRONG_INLINE Derived & | ||||
| MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other) | ||||
| { | ||||
|   SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, Derived, OtherDerived> tmp(derived()); | ||||
|   tmp = other.derived(); | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_CWISE_BINARY_OP_H | ||||
							
								
								
									
										864
									
								
								latan/Eigen/src/Core/CwiseNullaryOp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										864
									
								
								latan/Eigen/src/Core/CwiseNullaryOp.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,864 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_CWISE_NULLARY_OP_H | ||||
| #define EIGEN_CWISE_NULLARY_OP_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| /** \class CwiseNullaryOp | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Generic expression of a matrix where all coefficients are defined by a functor | ||||
|   * | ||||
|   * \param NullaryOp template functor implementing the operator | ||||
|   * \param PlainObjectType the underlying plain matrix/array type | ||||
|   * | ||||
|   * This class represents an expression of a generic nullary operator. | ||||
|   * It is the return type of the Ones(), Zero(), Constant(), Identity() and Random() methods, | ||||
|   * and most of the time this is the only way it is used. | ||||
|   * | ||||
|   * However, if you want to write a function returning such an expression, you | ||||
|   * will need to use this class. | ||||
|   * | ||||
|   * \sa class CwiseUnaryOp, class CwiseBinaryOp, DenseBase::NullaryExpr() | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename NullaryOp, typename PlainObjectType> | ||||
| struct traits<CwiseNullaryOp<NullaryOp, PlainObjectType> > : traits<PlainObjectType> | ||||
| { | ||||
|   enum { | ||||
|     Flags = (traits<PlainObjectType>::Flags | ||||
|       & (  HereditaryBits | ||||
|          | (functor_has_linear_access<NullaryOp>::ret ? LinearAccessBit : 0) | ||||
|          | (functor_traits<NullaryOp>::PacketAccess ? PacketAccessBit : 0))) | ||||
|       | (functor_traits<NullaryOp>::IsRepeatable ? 0 : EvalBeforeNestingBit), | ||||
|     CoeffReadCost = functor_traits<NullaryOp>::Cost | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename NullaryOp, typename PlainObjectType> | ||||
| class CwiseNullaryOp : internal::no_assignment_operator, | ||||
|   public internal::dense_xpr_base< CwiseNullaryOp<NullaryOp, PlainObjectType> >::type | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef typename internal::dense_xpr_base<CwiseNullaryOp>::type Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(CwiseNullaryOp) | ||||
|  | ||||
|     CwiseNullaryOp(Index rows, Index cols, const NullaryOp& func = NullaryOp()) | ||||
|       : m_rows(rows), m_cols(cols), m_functor(func) | ||||
|     { | ||||
|       eigen_assert(rows >= 0 | ||||
|             && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) | ||||
|             &&  cols >= 0 | ||||
|             && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)); | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Index rows() const { return m_rows.value(); } | ||||
|     EIGEN_STRONG_INLINE Index cols() const { return m_cols.value(); } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE const Scalar coeff(Index rows, Index cols) const | ||||
|     { | ||||
|       return m_functor(rows, cols); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const | ||||
|     { | ||||
|       return m_functor.packetOp(row, col); | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE const Scalar coeff(Index index) const | ||||
|     { | ||||
|       return m_functor(index); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     EIGEN_STRONG_INLINE PacketScalar packet(Index index) const | ||||
|     { | ||||
|       return m_functor.packetOp(index); | ||||
|     } | ||||
|  | ||||
|     /** \returns the functor representing the nullary operation */ | ||||
|     const NullaryOp& functor() const { return m_functor; } | ||||
|  | ||||
|   protected: | ||||
|     const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows; | ||||
|     const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols; | ||||
|     const NullaryOp m_functor; | ||||
| }; | ||||
|  | ||||
|  | ||||
| /** \returns an expression of a matrix defined by a custom functor \a func | ||||
|   * | ||||
|   * The parameters \a rows and \a cols are the number of rows and of columns of | ||||
|   * the returned matrix. Must be compatible with this MatrixBase type. | ||||
|   * | ||||
|   * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, | ||||
|   * it is redundant to pass \a rows and \a cols as arguments, so Zero() should be used | ||||
|   * instead. | ||||
|   * | ||||
|   * The template parameter \a CustomNullaryOp is the type of the functor. | ||||
|   * | ||||
|   * \sa class CwiseNullaryOp | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename CustomNullaryOp> | ||||
| EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived> | ||||
| DenseBase<Derived>::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func) | ||||
| { | ||||
|   return CwiseNullaryOp<CustomNullaryOp, Derived>(rows, cols, func); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of a matrix defined by a custom functor \a func | ||||
|   * | ||||
|   * The parameter \a size is the size of the returned vector. | ||||
|   * Must be compatible with this MatrixBase type. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * This variant is meant to be used for dynamic-size vector types. For fixed-size types, | ||||
|   * it is redundant to pass \a size as argument, so Zero() should be used | ||||
|   * instead. | ||||
|   * | ||||
|   * The template parameter \a CustomNullaryOp is the type of the functor. | ||||
|   * | ||||
|   * \sa class CwiseNullaryOp | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename CustomNullaryOp> | ||||
| EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived> | ||||
| DenseBase<Derived>::NullaryExpr(Index size, const CustomNullaryOp& func) | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   if(RowsAtCompileTime == 1) return CwiseNullaryOp<CustomNullaryOp, Derived>(1, size, func); | ||||
|   else return CwiseNullaryOp<CustomNullaryOp, Derived>(size, 1, func); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of a matrix defined by a custom functor \a func | ||||
|   * | ||||
|   * This variant is only for fixed-size DenseBase types. For dynamic-size types, you | ||||
|   * need to use the variants taking size arguments. | ||||
|   * | ||||
|   * The template parameter \a CustomNullaryOp is the type of the functor. | ||||
|   * | ||||
|   * \sa class CwiseNullaryOp | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename CustomNullaryOp> | ||||
| EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived> | ||||
| DenseBase<Derived>::NullaryExpr(const CustomNullaryOp& func) | ||||
| { | ||||
|   return CwiseNullaryOp<CustomNullaryOp, Derived>(RowsAtCompileTime, ColsAtCompileTime, func); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of a constant matrix of value \a value | ||||
|   * | ||||
|   * The parameters \a rows and \a cols are the number of rows and of columns of | ||||
|   * the returned matrix. Must be compatible with this DenseBase type. | ||||
|   * | ||||
|   * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, | ||||
|   * it is redundant to pass \a rows and \a cols as arguments, so Zero() should be used | ||||
|   * instead. | ||||
|   * | ||||
|   * The template parameter \a CustomNullaryOp is the type of the functor. | ||||
|   * | ||||
|   * \sa class CwiseNullaryOp | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType | ||||
| DenseBase<Derived>::Constant(Index rows, Index cols, const Scalar& value) | ||||
| { | ||||
|   return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_constant_op<Scalar>(value)); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of a constant matrix of value \a value | ||||
|   * | ||||
|   * The parameter \a size is the size of the returned vector. | ||||
|   * Must be compatible with this DenseBase type. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * This variant is meant to be used for dynamic-size vector types. For fixed-size types, | ||||
|   * it is redundant to pass \a size as argument, so Zero() should be used | ||||
|   * instead. | ||||
|   * | ||||
|   * The template parameter \a CustomNullaryOp is the type of the functor. | ||||
|   * | ||||
|   * \sa class CwiseNullaryOp | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType | ||||
| DenseBase<Derived>::Constant(Index size, const Scalar& value) | ||||
| { | ||||
|   return DenseBase<Derived>::NullaryExpr(size, internal::scalar_constant_op<Scalar>(value)); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of a constant matrix of value \a value | ||||
|   * | ||||
|   * This variant is only for fixed-size DenseBase types. For dynamic-size types, you | ||||
|   * need to use the variants taking size arguments. | ||||
|   * | ||||
|   * The template parameter \a CustomNullaryOp is the type of the functor. | ||||
|   * | ||||
|   * \sa class CwiseNullaryOp | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType | ||||
| DenseBase<Derived>::Constant(const Scalar& value) | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) | ||||
|   return DenseBase<Derived>::NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_constant_op<Scalar>(value)); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   * \brief Sets a linearly space vector. | ||||
|   * | ||||
|   * The function generates 'size' equally spaced values in the closed interval [low,high]. | ||||
|   * This particular version of LinSpaced() uses sequential access, i.e. vector access is | ||||
|   * assumed to be a(0), a(1), ..., a(size). This assumption allows for better vectorization | ||||
|   * and yields faster code than the random access version. | ||||
|   * | ||||
|   * When size is set to 1, a vector of length 1 containing 'high' is returned. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * Example: \include DenseBase_LinSpaced_seq.cpp | ||||
|   * Output: \verbinclude DenseBase_LinSpaced_seq.out | ||||
|   * | ||||
|   * \sa setLinSpaced(Index,const Scalar&,const Scalar&), LinSpaced(Index,Scalar,Scalar), CwiseNullaryOp | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename DenseBase<Derived>::SequentialLinSpacedReturnType | ||||
| DenseBase<Derived>::LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high) | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,false>(low,high,size)); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   * \copydoc DenseBase::LinSpaced(Sequential_t, Index, const Scalar&, const Scalar&) | ||||
|   * Special version for fixed size types which does not require the size parameter. | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename DenseBase<Derived>::SequentialLinSpacedReturnType | ||||
| DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& high) | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) | ||||
|   return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,false>(low,high,Derived::SizeAtCompileTime)); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   * \brief Sets a linearly space vector. | ||||
|   * | ||||
|   * The function generates 'size' equally spaced values in the closed interval [low,high]. | ||||
|   * When size is set to 1, a vector of length 1 containing 'high' is returned. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * Example: \include DenseBase_LinSpaced.cpp | ||||
|   * Output: \verbinclude DenseBase_LinSpaced.out | ||||
|   * | ||||
|   * \sa setLinSpaced(Index,const Scalar&,const Scalar&), LinSpaced(Sequential_t,Index,const Scalar&,const Scalar&,Index), CwiseNullaryOp | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType | ||||
| DenseBase<Derived>::LinSpaced(Index size, const Scalar& low, const Scalar& high) | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,true>(low,high,size)); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   * \copydoc DenseBase::LinSpaced(Index, const Scalar&, const Scalar&) | ||||
|   * Special version for fixed size types which does not require the size parameter. | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType | ||||
| DenseBase<Derived>::LinSpaced(const Scalar& low, const Scalar& high) | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) | ||||
|   return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,true>(low,high,Derived::SizeAtCompileTime)); | ||||
| } | ||||
|  | ||||
| /** \returns true if all coefficients in this matrix are approximately equal to \a value, to within precision \a prec */ | ||||
| template<typename Derived> | ||||
| bool DenseBase<Derived>::isApproxToConstant | ||||
| (const Scalar& value, RealScalar prec) const | ||||
| { | ||||
|   for(Index j = 0; j < cols(); ++j) | ||||
|     for(Index i = 0; i < rows(); ++i) | ||||
|       if(!internal::isApprox(this->coeff(i, j), value, prec)) | ||||
|         return false; | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| /** This is just an alias for isApproxToConstant(). | ||||
|   * | ||||
|   * \returns true if all coefficients in this matrix are approximately equal to \a value, to within precision \a prec */ | ||||
| template<typename Derived> | ||||
| bool DenseBase<Derived>::isConstant | ||||
| (const Scalar& value, RealScalar prec) const | ||||
| { | ||||
|   return isApproxToConstant(value, prec); | ||||
| } | ||||
|  | ||||
| /** Alias for setConstant(): sets all coefficients in this expression to \a value. | ||||
|   * | ||||
|   * \sa setConstant(), Constant(), class CwiseNullaryOp | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE void DenseBase<Derived>::fill(const Scalar& value) | ||||
| { | ||||
|   setConstant(value); | ||||
| } | ||||
|  | ||||
| /** Sets all coefficients in this expression to \a value. | ||||
|   * | ||||
|   * \sa fill(), setConstant(Index,const Scalar&), setConstant(Index,Index,const Scalar&), setZero(), setOnes(), Constant(), class CwiseNullaryOp, setZero(), setOnes() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setConstant(const Scalar& value) | ||||
| { | ||||
|   return derived() = Constant(rows(), cols(), value); | ||||
| } | ||||
|  | ||||
| /** Resizes to the given \a size, and sets all coefficients in this expression to the given \a value. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * Example: \include Matrix_setConstant_int.cpp | ||||
|   * Output: \verbinclude Matrix_setConstant_int.out | ||||
|   * | ||||
|   * \sa MatrixBase::setConstant(const Scalar&), setConstant(Index,Index,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&) | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE Derived& | ||||
| PlainObjectBase<Derived>::setConstant(Index size, const Scalar& value) | ||||
| { | ||||
|   resize(size); | ||||
|   return setConstant(value); | ||||
| } | ||||
|  | ||||
| /** Resizes to the given size, and sets all coefficients in this expression to the given \a value. | ||||
|   * | ||||
|   * \param rows the new number of rows | ||||
|   * \param cols the new number of columns | ||||
|   * \param value the value to which all coefficients are set | ||||
|   * | ||||
|   * Example: \include Matrix_setConstant_int_int.cpp | ||||
|   * Output: \verbinclude Matrix_setConstant_int_int.out | ||||
|   * | ||||
|   * \sa MatrixBase::setConstant(const Scalar&), setConstant(Index,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&) | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE Derived& | ||||
| PlainObjectBase<Derived>::setConstant(Index rows, Index cols, const Scalar& value) | ||||
| { | ||||
|   resize(rows, cols); | ||||
|   return setConstant(value); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   * \brief Sets a linearly space vector. | ||||
|   * | ||||
|   * The function generates 'size' equally spaced values in the closed interval [low,high]. | ||||
|   * When size is set to 1, a vector of length 1 containing 'high' is returned. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * Example: \include DenseBase_setLinSpaced.cpp | ||||
|   * Output: \verbinclude DenseBase_setLinSpaced.out | ||||
|   * | ||||
|   * \sa CwiseNullaryOp | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index size, const Scalar& low, const Scalar& high) | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   return derived() = Derived::NullaryExpr(size, internal::linspaced_op<Scalar,false>(low,high,size)); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   * \brief Sets a linearly space vector. | ||||
|   * | ||||
|   * The function fill *this with equally spaced values in the closed interval [low,high]. | ||||
|   * When size is set to 1, a vector of length 1 containing 'high' is returned. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * \sa setLinSpaced(Index, const Scalar&, const Scalar&), CwiseNullaryOp | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(const Scalar& low, const Scalar& high) | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   return setLinSpaced(size(), low, high); | ||||
| } | ||||
|  | ||||
| // zero: | ||||
|  | ||||
| /** \returns an expression of a zero matrix. | ||||
|   * | ||||
|   * The parameters \a rows and \a cols are the number of rows and of columns of | ||||
|   * the returned matrix. Must be compatible with this MatrixBase type. | ||||
|   * | ||||
|   * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, | ||||
|   * it is redundant to pass \a rows and \a cols as arguments, so Zero() should be used | ||||
|   * instead. | ||||
|   * | ||||
|   * Example: \include MatrixBase_zero_int_int.cpp | ||||
|   * Output: \verbinclude MatrixBase_zero_int_int.out | ||||
|   * | ||||
|   * \sa Zero(), Zero(Index) | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType | ||||
| DenseBase<Derived>::Zero(Index rows, Index cols) | ||||
| { | ||||
|   return Constant(rows, cols, Scalar(0)); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of a zero vector. | ||||
|   * | ||||
|   * The parameter \a size is the size of the returned vector. | ||||
|   * Must be compatible with this MatrixBase type. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * This variant is meant to be used for dynamic-size vector types. For fixed-size types, | ||||
|   * it is redundant to pass \a size as argument, so Zero() should be used | ||||
|   * instead. | ||||
|   * | ||||
|   * Example: \include MatrixBase_zero_int.cpp | ||||
|   * Output: \verbinclude MatrixBase_zero_int.out | ||||
|   * | ||||
|   * \sa Zero(), Zero(Index,Index) | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType | ||||
| DenseBase<Derived>::Zero(Index size) | ||||
| { | ||||
|   return Constant(size, Scalar(0)); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of a fixed-size zero matrix or vector. | ||||
|   * | ||||
|   * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you | ||||
|   * need to use the variants taking size arguments. | ||||
|   * | ||||
|   * Example: \include MatrixBase_zero.cpp | ||||
|   * Output: \verbinclude MatrixBase_zero.out | ||||
|   * | ||||
|   * \sa Zero(Index), Zero(Index,Index) | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType | ||||
| DenseBase<Derived>::Zero() | ||||
| { | ||||
|   return Constant(Scalar(0)); | ||||
| } | ||||
|  | ||||
| /** \returns true if *this is approximately equal to the zero matrix, | ||||
|   *          within the precision given by \a prec. | ||||
|   * | ||||
|   * Example: \include MatrixBase_isZero.cpp | ||||
|   * Output: \verbinclude MatrixBase_isZero.out | ||||
|   * | ||||
|   * \sa class CwiseNullaryOp, Zero() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| bool DenseBase<Derived>::isZero(RealScalar prec) const | ||||
| { | ||||
|   for(Index j = 0; j < cols(); ++j) | ||||
|     for(Index i = 0; i < rows(); ++i) | ||||
|       if(!internal::isMuchSmallerThan(this->coeff(i, j), static_cast<Scalar>(1), prec)) | ||||
|         return false; | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| /** Sets all coefficients in this expression to zero. | ||||
|   * | ||||
|   * Example: \include MatrixBase_setZero.cpp | ||||
|   * Output: \verbinclude MatrixBase_setZero.out | ||||
|   * | ||||
|   * \sa class CwiseNullaryOp, Zero() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setZero() | ||||
| { | ||||
|   return setConstant(Scalar(0)); | ||||
| } | ||||
|  | ||||
| /** Resizes to the given \a size, and sets all coefficients in this expression to zero. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * Example: \include Matrix_setZero_int.cpp | ||||
|   * Output: \verbinclude Matrix_setZero_int.out | ||||
|   * | ||||
|   * \sa DenseBase::setZero(), setZero(Index,Index), class CwiseNullaryOp, DenseBase::Zero() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE Derived& | ||||
| PlainObjectBase<Derived>::setZero(Index size) | ||||
| { | ||||
|   resize(size); | ||||
|   return setConstant(Scalar(0)); | ||||
| } | ||||
|  | ||||
| /** Resizes to the given size, and sets all coefficients in this expression to zero. | ||||
|   * | ||||
|   * \param rows the new number of rows | ||||
|   * \param cols the new number of columns | ||||
|   * | ||||
|   * Example: \include Matrix_setZero_int_int.cpp | ||||
|   * Output: \verbinclude Matrix_setZero_int_int.out | ||||
|   * | ||||
|   * \sa DenseBase::setZero(), setZero(Index), class CwiseNullaryOp, DenseBase::Zero() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE Derived& | ||||
| PlainObjectBase<Derived>::setZero(Index rows, Index cols) | ||||
| { | ||||
|   resize(rows, cols); | ||||
|   return setConstant(Scalar(0)); | ||||
| } | ||||
|  | ||||
| // ones: | ||||
|  | ||||
| /** \returns an expression of a matrix where all coefficients equal one. | ||||
|   * | ||||
|   * The parameters \a rows and \a cols are the number of rows and of columns of | ||||
|   * the returned matrix. Must be compatible with this MatrixBase type. | ||||
|   * | ||||
|   * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, | ||||
|   * it is redundant to pass \a rows and \a cols as arguments, so Ones() should be used | ||||
|   * instead. | ||||
|   * | ||||
|   * Example: \include MatrixBase_ones_int_int.cpp | ||||
|   * Output: \verbinclude MatrixBase_ones_int_int.out | ||||
|   * | ||||
|   * \sa Ones(), Ones(Index), isOnes(), class Ones | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType | ||||
| DenseBase<Derived>::Ones(Index rows, Index cols) | ||||
| { | ||||
|   return Constant(rows, cols, Scalar(1)); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of a vector where all coefficients equal one. | ||||
|   * | ||||
|   * The parameter \a size is the size of the returned vector. | ||||
|   * Must be compatible with this MatrixBase type. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * This variant is meant to be used for dynamic-size vector types. For fixed-size types, | ||||
|   * it is redundant to pass \a size as argument, so Ones() should be used | ||||
|   * instead. | ||||
|   * | ||||
|   * Example: \include MatrixBase_ones_int.cpp | ||||
|   * Output: \verbinclude MatrixBase_ones_int.out | ||||
|   * | ||||
|   * \sa Ones(), Ones(Index,Index), isOnes(), class Ones | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType | ||||
| DenseBase<Derived>::Ones(Index size) | ||||
| { | ||||
|   return Constant(size, Scalar(1)); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of a fixed-size matrix or vector where all coefficients equal one. | ||||
|   * | ||||
|   * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you | ||||
|   * need to use the variants taking size arguments. | ||||
|   * | ||||
|   * Example: \include MatrixBase_ones.cpp | ||||
|   * Output: \verbinclude MatrixBase_ones.out | ||||
|   * | ||||
|   * \sa Ones(Index), Ones(Index,Index), isOnes(), class Ones | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType | ||||
| DenseBase<Derived>::Ones() | ||||
| { | ||||
|   return Constant(Scalar(1)); | ||||
| } | ||||
|  | ||||
| /** \returns true if *this is approximately equal to the matrix where all coefficients | ||||
|   *          are equal to 1, within the precision given by \a prec. | ||||
|   * | ||||
|   * Example: \include MatrixBase_isOnes.cpp | ||||
|   * Output: \verbinclude MatrixBase_isOnes.out | ||||
|   * | ||||
|   * \sa class CwiseNullaryOp, Ones() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| bool DenseBase<Derived>::isOnes | ||||
| (RealScalar prec) const | ||||
| { | ||||
|   return isApproxToConstant(Scalar(1), prec); | ||||
| } | ||||
|  | ||||
| /** Sets all coefficients in this expression to one. | ||||
|   * | ||||
|   * Example: \include MatrixBase_setOnes.cpp | ||||
|   * Output: \verbinclude MatrixBase_setOnes.out | ||||
|   * | ||||
|   * \sa class CwiseNullaryOp, Ones() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setOnes() | ||||
| { | ||||
|   return setConstant(Scalar(1)); | ||||
| } | ||||
|  | ||||
| /** Resizes to the given \a size, and sets all coefficients in this expression to one. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * Example: \include Matrix_setOnes_int.cpp | ||||
|   * Output: \verbinclude Matrix_setOnes_int.out | ||||
|   * | ||||
|   * \sa MatrixBase::setOnes(), setOnes(Index,Index), class CwiseNullaryOp, MatrixBase::Ones() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE Derived& | ||||
| PlainObjectBase<Derived>::setOnes(Index size) | ||||
| { | ||||
|   resize(size); | ||||
|   return setConstant(Scalar(1)); | ||||
| } | ||||
|  | ||||
| /** Resizes to the given size, and sets all coefficients in this expression to one. | ||||
|   * | ||||
|   * \param rows the new number of rows | ||||
|   * \param cols the new number of columns | ||||
|   * | ||||
|   * Example: \include Matrix_setOnes_int_int.cpp | ||||
|   * Output: \verbinclude Matrix_setOnes_int_int.out | ||||
|   * | ||||
|   * \sa MatrixBase::setOnes(), setOnes(Index), class CwiseNullaryOp, MatrixBase::Ones() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE Derived& | ||||
| PlainObjectBase<Derived>::setOnes(Index rows, Index cols) | ||||
| { | ||||
|   resize(rows, cols); | ||||
|   return setConstant(Scalar(1)); | ||||
| } | ||||
|  | ||||
| // Identity: | ||||
|  | ||||
| /** \returns an expression of the identity matrix (not necessarily square). | ||||
|   * | ||||
|   * The parameters \a rows and \a cols are the number of rows and of columns of | ||||
|   * the returned matrix. Must be compatible with this MatrixBase type. | ||||
|   * | ||||
|   * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, | ||||
|   * it is redundant to pass \a rows and \a cols as arguments, so Identity() should be used | ||||
|   * instead. | ||||
|   * | ||||
|   * Example: \include MatrixBase_identity_int_int.cpp | ||||
|   * Output: \verbinclude MatrixBase_identity_int_int.out | ||||
|   * | ||||
|   * \sa Identity(), setIdentity(), isIdentity() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType | ||||
| MatrixBase<Derived>::Identity(Index rows, Index cols) | ||||
| { | ||||
|   return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_identity_op<Scalar>()); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of the identity matrix (not necessarily square). | ||||
|   * | ||||
|   * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you | ||||
|   * need to use the variant taking size arguments. | ||||
|   * | ||||
|   * Example: \include MatrixBase_identity.cpp | ||||
|   * Output: \verbinclude MatrixBase_identity.out | ||||
|   * | ||||
|   * \sa Identity(Index,Index), setIdentity(), isIdentity() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType | ||||
| MatrixBase<Derived>::Identity() | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) | ||||
|   return MatrixBase<Derived>::NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_identity_op<Scalar>()); | ||||
| } | ||||
|  | ||||
| /** \returns true if *this is approximately equal to the identity matrix | ||||
|   *          (not necessarily square), | ||||
|   *          within the precision given by \a prec. | ||||
|   * | ||||
|   * Example: \include MatrixBase_isIdentity.cpp | ||||
|   * Output: \verbinclude MatrixBase_isIdentity.out | ||||
|   * | ||||
|   * \sa class CwiseNullaryOp, Identity(), Identity(Index,Index), setIdentity() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| bool MatrixBase<Derived>::isIdentity | ||||
| (RealScalar prec) const | ||||
| { | ||||
|   for(Index j = 0; j < cols(); ++j) | ||||
|   { | ||||
|     for(Index i = 0; i < rows(); ++i) | ||||
|     { | ||||
|       if(i == j) | ||||
|       { | ||||
|         if(!internal::isApprox(this->coeff(i, j), static_cast<Scalar>(1), prec)) | ||||
|           return false; | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|         if(!internal::isMuchSmallerThan(this->coeff(i, j), static_cast<RealScalar>(1), prec)) | ||||
|           return false; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename Derived, bool Big = (Derived::SizeAtCompileTime>=16)> | ||||
| struct setIdentity_impl | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE Derived& run(Derived& m) | ||||
|   { | ||||
|     return m = Derived::Identity(m.rows(), m.cols()); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived> | ||||
| struct setIdentity_impl<Derived, true> | ||||
| { | ||||
|   typedef typename Derived::Index Index; | ||||
|   static EIGEN_STRONG_INLINE Derived& run(Derived& m) | ||||
|   { | ||||
|     m.setZero(); | ||||
|     const Index size = (std::min)(m.rows(), m.cols()); | ||||
|     for(Index i = 0; i < size; ++i) m.coeffRef(i,i) = typename Derived::Scalar(1); | ||||
|     return m; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /** Writes the identity expression (not necessarily square) into *this. | ||||
|   * | ||||
|   * Example: \include MatrixBase_setIdentity.cpp | ||||
|   * Output: \verbinclude MatrixBase_setIdentity.out | ||||
|   * | ||||
|   * \sa class CwiseNullaryOp, Identity(), Identity(Index,Index), isIdentity() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity() | ||||
| { | ||||
|   return internal::setIdentity_impl<Derived>::run(derived()); | ||||
| } | ||||
|  | ||||
| /** \brief Resizes to the given size, and writes the identity expression (not necessarily square) into *this. | ||||
|   * | ||||
|   * \param rows the new number of rows | ||||
|   * \param cols the new number of columns | ||||
|   * | ||||
|   * Example: \include Matrix_setIdentity_int_int.cpp | ||||
|   * Output: \verbinclude Matrix_setIdentity_int_int.out | ||||
|   * | ||||
|   * \sa MatrixBase::setIdentity(), class CwiseNullaryOp, MatrixBase::Identity() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity(Index rows, Index cols) | ||||
| { | ||||
|   derived().resize(rows, cols); | ||||
|   return setIdentity(); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of the i-th unit (basis) vector. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * \sa MatrixBase::Unit(Index), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index size, Index i) | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   return BasisReturnType(SquareMatrixType::Identity(size,size), i); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of the i-th unit (basis) vector. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * This variant is for fixed-size vector only. | ||||
|   * | ||||
|   * \sa MatrixBase::Unit(Index,Index), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index i) | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   return BasisReturnType(SquareMatrixType::Identity(),i); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of the X axis unit vector (1{,0}^*) | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitX() | ||||
| { return Derived::Unit(0); } | ||||
|  | ||||
| /** \returns an expression of the Y axis unit vector (0,1{,0}^*) | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitY() | ||||
| { return Derived::Unit(1); } | ||||
|  | ||||
| /** \returns an expression of the Z axis unit vector (0,0,1{,0}^*) | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitZ() | ||||
| { return Derived::Unit(2); } | ||||
|  | ||||
| /** \returns an expression of the W axis unit vector (0,0,0,1) | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitW() | ||||
| { return Derived::Unit(3); } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_CWISE_NULLARY_OP_H | ||||
							
								
								
									
										126
									
								
								latan/Eigen/src/Core/CwiseUnaryOp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								latan/Eigen/src/Core/CwiseUnaryOp.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_CWISE_UNARY_OP_H | ||||
| #define EIGEN_CWISE_UNARY_OP_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class CwiseUnaryOp | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Generic expression where a coefficient-wise unary operator is applied to an expression | ||||
|   * | ||||
|   * \param UnaryOp template functor implementing the operator | ||||
|   * \param XprType the type of the expression to which we are applying the unary operator | ||||
|   * | ||||
|   * This class represents an expression where a unary operator is applied to an expression. | ||||
|   * It is the return type of all operations taking exactly 1 input expression, regardless of the | ||||
|   * presence of other inputs such as scalars. For example, the operator* in the expression 3*matrix | ||||
|   * is considered unary, because only the right-hand side is an expression, and its | ||||
|   * return type is a specialization of CwiseUnaryOp. | ||||
|   * | ||||
|   * Most of the time, this is the only way that it is used, so you typically don't have to name | ||||
|   * CwiseUnaryOp types explicitly. | ||||
|   * | ||||
|   * \sa MatrixBase::unaryExpr(const CustomUnaryOp &) const, class CwiseBinaryOp, class CwiseNullaryOp | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename UnaryOp, typename XprType> | ||||
| struct traits<CwiseUnaryOp<UnaryOp, XprType> > | ||||
|  : traits<XprType> | ||||
| { | ||||
|   typedef typename result_of< | ||||
|                      UnaryOp(typename XprType::Scalar) | ||||
|                    >::type Scalar; | ||||
|   typedef typename XprType::Nested XprTypeNested; | ||||
|   typedef typename remove_reference<XprTypeNested>::type _XprTypeNested; | ||||
|   enum { | ||||
|     Flags = _XprTypeNested::Flags & ( | ||||
|       HereditaryBits | LinearAccessBit | AlignedBit | ||||
|       | (functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0)), | ||||
|     CoeffReadCost = _XprTypeNested::CoeffReadCost + functor_traits<UnaryOp>::Cost | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename UnaryOp, typename XprType, typename StorageKind> | ||||
| class CwiseUnaryOpImpl; | ||||
|  | ||||
| template<typename UnaryOp, typename XprType> | ||||
| class CwiseUnaryOp : internal::no_assignment_operator, | ||||
|   public CwiseUnaryOpImpl<UnaryOp, XprType, typename internal::traits<XprType>::StorageKind> | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef typename CwiseUnaryOpImpl<UnaryOp, XprType,typename internal::traits<XprType>::StorageKind>::Base Base; | ||||
|     EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryOp) | ||||
|  | ||||
|     inline CwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp()) | ||||
|       : m_xpr(xpr), m_functor(func) {} | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Index rows() const { return m_xpr.rows(); } | ||||
|     EIGEN_STRONG_INLINE Index cols() const { return m_xpr.cols(); } | ||||
|  | ||||
|     /** \returns the functor representing the unary operation */ | ||||
|     const UnaryOp& functor() const { return m_functor; } | ||||
|  | ||||
|     /** \returns the nested expression */ | ||||
|     const typename internal::remove_all<typename XprType::Nested>::type& | ||||
|     nestedExpression() const { return m_xpr; } | ||||
|  | ||||
|     /** \returns the nested expression */ | ||||
|     typename internal::remove_all<typename XprType::Nested>::type& | ||||
|     nestedExpression() { return m_xpr.const_cast_derived(); } | ||||
|  | ||||
|   protected: | ||||
|     typename XprType::Nested m_xpr; | ||||
|     const UnaryOp m_functor; | ||||
| }; | ||||
|  | ||||
| // This is the generic implementation for dense storage. | ||||
| // It can be used for any expression types implementing the dense concept. | ||||
| template<typename UnaryOp, typename XprType> | ||||
| class CwiseUnaryOpImpl<UnaryOp,XprType,Dense> | ||||
|   : public internal::dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef CwiseUnaryOp<UnaryOp, XprType> Derived; | ||||
|     typedef typename internal::dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(Derived) | ||||
|  | ||||
|     EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const | ||||
|     { | ||||
|       return derived().functor()(derived().nestedExpression().coeff(row, col)); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const | ||||
|     { | ||||
|       return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(row, col)); | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE const Scalar coeff(Index index) const | ||||
|     { | ||||
|       return derived().functor()(derived().nestedExpression().coeff(index)); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     EIGEN_STRONG_INLINE PacketScalar packet(Index index) const | ||||
|     { | ||||
|       return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(index)); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_CWISE_UNARY_OP_H | ||||
							
								
								
									
										136
									
								
								latan/Eigen/src/Core/CwiseUnaryView.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								latan/Eigen/src/Core/CwiseUnaryView.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,136 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_CWISE_UNARY_VIEW_H | ||||
| #define EIGEN_CWISE_UNARY_VIEW_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| /** \class CwiseUnaryView | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Generic lvalue expression of a coefficient-wise unary operator of a matrix or a vector | ||||
|   * | ||||
|   * \param ViewOp template functor implementing the view | ||||
|   * \param MatrixType the type of the matrix we are applying the unary operator | ||||
|   * | ||||
|   * This class represents a lvalue expression of a generic unary view operator of a matrix or a vector. | ||||
|   * It is the return type of real() and imag(), and most of the time this is the only way it is used. | ||||
|   * | ||||
|   * \sa MatrixBase::unaryViewExpr(const CustomUnaryOp &) const, class CwiseUnaryOp | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename ViewOp, typename MatrixType> | ||||
| struct traits<CwiseUnaryView<ViewOp, MatrixType> > | ||||
|  : traits<MatrixType> | ||||
| { | ||||
|   typedef typename result_of< | ||||
|                      ViewOp(typename traits<MatrixType>::Scalar) | ||||
|                    >::type Scalar; | ||||
|   typedef typename MatrixType::Nested MatrixTypeNested; | ||||
|   typedef typename remove_all<MatrixTypeNested>::type _MatrixTypeNested; | ||||
|   enum { | ||||
|     Flags = (traits<_MatrixTypeNested>::Flags & (HereditaryBits | LvalueBit | LinearAccessBit | DirectAccessBit)), | ||||
|     CoeffReadCost = traits<_MatrixTypeNested>::CoeffReadCost + functor_traits<ViewOp>::Cost, | ||||
|     MatrixTypeInnerStride =  inner_stride_at_compile_time<MatrixType>::ret, | ||||
|     // need to cast the sizeof's from size_t to int explicitly, otherwise: | ||||
|     // "error: no integral type can represent all of the enumerator values | ||||
|     InnerStrideAtCompileTime = MatrixTypeInnerStride == Dynamic | ||||
|                              ? int(Dynamic) | ||||
|                              : int(MatrixTypeInnerStride) * int(sizeof(typename traits<MatrixType>::Scalar) / sizeof(Scalar)), | ||||
|     OuterStrideAtCompileTime = outer_stride_at_compile_time<MatrixType>::ret == Dynamic | ||||
|                              ? int(Dynamic) | ||||
|                              : outer_stride_at_compile_time<MatrixType>::ret * int(sizeof(typename traits<MatrixType>::Scalar) / sizeof(Scalar)) | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename ViewOp, typename MatrixType, typename StorageKind> | ||||
| class CwiseUnaryViewImpl; | ||||
|  | ||||
| template<typename ViewOp, typename MatrixType> | ||||
| class CwiseUnaryView : internal::no_assignment_operator, | ||||
|   public CwiseUnaryViewImpl<ViewOp, MatrixType, typename internal::traits<MatrixType>::StorageKind> | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef typename CwiseUnaryViewImpl<ViewOp, MatrixType,typename internal::traits<MatrixType>::StorageKind>::Base Base; | ||||
|     EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryView) | ||||
|  | ||||
|     inline CwiseUnaryView(const MatrixType& mat, const ViewOp& func = ViewOp()) | ||||
|       : m_matrix(mat), m_functor(func) {} | ||||
|  | ||||
|     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryView) | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Index rows() const { return m_matrix.rows(); } | ||||
|     EIGEN_STRONG_INLINE Index cols() const { return m_matrix.cols(); } | ||||
|  | ||||
|     /** \returns the functor representing unary operation */ | ||||
|     const ViewOp& functor() const { return m_functor; } | ||||
|  | ||||
|     /** \returns the nested expression */ | ||||
|     const typename internal::remove_all<typename MatrixType::Nested>::type& | ||||
|     nestedExpression() const { return m_matrix; } | ||||
|  | ||||
|     /** \returns the nested expression */ | ||||
|     typename internal::remove_all<typename MatrixType::Nested>::type& | ||||
|     nestedExpression() { return m_matrix.const_cast_derived(); } | ||||
|  | ||||
|   protected: | ||||
|     // FIXME changed from MatrixType::Nested because of a weird compilation error with sun CC | ||||
|     typename internal::nested<MatrixType>::type m_matrix; | ||||
|     ViewOp m_functor; | ||||
| }; | ||||
|  | ||||
| template<typename ViewOp, typename MatrixType> | ||||
| class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense> | ||||
|   : public internal::dense_xpr_base< CwiseUnaryView<ViewOp, MatrixType> >::type | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef CwiseUnaryView<ViewOp, MatrixType> Derived; | ||||
|     typedef typename internal::dense_xpr_base< CwiseUnaryView<ViewOp, MatrixType> >::type Base; | ||||
|  | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(Derived) | ||||
|  | ||||
|     inline Index innerStride() const | ||||
|     { | ||||
|       return derived().nestedExpression().innerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar); | ||||
|     } | ||||
|  | ||||
|     inline Index outerStride() const | ||||
|     { | ||||
|       return derived().nestedExpression().outerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar); | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const | ||||
|     { | ||||
|       return derived().functor()(derived().nestedExpression().coeff(row, col)); | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const | ||||
|     { | ||||
|       return derived().functor()(derived().nestedExpression().coeff(index)); | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col) | ||||
|     { | ||||
|       return derived().functor()(const_cast_derived().nestedExpression().coeffRef(row, col)); | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) | ||||
|     { | ||||
|       return derived().functor()(const_cast_derived().nestedExpression().coeffRef(index)); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_CWISE_UNARY_VIEW_H | ||||
							
								
								
									
										533
									
								
								latan/Eigen/src/Core/DenseBase.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										533
									
								
								latan/Eigen/src/Core/DenseBase.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,533 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_DENSEBASE_H | ||||
| #define EIGEN_DENSEBASE_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| /** \class DenseBase | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Base class for all dense matrices, vectors, and arrays | ||||
|   * | ||||
|   * This class is the base that is inherited by all dense objects (matrix, vector, arrays, | ||||
|   * and related expression types). The common Eigen API for dense objects is contained in this class. | ||||
|   * | ||||
|   * \tparam Derived is the derived type, e.g., a matrix type or an expression. | ||||
|   * | ||||
|   * This class can be extended with the help of the plugin mechanism described on the page | ||||
|   * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_DENSEBASE_PLUGIN. | ||||
|   * | ||||
|   * \sa \ref TopicClassHierarchy | ||||
|   */ | ||||
| template<typename Derived> class DenseBase | ||||
| #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|   : public internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar, | ||||
|                                      typename NumTraits<typename internal::traits<Derived>::Scalar>::Real> | ||||
| #else | ||||
|   : public DenseCoeffsBase<Derived> | ||||
| #endif // not EIGEN_PARSED_BY_DOXYGEN | ||||
| { | ||||
|   public: | ||||
|     using internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar, | ||||
|                 typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>::operator*; | ||||
|  | ||||
|     class InnerIterator; | ||||
|  | ||||
|     typedef typename internal::traits<Derived>::StorageKind StorageKind; | ||||
|  | ||||
|     /** \brief The type of indices  | ||||
|       * \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE. | ||||
|       * \sa \ref TopicPreprocessorDirectives. | ||||
|       */ | ||||
|     typedef typename internal::traits<Derived>::Index Index;  | ||||
|  | ||||
|     typedef typename internal::traits<Derived>::Scalar Scalar; | ||||
|     typedef typename internal::packet_traits<Scalar>::type PacketScalar; | ||||
|     typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|  | ||||
|     typedef DenseCoeffsBase<Derived> Base; | ||||
|     using Base::derived; | ||||
|     using Base::const_cast_derived; | ||||
|     using Base::rows; | ||||
|     using Base::cols; | ||||
|     using Base::size; | ||||
|     using Base::rowIndexByOuterInner; | ||||
|     using Base::colIndexByOuterInner; | ||||
|     using Base::coeff; | ||||
|     using Base::coeffByOuterInner; | ||||
|     using Base::packet; | ||||
|     using Base::packetByOuterInner; | ||||
|     using Base::writePacket; | ||||
|     using Base::writePacketByOuterInner; | ||||
|     using Base::coeffRef; | ||||
|     using Base::coeffRefByOuterInner; | ||||
|     using Base::copyCoeff; | ||||
|     using Base::copyCoeffByOuterInner; | ||||
|     using Base::copyPacket; | ||||
|     using Base::copyPacketByOuterInner; | ||||
|     using Base::operator(); | ||||
|     using Base::operator[]; | ||||
|     using Base::x; | ||||
|     using Base::y; | ||||
|     using Base::z; | ||||
|     using Base::w; | ||||
|     using Base::stride; | ||||
|     using Base::innerStride; | ||||
|     using Base::outerStride; | ||||
|     using Base::rowStride; | ||||
|     using Base::colStride; | ||||
|     typedef typename Base::CoeffReturnType CoeffReturnType; | ||||
|  | ||||
|     enum { | ||||
|  | ||||
|       RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime, | ||||
|         /**< The number of rows at compile-time. This is just a copy of the value provided | ||||
|           * by the \a Derived type. If a value is not known at compile-time, | ||||
|           * it is set to the \a Dynamic constant. | ||||
|           * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */ | ||||
|  | ||||
|       ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime, | ||||
|         /**< The number of columns at compile-time. This is just a copy of the value provided | ||||
|           * by the \a Derived type. If a value is not known at compile-time, | ||||
|           * it is set to the \a Dynamic constant. | ||||
|           * \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */ | ||||
|  | ||||
|  | ||||
|       SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime, | ||||
|                                                    internal::traits<Derived>::ColsAtCompileTime>::ret), | ||||
|         /**< This is equal to the number of coefficients, i.e. the number of | ||||
|           * rows times the number of columns, or to \a Dynamic if this is not | ||||
|           * known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */ | ||||
|  | ||||
|       MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime, | ||||
|         /**< This value is equal to the maximum possible number of rows that this expression | ||||
|           * might have. If this expression might have an arbitrarily high number of rows, | ||||
|           * this value is set to \a Dynamic. | ||||
|           * | ||||
|           * This value is useful to know when evaluating an expression, in order to determine | ||||
|           * whether it is possible to avoid doing a dynamic memory allocation. | ||||
|           * | ||||
|           * \sa RowsAtCompileTime, MaxColsAtCompileTime, MaxSizeAtCompileTime | ||||
|           */ | ||||
|  | ||||
|       MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime, | ||||
|         /**< This value is equal to the maximum possible number of columns that this expression | ||||
|           * might have. If this expression might have an arbitrarily high number of columns, | ||||
|           * this value is set to \a Dynamic. | ||||
|           * | ||||
|           * This value is useful to know when evaluating an expression, in order to determine | ||||
|           * whether it is possible to avoid doing a dynamic memory allocation. | ||||
|           * | ||||
|           * \sa ColsAtCompileTime, MaxRowsAtCompileTime, MaxSizeAtCompileTime | ||||
|           */ | ||||
|  | ||||
|       MaxSizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::MaxRowsAtCompileTime, | ||||
|                                                       internal::traits<Derived>::MaxColsAtCompileTime>::ret), | ||||
|         /**< This value is equal to the maximum possible number of coefficients that this expression | ||||
|           * might have. If this expression might have an arbitrarily high number of coefficients, | ||||
|           * this value is set to \a Dynamic. | ||||
|           * | ||||
|           * This value is useful to know when evaluating an expression, in order to determine | ||||
|           * whether it is possible to avoid doing a dynamic memory allocation. | ||||
|           * | ||||
|           * \sa SizeAtCompileTime, MaxRowsAtCompileTime, MaxColsAtCompileTime | ||||
|           */ | ||||
|  | ||||
|       IsVectorAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime == 1 | ||||
|                            || internal::traits<Derived>::MaxColsAtCompileTime == 1, | ||||
|         /**< This is set to true if either the number of rows or the number of | ||||
|           * columns is known at compile-time to be equal to 1. Indeed, in that case, | ||||
|           * we are dealing with a column-vector (if there is only one column) or with | ||||
|           * a row-vector (if there is only one row). */ | ||||
|  | ||||
|       Flags = internal::traits<Derived>::Flags, | ||||
|         /**< This stores expression \ref flags flags which may or may not be inherited by new expressions | ||||
|           * constructed from this one. See the \ref flags "list of flags". | ||||
|           */ | ||||
|  | ||||
|       IsRowMajor = int(Flags) & RowMajorBit, /**< True if this expression has row-major storage order. */ | ||||
|  | ||||
|       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 | ||||
|           * this expression. | ||||
|           */ | ||||
|  | ||||
|       InnerStrideAtCompileTime = internal::inner_stride_at_compile_time<Derived>::ret, | ||||
|       OuterStrideAtCompileTime = internal::outer_stride_at_compile_time<Derived>::ret | ||||
|     }; | ||||
|  | ||||
|     enum { ThisConstantIsPrivateInPlainObjectBase }; | ||||
|  | ||||
|     /** \returns the number of nonzero coefficients which is in practice the number | ||||
|       * of stored coefficients. */ | ||||
|     inline Index nonZeros() const { return size(); } | ||||
|     /** \returns true if either the number of rows or the number of columns is equal to 1. | ||||
|       * In other words, this function returns | ||||
|       * \code rows()==1 || cols()==1 \endcode | ||||
|       * \sa rows(), cols(), IsVectorAtCompileTime. */ | ||||
|  | ||||
|     /** \returns the outer size. | ||||
|       * | ||||
|       * \note For a vector, this returns just 1. For a matrix (non-vector), this is the major dimension | ||||
|       * with respect to the \ref TopicStorageOrders "storage order", i.e., the number of columns for a | ||||
|       * column-major matrix, and the number of rows for a row-major matrix. */ | ||||
|     Index outerSize() const | ||||
|     { | ||||
|       return IsVectorAtCompileTime ? 1 | ||||
|            : int(IsRowMajor) ? this->rows() : this->cols(); | ||||
|     } | ||||
|  | ||||
|     /** \returns the inner size. | ||||
|       * | ||||
|       * \note For a vector, this is just the size. For a matrix (non-vector), this is the minor dimension | ||||
|       * with respect to the \ref TopicStorageOrders "storage order", i.e., the number of rows for a  | ||||
|       * column-major matrix, and the number of columns for a row-major matrix. */ | ||||
|     Index innerSize() const | ||||
|     { | ||||
|       return IsVectorAtCompileTime ? this->size() | ||||
|            : int(IsRowMajor) ? this->cols() : this->rows(); | ||||
|     } | ||||
|  | ||||
|     /** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are | ||||
|       * Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does | ||||
|       * nothing else. | ||||
|       */ | ||||
|     void resize(Index size) | ||||
|     { | ||||
|       EIGEN_ONLY_USED_FOR_DEBUG(size); | ||||
|       eigen_assert(size == this->size() | ||||
|                 && "DenseBase::resize() does not actually allow to resize."); | ||||
|     } | ||||
|     /** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are | ||||
|       * Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does | ||||
|       * nothing else. | ||||
|       */ | ||||
|     void resize(Index rows, Index cols) | ||||
|     { | ||||
|       EIGEN_ONLY_USED_FOR_DEBUG(rows); | ||||
|       EIGEN_ONLY_USED_FOR_DEBUG(cols); | ||||
|       eigen_assert(rows == this->rows() && cols == this->cols() | ||||
|                 && "DenseBase::resize() does not actually allow to resize."); | ||||
|     } | ||||
|  | ||||
| #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|  | ||||
|     /** \internal Represents a matrix with all coefficients equal to one another*/ | ||||
|     typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Derived> ConstantReturnType; | ||||
|     /** \internal Represents a vector with linearly spaced coefficients that allows sequential access only. */ | ||||
|     typedef CwiseNullaryOp<internal::linspaced_op<Scalar,false>,Derived> SequentialLinSpacedReturnType; | ||||
|     /** \internal Represents a vector with linearly spaced coefficients that allows random access. */ | ||||
|     typedef CwiseNullaryOp<internal::linspaced_op<Scalar,true>,Derived> RandomAccessLinSpacedReturnType; | ||||
|     /** \internal the return type of MatrixBase::eigenvalues() */ | ||||
|     typedef Matrix<typename NumTraits<typename internal::traits<Derived>::Scalar>::Real, internal::traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType; | ||||
|  | ||||
| #endif // not EIGEN_PARSED_BY_DOXYGEN | ||||
|  | ||||
|     /** Copies \a other into *this. \returns a reference to *this. */ | ||||
|     template<typename OtherDerived> | ||||
|     Derived& operator=(const DenseBase<OtherDerived>& other); | ||||
|  | ||||
|     /** Special case of the template operator=, in order to prevent the compiler | ||||
|       * from generating a default operator= (issue hit with g++ 4.1) | ||||
|       */ | ||||
|     Derived& operator=(const DenseBase& other); | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     Derived& operator=(const EigenBase<OtherDerived> &other); | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     Derived& operator+=(const EigenBase<OtherDerived> &other); | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     Derived& operator-=(const EigenBase<OtherDerived> &other); | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     Derived& operator=(const ReturnByValue<OtherDerived>& func); | ||||
|  | ||||
| #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /** Copies \a other into *this without evaluating other. \returns a reference to *this. */ | ||||
|     template<typename OtherDerived> | ||||
|     Derived& lazyAssign(const DenseBase<OtherDerived>& other); | ||||
| #endif // not EIGEN_PARSED_BY_DOXYGEN | ||||
|  | ||||
|     CommaInitializer<Derived> operator<< (const Scalar& s); | ||||
|  | ||||
|     template<unsigned int Added,unsigned int Removed> | ||||
|     const Flagged<Derived, Added, Removed> flagged() const; | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     CommaInitializer<Derived> operator<< (const DenseBase<OtherDerived>& other); | ||||
|  | ||||
|     Eigen::Transpose<Derived> transpose(); | ||||
|     typedef const Transpose<const Derived> ConstTransposeReturnType; | ||||
|     ConstTransposeReturnType transpose() const; | ||||
|     void transposeInPlace(); | ||||
| #ifndef EIGEN_NO_DEBUG | ||||
|   protected: | ||||
|     template<typename OtherDerived> | ||||
|     void checkTransposeAliasing(const OtherDerived& other) const; | ||||
|   public: | ||||
| #endif | ||||
|  | ||||
|     typedef VectorBlock<Derived> SegmentReturnType; | ||||
|     typedef const VectorBlock<const Derived> ConstSegmentReturnType; | ||||
|     template<int Size> struct FixedSegmentReturnType { typedef VectorBlock<Derived, Size> Type; }; | ||||
|     template<int Size> struct ConstFixedSegmentReturnType { typedef const VectorBlock<const Derived, Size> Type; }; | ||||
|      | ||||
|     // Note: The "DenseBase::" prefixes are added to help MSVC9 to match these declarations with the later implementations. | ||||
|     SegmentReturnType segment(Index start, Index size); | ||||
|     typename DenseBase::ConstSegmentReturnType segment(Index start, Index size) const; | ||||
|  | ||||
|     SegmentReturnType head(Index size); | ||||
|     typename DenseBase::ConstSegmentReturnType head(Index size) const; | ||||
|  | ||||
|     SegmentReturnType tail(Index size); | ||||
|     typename DenseBase::ConstSegmentReturnType tail(Index size) const; | ||||
|  | ||||
|     template<int Size> typename FixedSegmentReturnType<Size>::Type head(); | ||||
|     template<int Size> typename ConstFixedSegmentReturnType<Size>::Type head() const; | ||||
|  | ||||
|     template<int Size> typename FixedSegmentReturnType<Size>::Type tail(); | ||||
|     template<int Size> typename ConstFixedSegmentReturnType<Size>::Type tail() const; | ||||
|  | ||||
|     template<int Size> typename FixedSegmentReturnType<Size>::Type segment(Index start); | ||||
|     template<int Size> typename ConstFixedSegmentReturnType<Size>::Type segment(Index start) const; | ||||
|  | ||||
|     static const ConstantReturnType | ||||
|     Constant(Index rows, Index cols, const Scalar& value); | ||||
|     static const ConstantReturnType | ||||
|     Constant(Index size, const Scalar& value); | ||||
|     static const ConstantReturnType | ||||
|     Constant(const Scalar& value); | ||||
|  | ||||
|     static const SequentialLinSpacedReturnType | ||||
|     LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high); | ||||
|     static const RandomAccessLinSpacedReturnType | ||||
|     LinSpaced(Index size, const Scalar& low, const Scalar& high); | ||||
|     static const SequentialLinSpacedReturnType | ||||
|     LinSpaced(Sequential_t, const Scalar& low, const Scalar& high); | ||||
|     static const RandomAccessLinSpacedReturnType | ||||
|     LinSpaced(const Scalar& low, const Scalar& high); | ||||
|  | ||||
|     template<typename CustomNullaryOp> | ||||
|     static const CwiseNullaryOp<CustomNullaryOp, Derived> | ||||
|     NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func); | ||||
|     template<typename CustomNullaryOp> | ||||
|     static const CwiseNullaryOp<CustomNullaryOp, Derived> | ||||
|     NullaryExpr(Index size, const CustomNullaryOp& func); | ||||
|     template<typename CustomNullaryOp> | ||||
|     static const CwiseNullaryOp<CustomNullaryOp, Derived> | ||||
|     NullaryExpr(const CustomNullaryOp& func); | ||||
|  | ||||
|     static const ConstantReturnType Zero(Index rows, Index cols); | ||||
|     static const ConstantReturnType Zero(Index size); | ||||
|     static const ConstantReturnType Zero(); | ||||
|     static const ConstantReturnType Ones(Index rows, Index cols); | ||||
|     static const ConstantReturnType Ones(Index size); | ||||
|     static const ConstantReturnType Ones(); | ||||
|  | ||||
|     void fill(const Scalar& value); | ||||
|     Derived& setConstant(const Scalar& value); | ||||
|     Derived& setLinSpaced(Index size, const Scalar& low, const Scalar& high); | ||||
|     Derived& setLinSpaced(const Scalar& low, const Scalar& high); | ||||
|     Derived& setZero(); | ||||
|     Derived& setOnes(); | ||||
|     Derived& setRandom(); | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     bool isApprox(const DenseBase<OtherDerived>& other, | ||||
|                   RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; | ||||
|     bool isMuchSmallerThan(const RealScalar& other, | ||||
|                            RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; | ||||
|     template<typename OtherDerived> | ||||
|     bool isMuchSmallerThan(const DenseBase<OtherDerived>& other, | ||||
|                            RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; | ||||
|  | ||||
|     bool isApproxToConstant(const Scalar& value, RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; | ||||
|     bool isConstant(const Scalar& value, RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; | ||||
|     bool isZero(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; | ||||
|     bool isOnes(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; | ||||
|  | ||||
|     inline Derived& operator*=(const Scalar& other); | ||||
|     inline Derived& operator/=(const Scalar& other); | ||||
|  | ||||
|     typedef typename internal::add_const_on_value_type<typename internal::eval<Derived>::type>::type EvalReturnType; | ||||
|     /** \returns the matrix or vector obtained by evaluating this expression. | ||||
|       * | ||||
|       * Notice that in the case of a plain matrix or vector (not an expression) this function just returns | ||||
|       * a const reference, in order to avoid a useless copy. | ||||
|       */ | ||||
|     EIGEN_STRONG_INLINE EvalReturnType eval() const | ||||
|     { | ||||
|       // Even though MSVC does not honor strong inlining when the return type | ||||
|       // is a dynamic matrix, we desperately need strong inlining for fixed | ||||
|       // size types on MSVC. | ||||
|       return typename internal::eval<Derived>::type(derived()); | ||||
|     } | ||||
|  | ||||
|     /** swaps *this with the expression \a other. | ||||
|       * | ||||
|       */ | ||||
|     template<typename OtherDerived> | ||||
|     void swap(const DenseBase<OtherDerived>& other, | ||||
|               int = OtherDerived::ThisConstantIsPrivateInPlainObjectBase) | ||||
|     { | ||||
|       SwapWrapper<Derived>(derived()).lazyAssign(other.derived()); | ||||
|     } | ||||
|  | ||||
|     /** swaps *this with the matrix or array \a other. | ||||
|       * | ||||
|       */ | ||||
|     template<typename OtherDerived> | ||||
|     void swap(PlainObjectBase<OtherDerived>& other) | ||||
|     { | ||||
|       SwapWrapper<Derived>(derived()).lazyAssign(other.derived()); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     inline const NestByValue<Derived> nestByValue() const; | ||||
|     inline const ForceAlignedAccess<Derived> forceAlignedAccess() const; | ||||
|     inline ForceAlignedAccess<Derived> forceAlignedAccess(); | ||||
|     template<bool Enable> inline const typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf() const; | ||||
|     template<bool Enable> inline typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf(); | ||||
|  | ||||
|     Scalar sum() const; | ||||
|     Scalar mean() const; | ||||
|     Scalar trace() const; | ||||
|  | ||||
|     Scalar prod() const; | ||||
|  | ||||
|     typename internal::traits<Derived>::Scalar minCoeff() const; | ||||
|     typename internal::traits<Derived>::Scalar maxCoeff() const; | ||||
|  | ||||
|     template<typename IndexType> | ||||
|     typename internal::traits<Derived>::Scalar minCoeff(IndexType* row, IndexType* col) const; | ||||
|     template<typename IndexType> | ||||
|     typename internal::traits<Derived>::Scalar maxCoeff(IndexType* row, IndexType* col) const; | ||||
|     template<typename IndexType> | ||||
|     typename internal::traits<Derived>::Scalar minCoeff(IndexType* index) const; | ||||
|     template<typename IndexType> | ||||
|     typename internal::traits<Derived>::Scalar maxCoeff(IndexType* index) const; | ||||
|  | ||||
|     template<typename BinaryOp> | ||||
|     typename internal::result_of<BinaryOp(typename internal::traits<Derived>::Scalar)>::type | ||||
|     redux(const BinaryOp& func) const; | ||||
|  | ||||
|     template<typename Visitor> | ||||
|     void visit(Visitor& func) const; | ||||
|  | ||||
|     inline const WithFormat<Derived> format(const IOFormat& fmt) const; | ||||
|  | ||||
|     /** \returns the unique coefficient of a 1x1 expression */ | ||||
|     CoeffReturnType value() const | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_SIZE_1x1(Derived) | ||||
|       eigen_assert(this->rows() == 1 && this->cols() == 1); | ||||
|       return derived().coeff(0,0); | ||||
|     } | ||||
|  | ||||
| /////////// Array module /////////// | ||||
|  | ||||
|     bool all(void) const; | ||||
|     bool any(void) const; | ||||
|     Index count() const; | ||||
|  | ||||
|     typedef VectorwiseOp<Derived, Horizontal> RowwiseReturnType; | ||||
|     typedef const VectorwiseOp<const Derived, Horizontal> ConstRowwiseReturnType; | ||||
|     typedef VectorwiseOp<Derived, Vertical> ColwiseReturnType; | ||||
|     typedef const VectorwiseOp<const Derived, Vertical> ConstColwiseReturnType; | ||||
|  | ||||
|     ConstRowwiseReturnType rowwise() const; | ||||
|     RowwiseReturnType rowwise(); | ||||
|     ConstColwiseReturnType colwise() const; | ||||
|     ColwiseReturnType colwise(); | ||||
|  | ||||
|     static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random(Index rows, Index cols); | ||||
|     static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random(Index size); | ||||
|     static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random(); | ||||
|  | ||||
|     template<typename ThenDerived,typename ElseDerived> | ||||
|     const Select<Derived,ThenDerived,ElseDerived> | ||||
|     select(const DenseBase<ThenDerived>& thenMatrix, | ||||
|            const DenseBase<ElseDerived>& elseMatrix) const; | ||||
|  | ||||
|     template<typename ThenDerived> | ||||
|     inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType> | ||||
|     select(const DenseBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const; | ||||
|  | ||||
|     template<typename ElseDerived> | ||||
|     inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived > | ||||
|     select(typename ElseDerived::Scalar thenScalar, const DenseBase<ElseDerived>& elseMatrix) const; | ||||
|  | ||||
|     template<int p> RealScalar lpNorm() const; | ||||
|  | ||||
|     template<int RowFactor, int ColFactor> | ||||
|     const Replicate<Derived,RowFactor,ColFactor> replicate() const; | ||||
|     const Replicate<Derived,Dynamic,Dynamic> replicate(Index rowFacor,Index colFactor) const; | ||||
|  | ||||
|     typedef Reverse<Derived, BothDirections> ReverseReturnType; | ||||
|     typedef const Reverse<const Derived, BothDirections> ConstReverseReturnType; | ||||
|     ReverseReturnType reverse(); | ||||
|     ConstReverseReturnType reverse() const; | ||||
|     void reverseInPlace(); | ||||
|  | ||||
| #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::DenseBase | ||||
| #   include "../plugins/BlockMethods.h" | ||||
| #   ifdef EIGEN_DENSEBASE_PLUGIN | ||||
| #     include EIGEN_DENSEBASE_PLUGIN | ||||
| #   endif | ||||
| #undef EIGEN_CURRENT_STORAGE_BASE_CLASS | ||||
|  | ||||
| #ifdef EIGEN2_SUPPORT | ||||
|  | ||||
|     Block<Derived> corner(CornerType type, Index cRows, Index cCols); | ||||
|     const Block<Derived> corner(CornerType type, Index cRows, Index cCols) const; | ||||
|     template<int CRows, int CCols> | ||||
|     Block<Derived, CRows, CCols> corner(CornerType type); | ||||
|     template<int CRows, int CCols> | ||||
|     const Block<Derived, CRows, CCols> corner(CornerType type) const; | ||||
|  | ||||
| #endif // EIGEN2_SUPPORT | ||||
|  | ||||
|  | ||||
|     // disable the use of evalTo for dense objects with a nice compilation error | ||||
|     template<typename Dest> inline void evalTo(Dest& ) const | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT((internal::is_same<Dest,void>::value),THE_EVAL_EVALTO_FUNCTION_SHOULD_NEVER_BE_CALLED_FOR_DENSE_OBJECTS); | ||||
|     } | ||||
|  | ||||
|   protected: | ||||
|     /** Default constructor. Do nothing. */ | ||||
|     DenseBase() | ||||
|     { | ||||
|       /* Just checks for self-consistency of the flags. | ||||
|        * Only do it when debugging Eigen, as this borders on paranoiac and could slow compilation down | ||||
|        */ | ||||
| #ifdef EIGEN_INTERNAL_DEBUGGING | ||||
|       EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, int(IsRowMajor)) | ||||
|                         && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, int(!IsRowMajor))), | ||||
|                           INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION) | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|   private: | ||||
|     explicit DenseBase(int); | ||||
|     DenseBase(int,int); | ||||
|     template<typename OtherDerived> explicit DenseBase(const DenseBase<OtherDerived>&); | ||||
| }; | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_DENSEBASE_H | ||||
							
								
								
									
										754
									
								
								latan/Eigen/src/Core/DenseCoeffsBase.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										754
									
								
								latan/Eigen/src/Core/DenseCoeffsBase.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,754 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_DENSECOEFFSBASE_H | ||||
| #define EIGEN_DENSECOEFFSBASE_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| namespace internal { | ||||
| template<typename T> struct add_const_on_value_type_if_arithmetic | ||||
| { | ||||
|   typedef typename conditional<is_arithmetic<T>::value, T, typename add_const_on_value_type<T>::type>::type type; | ||||
| }; | ||||
| } | ||||
|  | ||||
| /** \brief Base class providing read-only coefficient access to matrices and arrays. | ||||
|   * \ingroup Core_Module | ||||
|   * \tparam Derived Type of the derived class | ||||
|   * \tparam #ReadOnlyAccessors Constant indicating read-only access | ||||
|   * | ||||
|   * This class defines the \c operator() \c const function and friends, which can be used to read specific | ||||
|   * entries of a matrix or array. | ||||
|   *  | ||||
|   * \sa DenseCoeffsBase<Derived, WriteAccessors>, DenseCoeffsBase<Derived, DirectAccessors>, | ||||
|   *     \ref TopicClassHierarchy | ||||
|   */ | ||||
| template<typename Derived> | ||||
| class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived> | ||||
| { | ||||
|   public: | ||||
|     typedef typename internal::traits<Derived>::StorageKind StorageKind; | ||||
|     typedef typename internal::traits<Derived>::Index Index; | ||||
|     typedef typename internal::traits<Derived>::Scalar Scalar; | ||||
|     typedef typename internal::packet_traits<Scalar>::type PacketScalar; | ||||
|  | ||||
|     // Explanation for this CoeffReturnType typedef. | ||||
|     // - This is the return type of the coeff() method. | ||||
|     // - The LvalueBit means exactly that we can offer a coeffRef() method, which means exactly that we can get references | ||||
|     // to coeffs, which means exactly that we can have coeff() return a const reference (as opposed to returning a value). | ||||
|     // - The is_artihmetic check is required since "const int", "const double", etc. will cause warnings on some systems | ||||
|     // while the declaration of "const T", where T is a non arithmetic type does not. Always returning "const Scalar&" is | ||||
|     // not possible, since the underlying expressions might not offer a valid address the reference could be referring to. | ||||
|     typedef typename internal::conditional<bool(internal::traits<Derived>::Flags&LvalueBit), | ||||
|                          const Scalar&, | ||||
|                          typename internal::conditional<internal::is_arithmetic<Scalar>::value, Scalar, const Scalar>::type | ||||
|                      >::type CoeffReturnType; | ||||
|  | ||||
|     typedef typename internal::add_const_on_value_type_if_arithmetic< | ||||
|                          typename internal::packet_traits<Scalar>::type | ||||
|                      >::type PacketReturnType; | ||||
|  | ||||
|     typedef EigenBase<Derived> Base; | ||||
|     using Base::rows; | ||||
|     using Base::cols; | ||||
|     using Base::size; | ||||
|     using Base::derived; | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Index rowIndexByOuterInner(Index outer, Index inner) const | ||||
|     { | ||||
|       return int(Derived::RowsAtCompileTime) == 1 ? 0 | ||||
|           : int(Derived::ColsAtCompileTime) == 1 ? inner | ||||
|           : int(Derived::Flags)&RowMajorBit ? outer | ||||
|           : inner; | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Index colIndexByOuterInner(Index outer, Index inner) const | ||||
|     { | ||||
|       return int(Derived::ColsAtCompileTime) == 1 ? 0 | ||||
|           : int(Derived::RowsAtCompileTime) == 1 ? inner | ||||
|           : int(Derived::Flags)&RowMajorBit ? inner | ||||
|           : outer; | ||||
|     } | ||||
|  | ||||
|     /** Short version: don't use this function, use | ||||
|       * \link operator()(Index,Index) const \endlink instead. | ||||
|       * | ||||
|       * Long version: this function is similar to | ||||
|       * \link operator()(Index,Index) const \endlink, but without the assertion. | ||||
|       * Use this for limiting the performance cost of debugging code when doing | ||||
|       * repeated coefficient access. Only use this when it is guaranteed that the | ||||
|       * parameters \a row and \a col are in range. | ||||
|       * | ||||
|       * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this | ||||
|       * function equivalent to \link operator()(Index,Index) const \endlink. | ||||
|       * | ||||
|       * \sa operator()(Index,Index) const, coeffRef(Index,Index), coeff(Index) const | ||||
|       */ | ||||
|     EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const | ||||
|     { | ||||
|       eigen_internal_assert(row >= 0 && row < rows() | ||||
|                         && col >= 0 && col < cols()); | ||||
|       return derived().coeff(row, col); | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE CoeffReturnType coeffByOuterInner(Index outer, Index inner) const | ||||
|     { | ||||
|       return coeff(rowIndexByOuterInner(outer, inner), | ||||
|                    colIndexByOuterInner(outer, inner)); | ||||
|     } | ||||
|  | ||||
|     /** \returns the coefficient at given the given row and column. | ||||
|       * | ||||
|       * \sa operator()(Index,Index), operator[](Index) | ||||
|       */ | ||||
|     EIGEN_STRONG_INLINE CoeffReturnType operator()(Index row, Index col) const | ||||
|     { | ||||
|       eigen_assert(row >= 0 && row < rows() | ||||
|           && col >= 0 && col < cols()); | ||||
|       return derived().coeff(row, col); | ||||
|     } | ||||
|  | ||||
|     /** Short version: don't use this function, use | ||||
|       * \link operator[](Index) const \endlink instead. | ||||
|       * | ||||
|       * Long version: this function is similar to | ||||
|       * \link operator[](Index) const \endlink, but without the assertion. | ||||
|       * Use this for limiting the performance cost of debugging code when doing | ||||
|       * repeated coefficient access. Only use this when it is guaranteed that the | ||||
|       * parameter \a index is in range. | ||||
|       * | ||||
|       * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this | ||||
|       * function equivalent to \link operator[](Index) const \endlink. | ||||
|       * | ||||
|       * \sa operator[](Index) const, coeffRef(Index), coeff(Index,Index) const | ||||
|       */ | ||||
|  | ||||
|     EIGEN_STRONG_INLINE CoeffReturnType | ||||
|     coeff(Index index) const | ||||
|     { | ||||
|       eigen_internal_assert(index >= 0 && index < size()); | ||||
|       return derived().coeff(index); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** \returns the coefficient at given index. | ||||
|       * | ||||
|       * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit. | ||||
|       * | ||||
|       * \sa operator[](Index), operator()(Index,Index) const, x() const, y() const, | ||||
|       * z() const, w() const | ||||
|       */ | ||||
|  | ||||
|     EIGEN_STRONG_INLINE CoeffReturnType | ||||
|     operator[](Index index) const | ||||
|     { | ||||
|       #ifndef EIGEN2_SUPPORT | ||||
|       EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime, | ||||
|                           THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD) | ||||
|       #endif | ||||
|       eigen_assert(index >= 0 && index < size()); | ||||
|       return derived().coeff(index); | ||||
|     } | ||||
|  | ||||
|     /** \returns the coefficient at given index. | ||||
|       * | ||||
|       * This is synonymous to operator[](Index) const. | ||||
|       * | ||||
|       * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit. | ||||
|       * | ||||
|       * \sa operator[](Index), operator()(Index,Index) const, x() const, y() const, | ||||
|       * z() const, w() const | ||||
|       */ | ||||
|  | ||||
|     EIGEN_STRONG_INLINE CoeffReturnType | ||||
|     operator()(Index index) const | ||||
|     { | ||||
|       eigen_assert(index >= 0 && index < size()); | ||||
|       return derived().coeff(index); | ||||
|     } | ||||
|  | ||||
|     /** equivalent to operator[](0).  */ | ||||
|  | ||||
|     EIGEN_STRONG_INLINE CoeffReturnType | ||||
|     x() const { return (*this)[0]; } | ||||
|  | ||||
|     /** equivalent to operator[](1).  */ | ||||
|  | ||||
|     EIGEN_STRONG_INLINE CoeffReturnType | ||||
|     y() const { return (*this)[1]; } | ||||
|  | ||||
|     /** equivalent to operator[](2).  */ | ||||
|  | ||||
|     EIGEN_STRONG_INLINE CoeffReturnType | ||||
|     z() const { return (*this)[2]; } | ||||
|  | ||||
|     /** equivalent to operator[](3).  */ | ||||
|  | ||||
|     EIGEN_STRONG_INLINE CoeffReturnType | ||||
|     w() const { return (*this)[3]; } | ||||
|  | ||||
|     /** \internal | ||||
|       * \returns the packet of coefficients starting at the given row and column. It is your responsibility | ||||
|       * to ensure that a packet really starts there. This method is only available on expressions having the | ||||
|       * PacketAccessBit. | ||||
|       * | ||||
|       * The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select | ||||
|       * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets | ||||
|       * starting at an address which is a multiple of the packet size. | ||||
|       */ | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const | ||||
|     { | ||||
|       eigen_internal_assert(row >= 0 && row < rows() | ||||
|                       && col >= 0 && col < cols()); | ||||
|       return derived().template packet<LoadMode>(row,col); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** \internal */ | ||||
|     template<int LoadMode> | ||||
|     EIGEN_STRONG_INLINE PacketReturnType packetByOuterInner(Index outer, Index inner) const | ||||
|     { | ||||
|       return packet<LoadMode>(rowIndexByOuterInner(outer, inner), | ||||
|                               colIndexByOuterInner(outer, inner)); | ||||
|     } | ||||
|  | ||||
|     /** \internal | ||||
|       * \returns the packet of coefficients starting at the given index. It is your responsibility | ||||
|       * to ensure that a packet really starts there. This method is only available on expressions having the | ||||
|       * PacketAccessBit and the LinearAccessBit. | ||||
|       * | ||||
|       * The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select | ||||
|       * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets | ||||
|       * starting at an address which is a multiple of the packet size. | ||||
|       */ | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const | ||||
|     { | ||||
|       eigen_internal_assert(index >= 0 && index < size()); | ||||
|       return derived().template packet<LoadMode>(index); | ||||
|     } | ||||
|  | ||||
|   protected: | ||||
|     // explanation: DenseBase is doing "using ..." on the methods from DenseCoeffsBase. | ||||
|     // But some methods are only available in the DirectAccess case. | ||||
|     // So we add dummy methods here with these names, so that "using... " doesn't fail. | ||||
|     // It's not private so that the child class DenseBase can access them, and it's not public | ||||
|     // either since it's an implementation detail, so has to be protected. | ||||
|     void coeffRef(); | ||||
|     void coeffRefByOuterInner(); | ||||
|     void writePacket(); | ||||
|     void writePacketByOuterInner(); | ||||
|     void copyCoeff(); | ||||
|     void copyCoeffByOuterInner(); | ||||
|     void copyPacket(); | ||||
|     void copyPacketByOuterInner(); | ||||
|     void stride(); | ||||
|     void innerStride(); | ||||
|     void outerStride(); | ||||
|     void rowStride(); | ||||
|     void colStride(); | ||||
| }; | ||||
|  | ||||
| /** \brief Base class providing read/write coefficient access to matrices and arrays. | ||||
|   * \ingroup Core_Module | ||||
|   * \tparam Derived Type of the derived class | ||||
|   * \tparam #WriteAccessors Constant indicating read/write access | ||||
|   * | ||||
|   * This class defines the non-const \c operator() function and friends, which can be used to write specific | ||||
|   * entries of a matrix or array. This class inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which | ||||
|   * defines the const variant for reading specific entries. | ||||
|   *  | ||||
|   * \sa DenseCoeffsBase<Derived, DirectAccessors>, \ref TopicClassHierarchy | ||||
|   */ | ||||
| template<typename Derived> | ||||
| class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors> | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base; | ||||
|  | ||||
|     typedef typename internal::traits<Derived>::StorageKind StorageKind; | ||||
|     typedef typename internal::traits<Derived>::Index Index; | ||||
|     typedef typename internal::traits<Derived>::Scalar Scalar; | ||||
|     typedef typename internal::packet_traits<Scalar>::type PacketScalar; | ||||
|     typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|  | ||||
|     using Base::coeff; | ||||
|     using Base::rows; | ||||
|     using Base::cols; | ||||
|     using Base::size; | ||||
|     using Base::derived; | ||||
|     using Base::rowIndexByOuterInner; | ||||
|     using Base::colIndexByOuterInner; | ||||
|     using Base::operator[]; | ||||
|     using Base::operator(); | ||||
|     using Base::x; | ||||
|     using Base::y; | ||||
|     using Base::z; | ||||
|     using Base::w; | ||||
|  | ||||
|     /** Short version: don't use this function, use | ||||
|       * \link operator()(Index,Index) \endlink instead. | ||||
|       * | ||||
|       * Long version: this function is similar to | ||||
|       * \link operator()(Index,Index) \endlink, but without the assertion. | ||||
|       * Use this for limiting the performance cost of debugging code when doing | ||||
|       * repeated coefficient access. Only use this when it is guaranteed that the | ||||
|       * parameters \a row and \a col are in range. | ||||
|       * | ||||
|       * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this | ||||
|       * function equivalent to \link operator()(Index,Index) \endlink. | ||||
|       * | ||||
|       * \sa operator()(Index,Index), coeff(Index, Index) const, coeffRef(Index) | ||||
|       */ | ||||
|     EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col) | ||||
|     { | ||||
|       eigen_internal_assert(row >= 0 && row < rows() | ||||
|                         && col >= 0 && col < cols()); | ||||
|       return derived().coeffRef(row, col); | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Scalar& | ||||
|     coeffRefByOuterInner(Index outer, Index inner) | ||||
|     { | ||||
|       return coeffRef(rowIndexByOuterInner(outer, inner), | ||||
|                       colIndexByOuterInner(outer, inner)); | ||||
|     } | ||||
|  | ||||
|     /** \returns a reference to the coefficient at given the given row and column. | ||||
|       * | ||||
|       * \sa operator[](Index) | ||||
|       */ | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Scalar& | ||||
|     operator()(Index row, Index col) | ||||
|     { | ||||
|       eigen_assert(row >= 0 && row < rows() | ||||
|           && col >= 0 && col < cols()); | ||||
|       return derived().coeffRef(row, col); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** Short version: don't use this function, use | ||||
|       * \link operator[](Index) \endlink instead. | ||||
|       * | ||||
|       * Long version: this function is similar to | ||||
|       * \link operator[](Index) \endlink, but without the assertion. | ||||
|       * Use this for limiting the performance cost of debugging code when doing | ||||
|       * repeated coefficient access. Only use this when it is guaranteed that the | ||||
|       * parameters \a row and \a col are in range. | ||||
|       * | ||||
|       * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this | ||||
|       * function equivalent to \link operator[](Index) \endlink. | ||||
|       * | ||||
|       * \sa operator[](Index), coeff(Index) const, coeffRef(Index,Index) | ||||
|       */ | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Scalar& | ||||
|     coeffRef(Index index) | ||||
|     { | ||||
|       eigen_internal_assert(index >= 0 && index < size()); | ||||
|       return derived().coeffRef(index); | ||||
|     } | ||||
|  | ||||
|     /** \returns a reference to the coefficient at given index. | ||||
|       * | ||||
|       * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit. | ||||
|       * | ||||
|       * \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w() | ||||
|       */ | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Scalar& | ||||
|     operator[](Index index) | ||||
|     { | ||||
|       #ifndef EIGEN2_SUPPORT | ||||
|       EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime, | ||||
|                           THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD) | ||||
|       #endif | ||||
|       eigen_assert(index >= 0 && index < size()); | ||||
|       return derived().coeffRef(index); | ||||
|     } | ||||
|  | ||||
|     /** \returns a reference to the coefficient at given index. | ||||
|       * | ||||
|       * This is synonymous to operator[](Index). | ||||
|       * | ||||
|       * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit. | ||||
|       * | ||||
|       * \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w() | ||||
|       */ | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Scalar& | ||||
|     operator()(Index index) | ||||
|     { | ||||
|       eigen_assert(index >= 0 && index < size()); | ||||
|       return derived().coeffRef(index); | ||||
|     } | ||||
|  | ||||
|     /** equivalent to operator[](0).  */ | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Scalar& | ||||
|     x() { return (*this)[0]; } | ||||
|  | ||||
|     /** equivalent to operator[](1).  */ | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Scalar& | ||||
|     y() { return (*this)[1]; } | ||||
|  | ||||
|     /** equivalent to operator[](2).  */ | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Scalar& | ||||
|     z() { return (*this)[2]; } | ||||
|  | ||||
|     /** equivalent to operator[](3).  */ | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Scalar& | ||||
|     w() { return (*this)[3]; } | ||||
|  | ||||
|     /** \internal | ||||
|       * Stores the given packet of coefficients, at the given row and column of this expression. It is your responsibility | ||||
|       * to ensure that a packet really starts there. This method is only available on expressions having the | ||||
|       * PacketAccessBit. | ||||
|       * | ||||
|       * The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select | ||||
|       * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets | ||||
|       * starting at an address which is a multiple of the packet size. | ||||
|       */ | ||||
|  | ||||
|     template<int StoreMode> | ||||
|     EIGEN_STRONG_INLINE void writePacket | ||||
|     (Index row, Index col, const typename internal::packet_traits<Scalar>::type& x) | ||||
|     { | ||||
|       eigen_internal_assert(row >= 0 && row < rows() | ||||
|                         && col >= 0 && col < cols()); | ||||
|       derived().template writePacket<StoreMode>(row,col,x); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** \internal */ | ||||
|     template<int StoreMode> | ||||
|     EIGEN_STRONG_INLINE void writePacketByOuterInner | ||||
|     (Index outer, Index inner, const typename internal::packet_traits<Scalar>::type& x) | ||||
|     { | ||||
|       writePacket<StoreMode>(rowIndexByOuterInner(outer, inner), | ||||
|                             colIndexByOuterInner(outer, inner), | ||||
|                             x); | ||||
|     } | ||||
|  | ||||
|     /** \internal | ||||
|       * Stores the given packet of coefficients, at the given index in this expression. It is your responsibility | ||||
|       * to ensure that a packet really starts there. This method is only available on expressions having the | ||||
|       * PacketAccessBit and the LinearAccessBit. | ||||
|       * | ||||
|       * The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select | ||||
|       * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets | ||||
|       * starting at an address which is a multiple of the packet size. | ||||
|       */ | ||||
|     template<int StoreMode> | ||||
|     EIGEN_STRONG_INLINE void writePacket | ||||
|     (Index index, const typename internal::packet_traits<Scalar>::type& x) | ||||
|     { | ||||
|       eigen_internal_assert(index >= 0 && index < size()); | ||||
|       derived().template writePacket<StoreMode>(index,x); | ||||
|     } | ||||
|  | ||||
| #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|  | ||||
|     /** \internal Copies the coefficient at position (row,col) of other into *this. | ||||
|       * | ||||
|       * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code | ||||
|       * with usual assignments. | ||||
|       * | ||||
|       * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox. | ||||
|       */ | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       eigen_internal_assert(row >= 0 && row < rows() | ||||
|                         && col >= 0 && col < cols()); | ||||
|       derived().coeffRef(row, col) = other.derived().coeff(row, col); | ||||
|     } | ||||
|  | ||||
|     /** \internal Copies the coefficient at the given index of other into *this. | ||||
|       * | ||||
|       * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code | ||||
|       * with usual assignments. | ||||
|       * | ||||
|       * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox. | ||||
|       */ | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE void copyCoeff(Index index, const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       eigen_internal_assert(index >= 0 && index < size()); | ||||
|       derived().coeffRef(index) = other.derived().coeff(index); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE void copyCoeffByOuterInner(Index outer, Index inner, const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       const Index row = rowIndexByOuterInner(outer,inner); | ||||
|       const Index col = colIndexByOuterInner(outer,inner); | ||||
|       // derived() is important here: copyCoeff() may be reimplemented in Derived! | ||||
|       derived().copyCoeff(row, col, other); | ||||
|     } | ||||
|  | ||||
|     /** \internal Copies the packet at position (row,col) of other into *this. | ||||
|       * | ||||
|       * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code | ||||
|       * with usual assignments. | ||||
|       * | ||||
|       * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox. | ||||
|       */ | ||||
|  | ||||
|     template<typename OtherDerived, int StoreMode, int LoadMode> | ||||
|     EIGEN_STRONG_INLINE void copyPacket(Index row, Index col, const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       eigen_internal_assert(row >= 0 && row < rows() | ||||
|                         && col >= 0 && col < cols()); | ||||
|       derived().template writePacket<StoreMode>(row, col, | ||||
|         other.derived().template packet<LoadMode>(row, col)); | ||||
|     } | ||||
|  | ||||
|     /** \internal Copies the packet at the given index of other into *this. | ||||
|       * | ||||
|       * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code | ||||
|       * with usual assignments. | ||||
|       * | ||||
|       * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox. | ||||
|       */ | ||||
|  | ||||
|     template<typename OtherDerived, int StoreMode, int LoadMode> | ||||
|     EIGEN_STRONG_INLINE void copyPacket(Index index, const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       eigen_internal_assert(index >= 0 && index < size()); | ||||
|       derived().template writePacket<StoreMode>(index, | ||||
|         other.derived().template packet<LoadMode>(index)); | ||||
|     } | ||||
|  | ||||
|     /** \internal */ | ||||
|     template<typename OtherDerived, int StoreMode, int LoadMode> | ||||
|     EIGEN_STRONG_INLINE void copyPacketByOuterInner(Index outer, Index inner, const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       const Index row = rowIndexByOuterInner(outer,inner); | ||||
|       const Index col = colIndexByOuterInner(outer,inner); | ||||
|       // derived() is important here: copyCoeff() may be reimplemented in Derived! | ||||
|       derived().template copyPacket< OtherDerived, StoreMode, LoadMode>(row, col, other); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
| }; | ||||
|  | ||||
| /** \brief Base class providing direct read-only coefficient access to matrices and arrays. | ||||
|   * \ingroup Core_Module | ||||
|   * \tparam Derived Type of the derived class | ||||
|   * \tparam #DirectAccessors Constant indicating direct access | ||||
|   * | ||||
|   * This class defines functions to work with strides which can be used to access entries directly. This class | ||||
|   * inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which defines functions to access entries read-only using | ||||
|   * \c operator() . | ||||
|   * | ||||
|   * \sa \ref TopicClassHierarchy | ||||
|   */ | ||||
| template<typename Derived> | ||||
| class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors> | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base; | ||||
|     typedef typename internal::traits<Derived>::Index Index; | ||||
|     typedef typename internal::traits<Derived>::Scalar Scalar; | ||||
|     typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|  | ||||
|     using Base::rows; | ||||
|     using Base::cols; | ||||
|     using Base::size; | ||||
|     using Base::derived; | ||||
|  | ||||
|     /** \returns the pointer increment between two consecutive elements within a slice in the inner direction. | ||||
|       * | ||||
|       * \sa outerStride(), rowStride(), colStride() | ||||
|       */ | ||||
|     inline Index innerStride() const | ||||
|     { | ||||
|       return derived().innerStride(); | ||||
|     } | ||||
|  | ||||
|     /** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns | ||||
|       *          in a column-major matrix). | ||||
|       * | ||||
|       * \sa innerStride(), rowStride(), colStride() | ||||
|       */ | ||||
|     inline Index outerStride() const | ||||
|     { | ||||
|       return derived().outerStride(); | ||||
|     } | ||||
|  | ||||
|     // FIXME shall we remove it ? | ||||
|     inline Index stride() const | ||||
|     { | ||||
|       return Derived::IsVectorAtCompileTime ? innerStride() : outerStride(); | ||||
|     } | ||||
|  | ||||
|     /** \returns the pointer increment between two consecutive rows. | ||||
|       * | ||||
|       * \sa innerStride(), outerStride(), colStride() | ||||
|       */ | ||||
|     inline Index rowStride() const | ||||
|     { | ||||
|       return Derived::IsRowMajor ? outerStride() : innerStride(); | ||||
|     } | ||||
|  | ||||
|     /** \returns the pointer increment between two consecutive columns. | ||||
|       * | ||||
|       * \sa innerStride(), outerStride(), rowStride() | ||||
|       */ | ||||
|     inline Index colStride() const | ||||
|     { | ||||
|       return Derived::IsRowMajor ? innerStride() : outerStride(); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| /** \brief Base class providing direct read/write coefficient access to matrices and arrays. | ||||
|   * \ingroup Core_Module | ||||
|   * \tparam Derived Type of the derived class | ||||
|   * \tparam #DirectWriteAccessors Constant indicating direct access | ||||
|   * | ||||
|   * This class defines functions to work with strides which can be used to access entries directly. This class | ||||
|   * inherits DenseCoeffsBase<Derived, WriteAccessors> which defines functions to access entries read/write using | ||||
|   * \c operator(). | ||||
|   * | ||||
|   * \sa \ref TopicClassHierarchy | ||||
|   */ | ||||
| template<typename Derived> | ||||
| class DenseCoeffsBase<Derived, DirectWriteAccessors> | ||||
|   : public DenseCoeffsBase<Derived, WriteAccessors> | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef DenseCoeffsBase<Derived, WriteAccessors> Base; | ||||
|     typedef typename internal::traits<Derived>::Index Index; | ||||
|     typedef typename internal::traits<Derived>::Scalar Scalar; | ||||
|     typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|  | ||||
|     using Base::rows; | ||||
|     using Base::cols; | ||||
|     using Base::size; | ||||
|     using Base::derived; | ||||
|  | ||||
|     /** \returns the pointer increment between two consecutive elements within a slice in the inner direction. | ||||
|       * | ||||
|       * \sa outerStride(), rowStride(), colStride() | ||||
|       */ | ||||
|     inline Index innerStride() const | ||||
|     { | ||||
|       return derived().innerStride(); | ||||
|     } | ||||
|  | ||||
|     /** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns | ||||
|       *          in a column-major matrix). | ||||
|       * | ||||
|       * \sa innerStride(), rowStride(), colStride() | ||||
|       */ | ||||
|     inline Index outerStride() const | ||||
|     { | ||||
|       return derived().outerStride(); | ||||
|     } | ||||
|  | ||||
|     // FIXME shall we remove it ? | ||||
|     inline Index stride() const | ||||
|     { | ||||
|       return Derived::IsVectorAtCompileTime ? innerStride() : outerStride(); | ||||
|     } | ||||
|  | ||||
|     /** \returns the pointer increment between two consecutive rows. | ||||
|       * | ||||
|       * \sa innerStride(), outerStride(), colStride() | ||||
|       */ | ||||
|     inline Index rowStride() const | ||||
|     { | ||||
|       return Derived::IsRowMajor ? outerStride() : innerStride(); | ||||
|     } | ||||
|  | ||||
|     /** \returns the pointer increment between two consecutive columns. | ||||
|       * | ||||
|       * \sa innerStride(), outerStride(), rowStride() | ||||
|       */ | ||||
|     inline Index colStride() const | ||||
|     { | ||||
|       return Derived::IsRowMajor ? innerStride() : outerStride(); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename Derived, bool JustReturnZero> | ||||
| struct first_aligned_impl | ||||
| { | ||||
|   static inline typename Derived::Index run(const Derived&) | ||||
|   { return 0; } | ||||
| }; | ||||
|  | ||||
| template<typename Derived> | ||||
| struct first_aligned_impl<Derived, false> | ||||
| { | ||||
|   static inline typename Derived::Index run(const Derived& m) | ||||
|   { | ||||
|     return internal::first_aligned(&m.const_cast_derived().coeffRef(0,0), m.size()); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** \internal \returns the index of the first element of the array that is well aligned for vectorization. | ||||
|   * | ||||
|   * There is also the variant first_aligned(const Scalar*, Integer) defined in Memory.h. See it for more | ||||
|   * documentation. | ||||
|   */ | ||||
| template<typename Derived> | ||||
| static inline typename Derived::Index first_aligned(const Derived& m) | ||||
| { | ||||
|   return first_aligned_impl | ||||
|           <Derived, (Derived::Flags & AlignedBit) || !(Derived::Flags & DirectAccessBit)> | ||||
|           ::run(m); | ||||
| } | ||||
|  | ||||
| template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret> | ||||
| struct inner_stride_at_compile_time | ||||
| { | ||||
|   enum { ret = traits<Derived>::InnerStrideAtCompileTime }; | ||||
| }; | ||||
|  | ||||
| template<typename Derived> | ||||
| struct inner_stride_at_compile_time<Derived, false> | ||||
| { | ||||
|   enum { ret = 0 }; | ||||
| }; | ||||
|  | ||||
| template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret> | ||||
| struct outer_stride_at_compile_time | ||||
| { | ||||
|   enum { ret = traits<Derived>::OuterStrideAtCompileTime }; | ||||
| }; | ||||
|  | ||||
| template<typename Derived> | ||||
| struct outer_stride_at_compile_time<Derived, false> | ||||
| { | ||||
|   enum { ret = 0 }; | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_DENSECOEFFSBASE_H | ||||
							
								
								
									
										314
									
								
								latan/Eigen/src/Core/DenseStorage.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										314
									
								
								latan/Eigen/src/Core/DenseStorage.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,314 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_MATRIXSTORAGE_H | ||||
| #define EIGEN_MATRIXSTORAGE_H | ||||
|  | ||||
| #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN | ||||
|   #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN EIGEN_DENSE_STORAGE_CTOR_PLUGIN; | ||||
| #else | ||||
|   #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN | ||||
| #endif | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| struct constructor_without_unaligned_array_assert {}; | ||||
|  | ||||
| /** \internal | ||||
|   * Static array. If the MatrixOrArrayOptions require auto-alignment, the array will be automatically aligned: | ||||
|   * to 16 bytes boundary if the total size is a multiple of 16 bytes. | ||||
|   */ | ||||
| template <typename T, int Size, int MatrixOrArrayOptions, | ||||
|           int Alignment = (MatrixOrArrayOptions&DontAlign) ? 0 | ||||
|                         : (((Size*sizeof(T))%16)==0) ? 16 | ||||
|                         : 0 > | ||||
| struct plain_array | ||||
| { | ||||
|   T array[Size]; | ||||
|   plain_array() {} | ||||
|   plain_array(constructor_without_unaligned_array_assert) {} | ||||
| }; | ||||
|  | ||||
| #if defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT) | ||||
|   #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) | ||||
| #elif EIGEN_GNUC_AT_LEAST(4,7)  | ||||
|   // GCC 4.7 is too aggressive in its optimizations and remove the alignement test based on the fact the array is declared to be aligned. | ||||
|   // See this bug report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53900 | ||||
|   // Hiding the origin of the array pointer behind a function argument seems to do the trick even if the function is inlined: | ||||
|   template<typename PtrType> | ||||
|   EIGEN_ALWAYS_INLINE PtrType eigen_unaligned_array_assert_workaround_gcc47(PtrType array) { return array; } | ||||
|   #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \ | ||||
|     eigen_assert((reinterpret_cast<size_t>(eigen_unaligned_array_assert_workaround_gcc47(array)) & sizemask) == 0 \ | ||||
|               && "this assertion is explained here: " \ | ||||
|               "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \ | ||||
|               " **** READ THIS WEB PAGE !!! ****"); | ||||
| #else | ||||
|   #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \ | ||||
|     eigen_assert((reinterpret_cast<size_t>(array) & sizemask) == 0 \ | ||||
|               && "this assertion is explained here: " \ | ||||
|               "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \ | ||||
|               " **** READ THIS WEB PAGE !!! ****"); | ||||
| #endif | ||||
|  | ||||
| template <typename T, int Size, int MatrixOrArrayOptions> | ||||
| struct plain_array<T, Size, MatrixOrArrayOptions, 16> | ||||
| { | ||||
|   EIGEN_USER_ALIGN16 T array[Size]; | ||||
|   plain_array() { EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(0xf) } | ||||
|   plain_array(constructor_without_unaligned_array_assert) {} | ||||
| }; | ||||
|  | ||||
| template <typename T, int MatrixOrArrayOptions, int Alignment> | ||||
| struct plain_array<T, 0, MatrixOrArrayOptions, Alignment> | ||||
| { | ||||
|   EIGEN_USER_ALIGN16 T array[1]; | ||||
|   plain_array() {} | ||||
|   plain_array(constructor_without_unaligned_array_assert) {} | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /** \internal | ||||
|   * | ||||
|   * \class DenseStorage | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Stores the data of a matrix | ||||
|   * | ||||
|   * This class stores the data of fixed-size, dynamic-size or mixed matrices | ||||
|   * in a way as compact as possible. | ||||
|   * | ||||
|   * \sa Matrix | ||||
|   */ | ||||
| template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseStorage; | ||||
|  | ||||
| // purely fixed-size matrix | ||||
| template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseStorage | ||||
| { | ||||
|     internal::plain_array<T,Size,_Options> m_data; | ||||
|   public: | ||||
|     inline explicit DenseStorage() {} | ||||
|     inline DenseStorage(internal::constructor_without_unaligned_array_assert) | ||||
|       : m_data(internal::constructor_without_unaligned_array_assert()) {} | ||||
|     inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} | ||||
|     inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); } | ||||
|     static inline DenseIndex rows(void) {return _Rows;} | ||||
|     static inline DenseIndex cols(void) {return _Cols;} | ||||
|     inline void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {} | ||||
|     inline void resize(DenseIndex,DenseIndex,DenseIndex) {} | ||||
|     inline const T *data() const { return m_data.array; } | ||||
|     inline T *data() { return m_data.array; } | ||||
| }; | ||||
|  | ||||
| // null matrix | ||||
| template<typename T, int _Rows, int _Cols, int _Options> class DenseStorage<T, 0, _Rows, _Cols, _Options> | ||||
| { | ||||
|   public: | ||||
|     inline explicit DenseStorage() {} | ||||
|     inline DenseStorage(internal::constructor_without_unaligned_array_assert) {} | ||||
|     inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} | ||||
|     inline void swap(DenseStorage& ) {} | ||||
|     static inline DenseIndex rows(void) {return _Rows;} | ||||
|     static inline DenseIndex cols(void) {return _Cols;} | ||||
|     inline void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {} | ||||
|     inline void resize(DenseIndex,DenseIndex,DenseIndex) {} | ||||
|     inline const T *data() const { return 0; } | ||||
|     inline T *data() { return 0; } | ||||
| }; | ||||
|  | ||||
| // more specializations for null matrices; these are necessary to resolve ambiguities | ||||
| template<typename T, int _Options> class DenseStorage<T, 0, Dynamic, Dynamic, _Options> | ||||
| : public DenseStorage<T, 0, 0, 0, _Options> { }; | ||||
|  | ||||
| template<typename T, int _Rows, int _Options> class DenseStorage<T, 0, _Rows, Dynamic, _Options> | ||||
| : public DenseStorage<T, 0, 0, 0, _Options> { }; | ||||
|  | ||||
| template<typename T, int _Cols, int _Options> class DenseStorage<T, 0, Dynamic, _Cols, _Options> | ||||
| : public DenseStorage<T, 0, 0, 0, _Options> { }; | ||||
|  | ||||
| // dynamic-size matrix with fixed-size storage | ||||
| template<typename T, int Size, int _Options> class DenseStorage<T, Size, Dynamic, Dynamic, _Options> | ||||
| { | ||||
|     internal::plain_array<T,Size,_Options> m_data; | ||||
|     DenseIndex m_rows; | ||||
|     DenseIndex m_cols; | ||||
|   public: | ||||
|     inline explicit DenseStorage() : m_rows(0), m_cols(0) {} | ||||
|     inline DenseStorage(internal::constructor_without_unaligned_array_assert) | ||||
|       : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {} | ||||
|     inline DenseStorage(DenseIndex, DenseIndex rows, DenseIndex cols) : m_rows(rows), m_cols(cols) {} | ||||
|     inline void swap(DenseStorage& other) | ||||
|     { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); } | ||||
|     inline DenseIndex rows(void) const {return m_rows;} | ||||
|     inline DenseIndex cols(void) const {return m_cols;} | ||||
|     inline void conservativeResize(DenseIndex, DenseIndex rows, DenseIndex cols) { m_rows = rows; m_cols = cols; } | ||||
|     inline void resize(DenseIndex, DenseIndex rows, DenseIndex cols) { m_rows = rows; m_cols = cols; } | ||||
|     inline const T *data() const { return m_data.array; } | ||||
|     inline T *data() { return m_data.array; } | ||||
| }; | ||||
|  | ||||
| // dynamic-size matrix with fixed-size storage and fixed width | ||||
| template<typename T, int Size, int _Cols, int _Options> class DenseStorage<T, Size, Dynamic, _Cols, _Options> | ||||
| { | ||||
|     internal::plain_array<T,Size,_Options> m_data; | ||||
|     DenseIndex m_rows; | ||||
|   public: | ||||
|     inline explicit DenseStorage() : m_rows(0) {} | ||||
|     inline DenseStorage(internal::constructor_without_unaligned_array_assert) | ||||
|       : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {} | ||||
|     inline DenseStorage(DenseIndex, DenseIndex rows, DenseIndex) : m_rows(rows) {} | ||||
|     inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } | ||||
|     inline DenseIndex rows(void) const {return m_rows;} | ||||
|     inline DenseIndex cols(void) const {return _Cols;} | ||||
|     inline void conservativeResize(DenseIndex, DenseIndex rows, DenseIndex) { m_rows = rows; } | ||||
|     inline void resize(DenseIndex, DenseIndex rows, DenseIndex) { m_rows = rows; } | ||||
|     inline const T *data() const { return m_data.array; } | ||||
|     inline T *data() { return m_data.array; } | ||||
| }; | ||||
|  | ||||
| // dynamic-size matrix with fixed-size storage and fixed height | ||||
| template<typename T, int Size, int _Rows, int _Options> class DenseStorage<T, Size, _Rows, Dynamic, _Options> | ||||
| { | ||||
|     internal::plain_array<T,Size,_Options> m_data; | ||||
|     DenseIndex m_cols; | ||||
|   public: | ||||
|     inline explicit DenseStorage() : m_cols(0) {} | ||||
|     inline DenseStorage(internal::constructor_without_unaligned_array_assert) | ||||
|       : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {} | ||||
|     inline DenseStorage(DenseIndex, DenseIndex, DenseIndex cols) : m_cols(cols) {} | ||||
|     inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } | ||||
|     inline DenseIndex rows(void) const {return _Rows;} | ||||
|     inline DenseIndex cols(void) const {return m_cols;} | ||||
|     inline void conservativeResize(DenseIndex, DenseIndex, DenseIndex cols) { m_cols = cols; } | ||||
|     inline void resize(DenseIndex, DenseIndex, DenseIndex cols) { m_cols = cols; } | ||||
|     inline const T *data() const { return m_data.array; } | ||||
|     inline T *data() { return m_data.array; } | ||||
| }; | ||||
|  | ||||
| // purely dynamic matrix. | ||||
| template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynamic, _Options> | ||||
| { | ||||
|     T *m_data; | ||||
|     DenseIndex m_rows; | ||||
|     DenseIndex m_cols; | ||||
|   public: | ||||
|     inline explicit DenseStorage() : m_data(0), m_rows(0), m_cols(0) {} | ||||
|     inline DenseStorage(internal::constructor_without_unaligned_array_assert) | ||||
|        : m_data(0), m_rows(0), m_cols(0) {} | ||||
|     inline DenseStorage(DenseIndex size, DenseIndex rows, DenseIndex cols) | ||||
|       : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(rows), m_cols(cols)  | ||||
|     { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } | ||||
|     inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); } | ||||
|     inline void swap(DenseStorage& other) | ||||
|     { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); } | ||||
|     inline DenseIndex rows(void) const {return m_rows;} | ||||
|     inline DenseIndex cols(void) const {return m_cols;} | ||||
|     inline void conservativeResize(DenseIndex size, DenseIndex rows, DenseIndex cols) | ||||
|     { | ||||
|       m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*m_cols); | ||||
|       m_rows = rows; | ||||
|       m_cols = cols; | ||||
|     } | ||||
|     void resize(DenseIndex size, DenseIndex rows, DenseIndex cols) | ||||
|     { | ||||
|       if(size != m_rows*m_cols) | ||||
|       { | ||||
|         internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); | ||||
|         if (size) | ||||
|           m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size); | ||||
|         else | ||||
|           m_data = 0; | ||||
|         EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN | ||||
|       } | ||||
|       m_rows = rows; | ||||
|       m_cols = cols; | ||||
|     } | ||||
|     inline const T *data() const { return m_data; } | ||||
|     inline T *data() { return m_data; } | ||||
| }; | ||||
|  | ||||
| // matrix with dynamic width and fixed height (so that matrix has dynamic size). | ||||
| template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Rows, Dynamic, _Options> | ||||
| { | ||||
|     T *m_data; | ||||
|     DenseIndex m_cols; | ||||
|   public: | ||||
|     inline explicit DenseStorage() : m_data(0), m_cols(0) {} | ||||
|     inline DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {} | ||||
|     inline DenseStorage(DenseIndex size, DenseIndex, DenseIndex cols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_cols(cols) | ||||
|     { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } | ||||
|     inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); } | ||||
|     inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } | ||||
|     static inline DenseIndex rows(void) {return _Rows;} | ||||
|     inline DenseIndex cols(void) const {return m_cols;} | ||||
|     inline void conservativeResize(DenseIndex size, DenseIndex, DenseIndex cols) | ||||
|     { | ||||
|       m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, _Rows*m_cols); | ||||
|       m_cols = cols; | ||||
|     } | ||||
|     EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex, DenseIndex cols) | ||||
|     { | ||||
|       if(size != _Rows*m_cols) | ||||
|       { | ||||
|         internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); | ||||
|         if (size) | ||||
|           m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size); | ||||
|         else | ||||
|           m_data = 0; | ||||
|         EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN | ||||
|       } | ||||
|       m_cols = cols; | ||||
|     } | ||||
|     inline const T *data() const { return m_data; } | ||||
|     inline T *data() { return m_data; } | ||||
| }; | ||||
|  | ||||
| // matrix with dynamic height and fixed width (so that matrix has dynamic size). | ||||
| template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dynamic, _Cols, _Options> | ||||
| { | ||||
|     T *m_data; | ||||
|     DenseIndex m_rows; | ||||
|   public: | ||||
|     inline explicit DenseStorage() : m_data(0), m_rows(0) {} | ||||
|     inline DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {} | ||||
|     inline DenseStorage(DenseIndex size, DenseIndex rows, DenseIndex) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(rows) | ||||
|     { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } | ||||
|     inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); } | ||||
|     inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } | ||||
|     inline DenseIndex rows(void) const {return m_rows;} | ||||
|     static inline DenseIndex cols(void) {return _Cols;} | ||||
|     inline void conservativeResize(DenseIndex size, DenseIndex rows, DenseIndex) | ||||
|     { | ||||
|       m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*_Cols); | ||||
|       m_rows = rows; | ||||
|     } | ||||
|     EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex rows, DenseIndex) | ||||
|     { | ||||
|       if(size != m_rows*_Cols) | ||||
|       { | ||||
|         internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); | ||||
|         if (size) | ||||
|           m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size); | ||||
|         else | ||||
|           m_data = 0; | ||||
|         EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN | ||||
|       } | ||||
|       m_rows = rows; | ||||
|     } | ||||
|     inline const T *data() const { return m_data; } | ||||
|     inline T *data() { return m_data; } | ||||
| }; | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_MATRIX_H | ||||
							
								
								
									
										236
									
								
								latan/Eigen/src/Core/Diagonal.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										236
									
								
								latan/Eigen/src/Core/Diagonal.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,236 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_DIAGONAL_H | ||||
| #define EIGEN_DIAGONAL_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class Diagonal | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Expression of a diagonal/subdiagonal/superdiagonal in a matrix | ||||
|   * | ||||
|   * \param MatrixType the type of the object in which we are taking a sub/main/super diagonal | ||||
|   * \param DiagIndex the index of the sub/super diagonal. The default is 0 and it means the main diagonal. | ||||
|   *              A positive value means a superdiagonal, a negative value means a subdiagonal. | ||||
|   *              You can also use Dynamic so the index can be set at runtime. | ||||
|   * | ||||
|   * The matrix is not required to be square. | ||||
|   * | ||||
|   * This class represents an expression of the main diagonal, or any sub/super diagonal | ||||
|   * of a square matrix. It is the return type of MatrixBase::diagonal() and MatrixBase::diagonal(Index) and most of the | ||||
|   * time this is the only way it is used. | ||||
|   * | ||||
|   * \sa MatrixBase::diagonal(), MatrixBase::diagonal(Index) | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename MatrixType, int DiagIndex> | ||||
| struct traits<Diagonal<MatrixType,DiagIndex> > | ||||
|  : traits<MatrixType> | ||||
| { | ||||
|   typedef typename nested<MatrixType>::type MatrixTypeNested; | ||||
|   typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested; | ||||
|   typedef typename MatrixType::StorageKind StorageKind; | ||||
|   enum { | ||||
|     RowsAtCompileTime = (int(DiagIndex) == Dynamic || int(MatrixType::SizeAtCompileTime) == Dynamic) ? Dynamic | ||||
|     : (EIGEN_PLAIN_ENUM_MIN(MatrixType::RowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0), | ||||
|                             MatrixType::ColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))), | ||||
|     ColsAtCompileTime = 1, | ||||
|     MaxRowsAtCompileTime = int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic | ||||
|                          : DiagIndex == Dynamic ? EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::MaxRowsAtCompileTime, | ||||
|                                                                               MatrixType::MaxColsAtCompileTime) | ||||
|                          : (EIGEN_PLAIN_ENUM_MIN(MatrixType::MaxRowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0), | ||||
|                                                  MatrixType::MaxColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))), | ||||
|     MaxColsAtCompileTime = 1, | ||||
|     MaskLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0, | ||||
|     Flags = (unsigned int)_MatrixTypeNested::Flags & (HereditaryBits | LinearAccessBit | MaskLvalueBit | DirectAccessBit) & ~RowMajorBit, | ||||
|     CoeffReadCost = _MatrixTypeNested::CoeffReadCost, | ||||
|     MatrixTypeOuterStride = outer_stride_at_compile_time<MatrixType>::ret, | ||||
|     InnerStrideAtCompileTime = MatrixTypeOuterStride == Dynamic ? Dynamic : MatrixTypeOuterStride+1, | ||||
|     OuterStrideAtCompileTime = 0 | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename MatrixType, int DiagIndex> class Diagonal | ||||
|    : public internal::dense_xpr_base< Diagonal<MatrixType,DiagIndex> >::type | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef typename internal::dense_xpr_base<Diagonal>::type Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(Diagonal) | ||||
|  | ||||
|     inline Diagonal(MatrixType& matrix, Index index = DiagIndex) : m_matrix(matrix), m_index(index) {} | ||||
|  | ||||
|     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Diagonal) | ||||
|  | ||||
|     inline Index rows() const | ||||
|     { return m_index.value()<0 ? (std::min)(m_matrix.cols(),m_matrix.rows()+m_index.value()) : (std::min)(m_matrix.rows(),m_matrix.cols()-m_index.value()); } | ||||
|  | ||||
|     inline Index cols() const { return 1; } | ||||
|  | ||||
|     inline Index innerStride() const | ||||
|     { | ||||
|       return m_matrix.outerStride() + 1; | ||||
|     } | ||||
|  | ||||
|     inline Index outerStride() const | ||||
|     { | ||||
|       return 0; | ||||
|     } | ||||
|  | ||||
|     typedef typename internal::conditional< | ||||
|                        internal::is_lvalue<MatrixType>::value, | ||||
|                        Scalar, | ||||
|                        const Scalar | ||||
|                      >::type ScalarWithConstIfNotLvalue; | ||||
|  | ||||
|     inline ScalarWithConstIfNotLvalue* data() { return &(m_matrix.const_cast_derived().coeffRef(rowOffset(), colOffset())); } | ||||
|     inline const Scalar* data() const { return &(m_matrix.const_cast_derived().coeffRef(rowOffset(), colOffset())); } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index row, Index) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_LVALUE(MatrixType) | ||||
|       return m_matrix.const_cast_derived().coeffRef(row+rowOffset(), row+colOffset()); | ||||
|     } | ||||
|  | ||||
|     inline const Scalar& coeffRef(Index row, Index) const | ||||
|     { | ||||
|       return m_matrix.const_cast_derived().coeffRef(row+rowOffset(), row+colOffset()); | ||||
|     } | ||||
|  | ||||
|     inline CoeffReturnType coeff(Index row, Index) const | ||||
|     { | ||||
|       return m_matrix.coeff(row+rowOffset(), row+colOffset()); | ||||
|     } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index index) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_LVALUE(MatrixType) | ||||
|       return m_matrix.const_cast_derived().coeffRef(index+rowOffset(), index+colOffset()); | ||||
|     } | ||||
|  | ||||
|     inline const Scalar& coeffRef(Index index) const | ||||
|     { | ||||
|       return m_matrix.const_cast_derived().coeffRef(index+rowOffset(), index+colOffset()); | ||||
|     } | ||||
|  | ||||
|     inline CoeffReturnType coeff(Index index) const | ||||
|     { | ||||
|       return m_matrix.coeff(index+rowOffset(), index+colOffset()); | ||||
|     } | ||||
|  | ||||
|     const typename internal::remove_all<typename MatrixType::Nested>::type&  | ||||
|     nestedExpression() const  | ||||
|     { | ||||
|       return m_matrix; | ||||
|     } | ||||
|  | ||||
|     int index() const | ||||
|     { | ||||
|       return m_index.value(); | ||||
|     } | ||||
|  | ||||
|   protected: | ||||
|     typename MatrixType::Nested m_matrix; | ||||
|     const internal::variable_if_dynamic<Index, DiagIndex> m_index; | ||||
|  | ||||
|   private: | ||||
|     // some compilers may fail to optimize std::max etc in case of compile-time constants... | ||||
|     EIGEN_STRONG_INLINE Index absDiagIndex() const { return m_index.value()>0 ? m_index.value() : -m_index.value(); } | ||||
|     EIGEN_STRONG_INLINE Index rowOffset() const { return m_index.value()>0 ? 0 : -m_index.value(); } | ||||
|     EIGEN_STRONG_INLINE Index colOffset() const { return m_index.value()>0 ? m_index.value() : 0; } | ||||
|     // triger a compile time error is someone try to call packet | ||||
|     template<int LoadMode> typename MatrixType::PacketReturnType packet(Index) const; | ||||
|     template<int LoadMode> typename MatrixType::PacketReturnType packet(Index,Index) const; | ||||
| }; | ||||
|  | ||||
| /** \returns an expression of the main diagonal of the matrix \c *this | ||||
|   * | ||||
|   * \c *this is not required to be square. | ||||
|   * | ||||
|   * Example: \include MatrixBase_diagonal.cpp | ||||
|   * Output: \verbinclude MatrixBase_diagonal.out | ||||
|   * | ||||
|   * \sa class Diagonal */ | ||||
| template<typename Derived> | ||||
| inline typename MatrixBase<Derived>::DiagonalReturnType | ||||
| MatrixBase<Derived>::diagonal() | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| /** This is the const version of diagonal(). */ | ||||
| template<typename Derived> | ||||
| inline const typename MatrixBase<Derived>::ConstDiagonalReturnType | ||||
| MatrixBase<Derived>::diagonal() const | ||||
| { | ||||
|   return ConstDiagonalReturnType(derived()); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this | ||||
|   * | ||||
|   * \c *this is not required to be square. | ||||
|   * | ||||
|   * The template parameter \a DiagIndex represent a super diagonal if \a DiagIndex > 0 | ||||
|   * and a sub diagonal otherwise. \a DiagIndex == 0 is equivalent to the main diagonal. | ||||
|   * | ||||
|   * Example: \include MatrixBase_diagonal_int.cpp | ||||
|   * Output: \verbinclude MatrixBase_diagonal_int.out | ||||
|   * | ||||
|   * \sa MatrixBase::diagonal(), class Diagonal */ | ||||
| template<typename Derived> | ||||
| inline typename MatrixBase<Derived>::template DiagonalIndexReturnType<Dynamic>::Type | ||||
| MatrixBase<Derived>::diagonal(Index index) | ||||
| { | ||||
|   return typename DiagonalIndexReturnType<Dynamic>::Type(derived(), index); | ||||
| } | ||||
|  | ||||
| /** This is the const version of diagonal(Index). */ | ||||
| template<typename Derived> | ||||
| inline typename MatrixBase<Derived>::template ConstDiagonalIndexReturnType<Dynamic>::Type | ||||
| MatrixBase<Derived>::diagonal(Index index) const | ||||
| { | ||||
|   return typename ConstDiagonalIndexReturnType<Dynamic>::Type(derived(), index); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this | ||||
|   * | ||||
|   * \c *this is not required to be square. | ||||
|   * | ||||
|   * The template parameter \a DiagIndex represent a super diagonal if \a DiagIndex > 0 | ||||
|   * and a sub diagonal otherwise. \a DiagIndex == 0 is equivalent to the main diagonal. | ||||
|   * | ||||
|   * Example: \include MatrixBase_diagonal_template_int.cpp | ||||
|   * Output: \verbinclude MatrixBase_diagonal_template_int.out | ||||
|   * | ||||
|   * \sa MatrixBase::diagonal(), class Diagonal */ | ||||
| template<typename Derived> | ||||
| template<int Index> | ||||
| inline typename MatrixBase<Derived>::template DiagonalIndexReturnType<Index>::Type | ||||
| MatrixBase<Derived>::diagonal() | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| /** This is the const version of diagonal<int>(). */ | ||||
| template<typename Derived> | ||||
| template<int Index> | ||||
| inline typename MatrixBase<Derived>::template ConstDiagonalIndexReturnType<Index>::Type | ||||
| MatrixBase<Derived>::diagonal() const | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_DIAGONAL_H | ||||
							
								
								
									
										307
									
								
								latan/Eigen/src/Core/DiagonalMatrix.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										307
									
								
								latan/Eigen/src/Core/DiagonalMatrix.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,307 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_DIAGONALMATRIX_H | ||||
| #define EIGEN_DIAGONALMATRIX_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
| template<typename Derived> | ||||
| class DiagonalBase : public EigenBase<Derived> | ||||
| { | ||||
|   public: | ||||
|     typedef typename internal::traits<Derived>::DiagonalVectorType DiagonalVectorType; | ||||
|     typedef typename DiagonalVectorType::Scalar Scalar; | ||||
|     typedef typename DiagonalVectorType::RealScalar RealScalar; | ||||
|     typedef typename internal::traits<Derived>::StorageKind StorageKind; | ||||
|     typedef typename internal::traits<Derived>::Index Index; | ||||
|  | ||||
|     enum { | ||||
|       RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, | ||||
|       ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, | ||||
|       MaxRowsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime, | ||||
|       MaxColsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime, | ||||
|       IsVectorAtCompileTime = 0, | ||||
|       Flags = 0 | ||||
|     }; | ||||
|  | ||||
|     typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, 0, MaxRowsAtCompileTime, MaxColsAtCompileTime> DenseMatrixType; | ||||
|     typedef DenseMatrixType DenseType; | ||||
|     typedef DiagonalMatrix<Scalar,DiagonalVectorType::SizeAtCompileTime,DiagonalVectorType::MaxSizeAtCompileTime> PlainObject; | ||||
|  | ||||
|     inline const Derived& derived() const { return *static_cast<const Derived*>(this); } | ||||
|     inline Derived& derived() { return *static_cast<Derived*>(this); } | ||||
|  | ||||
|     DenseMatrixType toDenseMatrix() const { return derived(); } | ||||
|     template<typename DenseDerived> | ||||
|     void evalTo(MatrixBase<DenseDerived> &other) const; | ||||
|     template<typename DenseDerived> | ||||
|     void addTo(MatrixBase<DenseDerived> &other) const | ||||
|     { other.diagonal() += diagonal(); } | ||||
|     template<typename DenseDerived> | ||||
|     void subTo(MatrixBase<DenseDerived> &other) const | ||||
|     { other.diagonal() -= diagonal(); } | ||||
|  | ||||
|     inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); } | ||||
|     inline DiagonalVectorType& diagonal() { return derived().diagonal(); } | ||||
|  | ||||
|     inline Index rows() const { return diagonal().size(); } | ||||
|     inline Index cols() const { return diagonal().size(); } | ||||
|  | ||||
|     template<typename MatrixDerived> | ||||
|     const DiagonalProduct<MatrixDerived, Derived, OnTheLeft> | ||||
|     operator*(const MatrixBase<MatrixDerived> &matrix) const; | ||||
|  | ||||
|     inline const DiagonalWrapper<const CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const DiagonalVectorType> > | ||||
|     inverse() const | ||||
|     { | ||||
|       return diagonal().cwiseInverse(); | ||||
|     } | ||||
|      | ||||
|     inline const DiagonalWrapper<const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DiagonalVectorType> > | ||||
|     operator*(const Scalar& scalar) const | ||||
|     { | ||||
|       return diagonal() * scalar; | ||||
|     } | ||||
|     friend inline const DiagonalWrapper<const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DiagonalVectorType> > | ||||
|     operator*(const Scalar& scalar, const DiagonalBase& other) | ||||
|     { | ||||
|       return other.diagonal() * scalar; | ||||
|     } | ||||
|      | ||||
|     #ifdef EIGEN2_SUPPORT | ||||
|     template<typename OtherDerived> | ||||
|     bool isApprox(const DiagonalBase<OtherDerived>& other, typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) const | ||||
|     { | ||||
|       return diagonal().isApprox(other.diagonal(), precision); | ||||
|     } | ||||
|     template<typename OtherDerived> | ||||
|     bool isApprox(const MatrixBase<OtherDerived>& other, typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) const | ||||
|     { | ||||
|       return toDenseMatrix().isApprox(other, precision); | ||||
|     } | ||||
|     #endif | ||||
| }; | ||||
|  | ||||
| template<typename Derived> | ||||
| template<typename DenseDerived> | ||||
| void DiagonalBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const | ||||
| { | ||||
|   other.setZero(); | ||||
|   other.diagonal() = diagonal(); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| /** \class DiagonalMatrix | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Represents a diagonal matrix with its storage | ||||
|   * | ||||
|   * \param _Scalar the type of coefficients | ||||
|   * \param SizeAtCompileTime the dimension of the matrix, or Dynamic | ||||
|   * \param MaxSizeAtCompileTime the dimension of the matrix, or Dynamic. This parameter is optional and defaults | ||||
|   *        to SizeAtCompileTime. Most of the time, you do not need to specify it. | ||||
|   * | ||||
|   * \sa class DiagonalWrapper | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime> | ||||
| struct traits<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> > | ||||
|  : traits<Matrix<_Scalar,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> > | ||||
| { | ||||
|   typedef Matrix<_Scalar,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1> DiagonalVectorType; | ||||
|   typedef Dense StorageKind; | ||||
|   typedef DenseIndex Index; | ||||
|   enum { | ||||
|     Flags = LvalueBit | ||||
|   }; | ||||
| }; | ||||
| } | ||||
| template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime> | ||||
| class DiagonalMatrix | ||||
|   : public DiagonalBase<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> > | ||||
| { | ||||
|   public: | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     typedef typename internal::traits<DiagonalMatrix>::DiagonalVectorType DiagonalVectorType; | ||||
|     typedef const DiagonalMatrix& Nested; | ||||
|     typedef _Scalar Scalar; | ||||
|     typedef typename internal::traits<DiagonalMatrix>::StorageKind StorageKind; | ||||
|     typedef typename internal::traits<DiagonalMatrix>::Index Index; | ||||
|     #endif | ||||
|  | ||||
|   protected: | ||||
|  | ||||
|     DiagonalVectorType m_diagonal; | ||||
|  | ||||
|   public: | ||||
|  | ||||
|     /** const version of diagonal(). */ | ||||
|     inline const DiagonalVectorType& diagonal() const { return m_diagonal; } | ||||
|     /** \returns a reference to the stored vector of diagonal coefficients. */ | ||||
|     inline DiagonalVectorType& diagonal() { return m_diagonal; } | ||||
|  | ||||
|     /** Default constructor without initialization */ | ||||
|     inline DiagonalMatrix() {} | ||||
|  | ||||
|     /** Constructs a diagonal matrix with given dimension  */ | ||||
|     inline DiagonalMatrix(Index dim) : m_diagonal(dim) {} | ||||
|  | ||||
|     /** 2D constructor. */ | ||||
|     inline DiagonalMatrix(const Scalar& x, const Scalar& y) : m_diagonal(x,y) {} | ||||
|  | ||||
|     /** 3D constructor. */ | ||||
|     inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {} | ||||
|  | ||||
|     /** Copy constructor. */ | ||||
|     template<typename OtherDerived> | ||||
|     inline DiagonalMatrix(const DiagonalBase<OtherDerived>& other) : m_diagonal(other.diagonal()) {} | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /** copy constructor. prevent a default copy constructor from hiding the other templated constructor */ | ||||
|     inline DiagonalMatrix(const DiagonalMatrix& other) : m_diagonal(other.diagonal()) {} | ||||
|     #endif | ||||
|  | ||||
|     /** generic constructor from expression of the diagonal coefficients */ | ||||
|     template<typename OtherDerived> | ||||
|     explicit inline DiagonalMatrix(const MatrixBase<OtherDerived>& other) : m_diagonal(other) | ||||
|     {} | ||||
|  | ||||
|     /** Copy operator. */ | ||||
|     template<typename OtherDerived> | ||||
|     DiagonalMatrix& operator=(const DiagonalBase<OtherDerived>& other) | ||||
|     { | ||||
|       m_diagonal = other.diagonal(); | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /** This is a special case of the templated operator=. Its purpose is to | ||||
|       * prevent a default operator= from hiding the templated operator=. | ||||
|       */ | ||||
|     DiagonalMatrix& operator=(const DiagonalMatrix& other) | ||||
|     { | ||||
|       m_diagonal = other.diagonal(); | ||||
|       return *this; | ||||
|     } | ||||
|     #endif | ||||
|  | ||||
|     /** Resizes to given size. */ | ||||
|     inline void resize(Index size) { m_diagonal.resize(size); } | ||||
|     /** Sets all coefficients to zero. */ | ||||
|     inline void setZero() { m_diagonal.setZero(); } | ||||
|     /** Resizes and sets all coefficients to zero. */ | ||||
|     inline void setZero(Index size) { m_diagonal.setZero(size); } | ||||
|     /** Sets this matrix to be the identity matrix of the current size. */ | ||||
|     inline void setIdentity() { m_diagonal.setOnes(); } | ||||
|     /** Sets this matrix to be the identity matrix of the given size. */ | ||||
|     inline void setIdentity(Index size) { m_diagonal.setOnes(size); } | ||||
| }; | ||||
|  | ||||
| /** \class DiagonalWrapper | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Expression of a diagonal matrix | ||||
|   * | ||||
|   * \param _DiagonalVectorType the type of the vector of diagonal coefficients | ||||
|   * | ||||
|   * This class is an expression of a diagonal matrix, but not storing its own vector of diagonal coefficients, | ||||
|   * instead wrapping an existing vector expression. It is the return type of MatrixBase::asDiagonal() | ||||
|   * and most of the time this is the only way that it is used. | ||||
|   * | ||||
|   * \sa class DiagonalMatrix, class DiagonalBase, MatrixBase::asDiagonal() | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename _DiagonalVectorType> | ||||
| struct traits<DiagonalWrapper<_DiagonalVectorType> > | ||||
| { | ||||
|   typedef _DiagonalVectorType DiagonalVectorType; | ||||
|   typedef typename DiagonalVectorType::Scalar Scalar; | ||||
|   typedef typename DiagonalVectorType::Index Index; | ||||
|   typedef typename DiagonalVectorType::StorageKind StorageKind; | ||||
|   enum { | ||||
|     RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, | ||||
|     ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, | ||||
|     MaxRowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, | ||||
|     MaxColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, | ||||
|     Flags =  traits<DiagonalVectorType>::Flags & LvalueBit | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename _DiagonalVectorType> | ||||
| class DiagonalWrapper | ||||
|   : public DiagonalBase<DiagonalWrapper<_DiagonalVectorType> >, internal::no_assignment_operator | ||||
| { | ||||
|   public: | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     typedef _DiagonalVectorType DiagonalVectorType; | ||||
|     typedef DiagonalWrapper Nested; | ||||
|     #endif | ||||
|  | ||||
|     /** Constructor from expression of diagonal coefficients to wrap. */ | ||||
|     inline DiagonalWrapper(DiagonalVectorType& diagonal) : m_diagonal(diagonal) {} | ||||
|  | ||||
|     /** \returns a const reference to the wrapped expression of diagonal coefficients. */ | ||||
|     const DiagonalVectorType& diagonal() const { return m_diagonal; } | ||||
|  | ||||
|   protected: | ||||
|     typename DiagonalVectorType::Nested m_diagonal; | ||||
| }; | ||||
|  | ||||
| /** \returns a pseudo-expression of a diagonal matrix with *this as vector of diagonal coefficients | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * Example: \include MatrixBase_asDiagonal.cpp | ||||
|   * Output: \verbinclude MatrixBase_asDiagonal.out | ||||
|   * | ||||
|   * \sa class DiagonalWrapper, class DiagonalMatrix, diagonal(), isDiagonal() | ||||
|   **/ | ||||
| template<typename Derived> | ||||
| inline const DiagonalWrapper<const Derived> | ||||
| MatrixBase<Derived>::asDiagonal() const | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| /** \returns true if *this is approximately equal to a diagonal matrix, | ||||
|   *          within the precision given by \a prec. | ||||
|   * | ||||
|   * Example: \include MatrixBase_isDiagonal.cpp | ||||
|   * Output: \verbinclude MatrixBase_isDiagonal.out | ||||
|   * | ||||
|   * \sa asDiagonal() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| bool MatrixBase<Derived>::isDiagonal(RealScalar prec) const | ||||
| { | ||||
|   if(cols() != rows()) return false; | ||||
|   RealScalar maxAbsOnDiagonal = static_cast<RealScalar>(-1); | ||||
|   for(Index j = 0; j < cols(); ++j) | ||||
|   { | ||||
|     RealScalar absOnDiagonal = internal::abs(coeff(j,j)); | ||||
|     if(absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal; | ||||
|   } | ||||
|   for(Index j = 0; j < cols(); ++j) | ||||
|     for(Index i = 0; i < j; ++i) | ||||
|     { | ||||
|       if(!internal::isMuchSmallerThan(coeff(i, j), maxAbsOnDiagonal, prec)) return false; | ||||
|       if(!internal::isMuchSmallerThan(coeff(j, i), maxAbsOnDiagonal, prec)) return false; | ||||
|     } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_DIAGONALMATRIX_H | ||||
							
								
								
									
										123
									
								
								latan/Eigen/src/Core/DiagonalProduct.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								latan/Eigen/src/Core/DiagonalProduct.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,123 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_DIAGONALPRODUCT_H | ||||
| #define EIGEN_DIAGONALPRODUCT_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| namespace internal { | ||||
| template<typename MatrixType, typename DiagonalType, int ProductOrder> | ||||
| struct traits<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> > | ||||
|  : traits<MatrixType> | ||||
| { | ||||
|   typedef typename scalar_product_traits<typename MatrixType::Scalar, typename DiagonalType::Scalar>::ReturnType Scalar; | ||||
|   enum { | ||||
|     RowsAtCompileTime = MatrixType::RowsAtCompileTime, | ||||
|     ColsAtCompileTime = MatrixType::ColsAtCompileTime, | ||||
|     MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, | ||||
|     MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, | ||||
|  | ||||
|     _StorageOrder = MatrixType::Flags & RowMajorBit ? RowMajor : ColMajor, | ||||
|     _PacketOnDiag = !((int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheLeft) | ||||
|                     ||(int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheRight)), | ||||
|     _SameTypes = is_same<typename MatrixType::Scalar, typename DiagonalType::Scalar>::value, | ||||
|     // FIXME currently we need same types, but in the future the next rule should be the one | ||||
|     //_Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagonalType::Flags)&PacketAccessBit))), | ||||
|     _Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && _SameTypes && ((!_PacketOnDiag) || (bool(int(DiagonalType::Flags)&PacketAccessBit))), | ||||
|  | ||||
|     Flags = (HereditaryBits & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0), | ||||
|     CoeffReadCost = NumTraits<Scalar>::MulCost + MatrixType::CoeffReadCost + DiagonalType::DiagonalVectorType::CoeffReadCost | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename MatrixType, typename DiagonalType, int ProductOrder> | ||||
| class DiagonalProduct : internal::no_assignment_operator, | ||||
|                         public MatrixBase<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> > | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef MatrixBase<DiagonalProduct> Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(DiagonalProduct) | ||||
|  | ||||
|     inline DiagonalProduct(const MatrixType& matrix, const DiagonalType& diagonal) | ||||
|       : m_matrix(matrix), m_diagonal(diagonal) | ||||
|     { | ||||
|       eigen_assert(diagonal.diagonal().size() == (ProductOrder == OnTheLeft ? matrix.rows() : matrix.cols())); | ||||
|     } | ||||
|  | ||||
|     inline Index rows() const { return m_matrix.rows(); } | ||||
|     inline Index cols() const { return m_matrix.cols(); } | ||||
|  | ||||
|     const Scalar coeff(Index row, Index col) const | ||||
|     { | ||||
|       return m_diagonal.diagonal().coeff(ProductOrder == OnTheLeft ? row : col) * m_matrix.coeff(row, col); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const | ||||
|     { | ||||
|       enum { | ||||
|         StorageOrder = Flags & RowMajorBit ? RowMajor : ColMajor | ||||
|       }; | ||||
|       const Index indexInDiagonalVector = ProductOrder == OnTheLeft ? row : col; | ||||
|  | ||||
|       return packet_impl<LoadMode>(row,col,indexInDiagonalVector,typename internal::conditional< | ||||
|         ((int(StorageOrder) == RowMajor && int(ProductOrder) == OnTheLeft) | ||||
|        ||(int(StorageOrder) == ColMajor && int(ProductOrder) == OnTheRight)), internal::true_type, internal::false_type>::type()); | ||||
|     } | ||||
|  | ||||
|   protected: | ||||
|     template<int LoadMode> | ||||
|     EIGEN_STRONG_INLINE PacketScalar packet_impl(Index row, Index col, Index id, internal::true_type) const | ||||
|     { | ||||
|       return internal::pmul(m_matrix.template packet<LoadMode>(row, col), | ||||
|                      internal::pset1<PacketScalar>(m_diagonal.diagonal().coeff(id))); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     EIGEN_STRONG_INLINE PacketScalar packet_impl(Index row, Index col, Index id, internal::false_type) const | ||||
|     { | ||||
|       enum { | ||||
|         InnerSize = (MatrixType::Flags & RowMajorBit) ? MatrixType::ColsAtCompileTime : MatrixType::RowsAtCompileTime, | ||||
|         DiagonalVectorPacketLoadMode = (LoadMode == Aligned && ((InnerSize%16) == 0)) ? Aligned : Unaligned | ||||
|       }; | ||||
|       return internal::pmul(m_matrix.template packet<LoadMode>(row, col), | ||||
|                      m_diagonal.diagonal().template packet<DiagonalVectorPacketLoadMode>(id)); | ||||
|     } | ||||
|  | ||||
|     typename MatrixType::Nested m_matrix; | ||||
|     typename DiagonalType::Nested m_diagonal; | ||||
| }; | ||||
|  | ||||
| /** \returns the diagonal matrix product of \c *this by the diagonal matrix \a diagonal. | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename DiagonalDerived> | ||||
| inline const DiagonalProduct<Derived, DiagonalDerived, OnTheRight> | ||||
| MatrixBase<Derived>::operator*(const DiagonalBase<DiagonalDerived> &diagonal) const | ||||
| { | ||||
|   return DiagonalProduct<Derived, DiagonalDerived, OnTheRight>(derived(), diagonal.derived()); | ||||
| } | ||||
|  | ||||
| /** \returns the diagonal matrix product of \c *this by the matrix \a matrix. | ||||
|   */ | ||||
| template<typename DiagonalDerived> | ||||
| template<typename MatrixDerived> | ||||
| inline const DiagonalProduct<MatrixDerived, DiagonalDerived, OnTheLeft> | ||||
| DiagonalBase<DiagonalDerived>::operator*(const MatrixBase<MatrixDerived> &matrix) const | ||||
| { | ||||
|   return DiagonalProduct<MatrixDerived, DiagonalDerived, OnTheLeft>(matrix.derived(), derived()); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_DIAGONALPRODUCT_H | ||||
							
								
								
									
										261
									
								
								latan/Eigen/src/Core/Dot.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										261
									
								
								latan/Eigen/src/Core/Dot.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,261 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2006-2008, 2010 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_DOT_H | ||||
| #define EIGEN_DOT_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| // helper function for dot(). The problem is that if we put that in the body of dot(), then upon calling dot | ||||
| // with mismatched types, the compiler emits errors about failing to instantiate cwiseProduct BEFORE | ||||
| // looking at the static assertions. Thus this is a trick to get better compile errors. | ||||
| template<typename T, typename U, | ||||
| // the NeedToTranspose condition here is taken straight from Assign.h | ||||
|          bool NeedToTranspose = T::IsVectorAtCompileTime | ||||
|                 && U::IsVectorAtCompileTime | ||||
|                 && ((int(T::RowsAtCompileTime) == 1 && int(U::ColsAtCompileTime) == 1) | ||||
|                       |  // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&". | ||||
|                          // revert to || as soon as not needed anymore. | ||||
|                     (int(T::ColsAtCompileTime) == 1 && int(U::RowsAtCompileTime) == 1)) | ||||
| > | ||||
| struct dot_nocheck | ||||
| { | ||||
|   typedef typename scalar_product_traits<typename traits<T>::Scalar,typename traits<U>::Scalar>::ReturnType ResScalar; | ||||
|   static inline ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b) | ||||
|   { | ||||
|     return a.template binaryExpr<scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> >(b).sum(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename T, typename U> | ||||
| struct dot_nocheck<T, U, true> | ||||
| { | ||||
|   typedef typename scalar_product_traits<typename traits<T>::Scalar,typename traits<U>::Scalar>::ReturnType ResScalar; | ||||
|   static inline ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b) | ||||
|   { | ||||
|     return a.transpose().template binaryExpr<scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> >(b).sum(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /** \returns the dot product of *this with other. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * \note If the scalar type is complex numbers, then this function returns the hermitian | ||||
|   * (sesquilinear) dot product, conjugate-linear in the first variable and linear in the | ||||
|   * second variable. | ||||
|   * | ||||
|   * \sa squaredNorm(), norm() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| typename internal::scalar_product_traits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType | ||||
| MatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) | ||||
|   EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived) | ||||
|   typedef internal::scalar_conj_product_op<Scalar,typename OtherDerived::Scalar> func; | ||||
|   EIGEN_CHECK_BINARY_COMPATIBILIY(func,Scalar,typename OtherDerived::Scalar); | ||||
|  | ||||
|   eigen_assert(size() == other.size()); | ||||
|  | ||||
|   return internal::dot_nocheck<Derived,OtherDerived>::run(*this, other); | ||||
| } | ||||
|  | ||||
| #ifdef EIGEN2_SUPPORT | ||||
| /** \returns the dot product of *this with other, with the Eigen2 convention that the dot product is linear in the first variable | ||||
|   * (conjugating the second variable). Of course this only makes a difference in the complex case. | ||||
|   * | ||||
|   * This method is only available in EIGEN2_SUPPORT mode. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * \sa dot() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| typename internal::traits<Derived>::Scalar | ||||
| MatrixBase<Derived>::eigen2_dot(const MatrixBase<OtherDerived>& other) const | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) | ||||
|   EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived) | ||||
|   EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value), | ||||
|     YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) | ||||
|  | ||||
|   eigen_assert(size() == other.size()); | ||||
|  | ||||
|   return internal::dot_nocheck<OtherDerived,Derived>::run(other,*this); | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| //---------- implementation of L2 norm and related functions ---------- | ||||
|  | ||||
| /** \returns, for vectors, the squared \em l2 norm of \c *this, and for matrices the Frobenius norm. | ||||
|   * In both cases, it consists in the sum of the square of all the matrix entries. | ||||
|   * For vectors, this is also equals to the dot product of \c *this with itself. | ||||
|   * | ||||
|   * \sa dot(), norm() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::squaredNorm() const | ||||
| { | ||||
|   return internal::real((*this).cwiseAbs2().sum()); | ||||
| } | ||||
|  | ||||
| /** \returns, for vectors, the \em l2 norm of \c *this, and for matrices the Frobenius norm. | ||||
|   * In both cases, it consists in the square root of the sum of the square of all the matrix entries. | ||||
|   * For vectors, this is also equals to the square root of the dot product of \c *this with itself. | ||||
|   * | ||||
|   * \sa dot(), squaredNorm() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const | ||||
| { | ||||
|   return internal::sqrt(squaredNorm()); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of the quotient of *this by its own norm. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * \sa norm(), normalize() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline const typename MatrixBase<Derived>::PlainObject | ||||
| MatrixBase<Derived>::normalized() const | ||||
| { | ||||
|   typedef typename internal::nested<Derived>::type Nested; | ||||
|   typedef typename internal::remove_reference<Nested>::type _Nested; | ||||
|   _Nested n(derived()); | ||||
|   return n / n.norm(); | ||||
| } | ||||
|  | ||||
| /** Normalizes the vector, i.e. divides it by its own norm. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * \sa norm(), normalized() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline void MatrixBase<Derived>::normalize() | ||||
| { | ||||
|   *this /= norm(); | ||||
| } | ||||
|  | ||||
| //---------- implementation of other norms ---------- | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename Derived, int p> | ||||
| struct lpNorm_selector | ||||
| { | ||||
|   typedef typename NumTraits<typename traits<Derived>::Scalar>::Real RealScalar; | ||||
|   static inline RealScalar run(const MatrixBase<Derived>& m) | ||||
|   { | ||||
|     return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived> | ||||
| struct lpNorm_selector<Derived, 1> | ||||
| { | ||||
|   static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m) | ||||
|   { | ||||
|     return m.cwiseAbs().sum(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived> | ||||
| struct lpNorm_selector<Derived, 2> | ||||
| { | ||||
|   static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m) | ||||
|   { | ||||
|     return m.norm(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived> | ||||
| struct lpNorm_selector<Derived, Infinity> | ||||
| { | ||||
|   static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m) | ||||
|   { | ||||
|     return m.cwiseAbs().maxCoeff(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /** \returns the \f$ \ell^p \f$ norm of *this, that is, returns the p-th root of the sum of the p-th powers of the absolute values | ||||
|   *          of the coefficients of *this. If \a p is the special value \a Eigen::Infinity, this function returns the \f$ \ell^\infty \f$ | ||||
|   *          norm, that is the maximum of the absolute values of the coefficients of *this. | ||||
|   * | ||||
|   * \sa norm() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<int p> | ||||
| inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real | ||||
| MatrixBase<Derived>::lpNorm() const | ||||
| { | ||||
|   return internal::lpNorm_selector<Derived, p>::run(*this); | ||||
| } | ||||
|  | ||||
| //---------- implementation of isOrthogonal / isUnitary ---------- | ||||
|  | ||||
| /** \returns true if *this is approximately orthogonal to \a other, | ||||
|   *          within the precision given by \a prec. | ||||
|   * | ||||
|   * Example: \include MatrixBase_isOrthogonal.cpp | ||||
|   * Output: \verbinclude MatrixBase_isOrthogonal.out | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| bool MatrixBase<Derived>::isOrthogonal | ||||
| (const MatrixBase<OtherDerived>& other, RealScalar prec) const | ||||
| { | ||||
|   typename internal::nested<Derived,2>::type nested(derived()); | ||||
|   typename internal::nested<OtherDerived,2>::type otherNested(other.derived()); | ||||
|   return internal::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm(); | ||||
| } | ||||
|  | ||||
| /** \returns true if *this is approximately an unitary matrix, | ||||
|   *          within the precision given by \a prec. In the case where the \a Scalar | ||||
|   *          type is real numbers, a unitary matrix is an orthogonal matrix, whence the name. | ||||
|   * | ||||
|   * \note This can be used to check whether a family of vectors forms an orthonormal basis. | ||||
|   *       Indeed, \c m.isUnitary() returns true if and only if the columns (equivalently, the rows) of m form an | ||||
|   *       orthonormal basis. | ||||
|   * | ||||
|   * Example: \include MatrixBase_isUnitary.cpp | ||||
|   * Output: \verbinclude MatrixBase_isUnitary.out | ||||
|   */ | ||||
| template<typename Derived> | ||||
| bool MatrixBase<Derived>::isUnitary(RealScalar prec) const | ||||
| { | ||||
|   typename Derived::Nested nested(derived()); | ||||
|   for(Index i = 0; i < cols(); ++i) | ||||
|   { | ||||
|     if(!internal::isApprox(nested.col(i).squaredNorm(), static_cast<RealScalar>(1), prec)) | ||||
|       return false; | ||||
|     for(Index j = 0; j < i; ++j) | ||||
|       if(!internal::isMuchSmallerThan(nested.col(i).dot(nested.col(j)), static_cast<Scalar>(1), prec)) | ||||
|         return false; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_DOT_H | ||||
							
								
								
									
										160
									
								
								latan/Eigen/src/Core/EigenBase.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								latan/Eigen/src/Core/EigenBase.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,160 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_EIGENBASE_H | ||||
| #define EIGEN_EIGENBASE_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| /** Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T). | ||||
|   * | ||||
|   * In other words, an EigenBase object is an object that can be copied into a MatrixBase. | ||||
|   * | ||||
|   * Besides MatrixBase-derived classes, this also includes special matrix classes such as diagonal matrices, etc. | ||||
|   * | ||||
|   * Notice that this class is trivial, it is only used to disambiguate overloaded functions. | ||||
|   * | ||||
|   * \sa \ref TopicClassHierarchy | ||||
|   */ | ||||
| template<typename Derived> struct EigenBase | ||||
| { | ||||
| //   typedef typename internal::plain_matrix_type<Derived>::type PlainObject; | ||||
|  | ||||
|   typedef typename internal::traits<Derived>::StorageKind StorageKind; | ||||
|   typedef typename internal::traits<Derived>::Index Index; | ||||
|  | ||||
|   /** \returns a reference to the derived object */ | ||||
|   Derived& derived() { return *static_cast<Derived*>(this); } | ||||
|   /** \returns a const reference to the derived object */ | ||||
|   const Derived& derived() const { return *static_cast<const Derived*>(this); } | ||||
|  | ||||
|   inline Derived& const_cast_derived() const | ||||
|   { return *static_cast<Derived*>(const_cast<EigenBase*>(this)); } | ||||
|   inline const Derived& const_derived() const | ||||
|   { return *static_cast<const Derived*>(this); } | ||||
|  | ||||
|   /** \returns the number of rows. \sa cols(), RowsAtCompileTime */ | ||||
|   inline Index rows() const { return derived().rows(); } | ||||
|   /** \returns the number of columns. \sa rows(), ColsAtCompileTime*/ | ||||
|   inline Index cols() const { return derived().cols(); } | ||||
|   /** \returns the number of coefficients, which is rows()*cols(). | ||||
|     * \sa rows(), cols(), SizeAtCompileTime. */ | ||||
|   inline Index size() const { return rows() * cols(); } | ||||
|  | ||||
|   /** \internal Don't use it, but do the equivalent: \code dst = *this; \endcode */ | ||||
|   template<typename Dest> inline void evalTo(Dest& dst) const | ||||
|   { derived().evalTo(dst); } | ||||
|  | ||||
|   /** \internal Don't use it, but do the equivalent: \code dst += *this; \endcode */ | ||||
|   template<typename Dest> inline void addTo(Dest& dst) const | ||||
|   { | ||||
|     // This is the default implementation, | ||||
|     // derived class can reimplement it in a more optimized way. | ||||
|     typename Dest::PlainObject res(rows(),cols()); | ||||
|     evalTo(res); | ||||
|     dst += res; | ||||
|   } | ||||
|  | ||||
|   /** \internal Don't use it, but do the equivalent: \code dst -= *this; \endcode */ | ||||
|   template<typename Dest> inline void subTo(Dest& dst) const | ||||
|   { | ||||
|     // This is the default implementation, | ||||
|     // derived class can reimplement it in a more optimized way. | ||||
|     typename Dest::PlainObject res(rows(),cols()); | ||||
|     evalTo(res); | ||||
|     dst -= res; | ||||
|   } | ||||
|  | ||||
|   /** \internal Don't use it, but do the equivalent: \code dst.applyOnTheRight(*this); \endcode */ | ||||
|   template<typename Dest> inline void applyThisOnTheRight(Dest& dst) const | ||||
|   { | ||||
|     // This is the default implementation, | ||||
|     // derived class can reimplement it in a more optimized way. | ||||
|     dst = dst * this->derived(); | ||||
|   } | ||||
|  | ||||
|   /** \internal Don't use it, but do the equivalent: \code dst.applyOnTheLeft(*this); \endcode */ | ||||
|   template<typename Dest> inline void applyThisOnTheLeft(Dest& dst) const | ||||
|   { | ||||
|     // This is the default implementation, | ||||
|     // derived class can reimplement it in a more optimized way. | ||||
|     dst = this->derived() * dst; | ||||
|   } | ||||
|  | ||||
| }; | ||||
|  | ||||
| /*************************************************************************** | ||||
| * Implementation of matrix base methods | ||||
| ***************************************************************************/ | ||||
|  | ||||
| /** \brief Copies the generic expression \a other into *this. | ||||
|   * | ||||
|   * \details The expression must provide a (templated) evalTo(Derived& dst) const | ||||
|   * function which does the actual job. In practice, this allows any user to write | ||||
|   * its own special matrix without having to modify MatrixBase | ||||
|   * | ||||
|   * \returns a reference to *this. | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| Derived& DenseBase<Derived>::operator=(const EigenBase<OtherDerived> &other) | ||||
| { | ||||
|   other.derived().evalTo(derived()); | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| Derived& DenseBase<Derived>::operator+=(const EigenBase<OtherDerived> &other) | ||||
| { | ||||
|   other.derived().addTo(derived()); | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| Derived& DenseBase<Derived>::operator-=(const EigenBase<OtherDerived> &other) | ||||
| { | ||||
|   other.derived().subTo(derived()); | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| /** replaces \c *this by \c *this * \a other. | ||||
|   * | ||||
|   * \returns a reference to \c *this | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| inline Derived& | ||||
| MatrixBase<Derived>::operator*=(const EigenBase<OtherDerived> &other) | ||||
| { | ||||
|   other.derived().applyThisOnTheRight(derived()); | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| /** replaces \c *this by \c *this * \a other. It is equivalent to MatrixBase::operator*=() */ | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| inline void MatrixBase<Derived>::applyOnTheRight(const EigenBase<OtherDerived> &other) | ||||
| { | ||||
|   other.derived().applyThisOnTheRight(derived()); | ||||
| } | ||||
|  | ||||
| /** replaces \c *this by \c *this * \a other. */ | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| inline void MatrixBase<Derived>::applyOnTheLeft(const EigenBase<OtherDerived> &other) | ||||
| { | ||||
|   other.derived().applyThisOnTheLeft(derived()); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_EIGENBASE_H | ||||
							
								
								
									
										140
									
								
								latan/Eigen/src/Core/Flagged.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								latan/Eigen/src/Core/Flagged.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,140 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_FLAGGED_H | ||||
| #define EIGEN_FLAGGED_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class Flagged | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Expression with modified flags | ||||
|   * | ||||
|   * \param ExpressionType the type of the object of which we are modifying the flags | ||||
|   * \param Added the flags added to the expression | ||||
|   * \param Removed the flags removed from the expression (has priority over Added). | ||||
|   * | ||||
|   * This class represents an expression whose flags have been modified. | ||||
|   * It is the return type of MatrixBase::flagged() | ||||
|   * and most of the time this is the only way it is used. | ||||
|   * | ||||
|   * \sa MatrixBase::flagged() | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename ExpressionType, unsigned int Added, unsigned int Removed> | ||||
| struct traits<Flagged<ExpressionType, Added, Removed> > : traits<ExpressionType> | ||||
| { | ||||
|   enum { Flags = (ExpressionType::Flags | Added) & ~Removed }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename ExpressionType, unsigned int Added, unsigned int Removed> class Flagged | ||||
|   : public MatrixBase<Flagged<ExpressionType, Added, Removed> > | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef MatrixBase<Flagged> Base; | ||||
|      | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(Flagged) | ||||
|     typedef typename internal::conditional<internal::must_nest_by_value<ExpressionType>::ret, | ||||
|         ExpressionType, const ExpressionType&>::type ExpressionTypeNested; | ||||
|     typedef typename ExpressionType::InnerIterator InnerIterator; | ||||
|  | ||||
|     inline Flagged(const ExpressionType& matrix) : m_matrix(matrix) {} | ||||
|  | ||||
|     inline Index rows() const { return m_matrix.rows(); } | ||||
|     inline Index cols() const { return m_matrix.cols(); } | ||||
|     inline Index outerStride() const { return m_matrix.outerStride(); } | ||||
|     inline Index innerStride() const { return m_matrix.innerStride(); } | ||||
|  | ||||
|     inline CoeffReturnType coeff(Index row, Index col) const | ||||
|     { | ||||
|       return m_matrix.coeff(row, col); | ||||
|     } | ||||
|  | ||||
|     inline CoeffReturnType coeff(Index index) const | ||||
|     { | ||||
|       return m_matrix.coeff(index); | ||||
|     } | ||||
|      | ||||
|     inline const Scalar& coeffRef(Index row, Index col) const | ||||
|     { | ||||
|       return m_matrix.const_cast_derived().coeffRef(row, col); | ||||
|     } | ||||
|  | ||||
|     inline const Scalar& coeffRef(Index index) const | ||||
|     { | ||||
|       return m_matrix.const_cast_derived().coeffRef(index); | ||||
|     } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index row, Index col) | ||||
|     { | ||||
|       return m_matrix.const_cast_derived().coeffRef(row, col); | ||||
|     } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index index) | ||||
|     { | ||||
|       return m_matrix.const_cast_derived().coeffRef(index); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline const PacketScalar packet(Index row, Index col) const | ||||
|     { | ||||
|       return m_matrix.template packet<LoadMode>(row, col); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline void writePacket(Index row, Index col, const PacketScalar& x) | ||||
|     { | ||||
|       m_matrix.const_cast_derived().template writePacket<LoadMode>(row, col, x); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline const PacketScalar packet(Index index) const | ||||
|     { | ||||
|       return m_matrix.template packet<LoadMode>(index); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline void writePacket(Index index, const PacketScalar& x) | ||||
|     { | ||||
|       m_matrix.const_cast_derived().template writePacket<LoadMode>(index, x); | ||||
|     } | ||||
|  | ||||
|     const ExpressionType& _expression() const { return m_matrix; } | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     typename ExpressionType::PlainObject solveTriangular(const MatrixBase<OtherDerived>& other) const; | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     void solveTriangularInPlace(const MatrixBase<OtherDerived>& other) const; | ||||
|  | ||||
|   protected: | ||||
|     ExpressionTypeNested m_matrix; | ||||
| }; | ||||
|  | ||||
| /** \returns an expression of *this with added and removed flags | ||||
|   * | ||||
|   * This is mostly for internal use. | ||||
|   * | ||||
|   * \sa class Flagged | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<unsigned int Added,unsigned int Removed> | ||||
| inline const Flagged<Derived, Added, Removed> | ||||
| DenseBase<Derived>::flagged() const | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_FLAGGED_H | ||||
							
								
								
									
										146
									
								
								latan/Eigen/src/Core/ForceAlignedAccess.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								latan/Eigen/src/Core/ForceAlignedAccess.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,146 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_FORCEALIGNEDACCESS_H | ||||
| #define EIGEN_FORCEALIGNEDACCESS_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| /** \class ForceAlignedAccess | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Enforce aligned packet loads and stores regardless of what is requested | ||||
|   * | ||||
|   * \param ExpressionType the type of the object of which we are forcing aligned packet access | ||||
|   * | ||||
|   * This class is the return type of MatrixBase::forceAlignedAccess() | ||||
|   * and most of the time this is the only way it is used. | ||||
|   * | ||||
|   * \sa MatrixBase::forceAlignedAccess() | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename ExpressionType> | ||||
| struct traits<ForceAlignedAccess<ExpressionType> > : public traits<ExpressionType> | ||||
| {}; | ||||
| } | ||||
|  | ||||
| template<typename ExpressionType> class ForceAlignedAccess | ||||
|   : public internal::dense_xpr_base< ForceAlignedAccess<ExpressionType> >::type | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef typename internal::dense_xpr_base<ForceAlignedAccess>::type Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(ForceAlignedAccess) | ||||
|  | ||||
|     inline ForceAlignedAccess(const ExpressionType& matrix) : m_expression(matrix) {} | ||||
|  | ||||
|     inline Index rows() const { return m_expression.rows(); } | ||||
|     inline Index cols() const { return m_expression.cols(); } | ||||
|     inline Index outerStride() const { return m_expression.outerStride(); } | ||||
|     inline Index innerStride() const { return m_expression.innerStride(); } | ||||
|  | ||||
|     inline const CoeffReturnType coeff(Index row, Index col) const | ||||
|     { | ||||
|       return m_expression.coeff(row, col); | ||||
|     } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index row, Index col) | ||||
|     { | ||||
|       return m_expression.const_cast_derived().coeffRef(row, col); | ||||
|     } | ||||
|  | ||||
|     inline const CoeffReturnType coeff(Index index) const | ||||
|     { | ||||
|       return m_expression.coeff(index); | ||||
|     } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index index) | ||||
|     { | ||||
|       return m_expression.const_cast_derived().coeffRef(index); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline const PacketScalar packet(Index row, Index col) const | ||||
|     { | ||||
|       return m_expression.template packet<Aligned>(row, col); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline void writePacket(Index row, Index col, const PacketScalar& x) | ||||
|     { | ||||
|       m_expression.const_cast_derived().template writePacket<Aligned>(row, col, x); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline const PacketScalar packet(Index index) const | ||||
|     { | ||||
|       return m_expression.template packet<Aligned>(index); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline void writePacket(Index index, const PacketScalar& x) | ||||
|     { | ||||
|       m_expression.const_cast_derived().template writePacket<Aligned>(index, x); | ||||
|     } | ||||
|  | ||||
|     operator const ExpressionType&() const { return m_expression; } | ||||
|  | ||||
|   protected: | ||||
|     const ExpressionType& m_expression; | ||||
|  | ||||
|   private: | ||||
|     ForceAlignedAccess& operator=(const ForceAlignedAccess&); | ||||
| }; | ||||
|  | ||||
| /** \returns an expression of *this with forced aligned access | ||||
|   * \sa forceAlignedAccessIf(),class ForceAlignedAccess | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline const ForceAlignedAccess<Derived> | ||||
| MatrixBase<Derived>::forceAlignedAccess() const | ||||
| { | ||||
|   return ForceAlignedAccess<Derived>(derived()); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of *this with forced aligned access | ||||
|   * \sa forceAlignedAccessIf(), class ForceAlignedAccess | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline ForceAlignedAccess<Derived> | ||||
| MatrixBase<Derived>::forceAlignedAccess() | ||||
| { | ||||
|   return ForceAlignedAccess<Derived>(derived()); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of *this with forced aligned access if \a Enable is true. | ||||
|   * \sa forceAlignedAccess(), class ForceAlignedAccess | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<bool Enable> | ||||
| inline typename internal::add_const_on_value_type<typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type>::type | ||||
| MatrixBase<Derived>::forceAlignedAccessIf() const | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of *this with forced aligned access if \a Enable is true. | ||||
|   * \sa forceAlignedAccess(), class ForceAlignedAccess | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<bool Enable> | ||||
| inline typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type | ||||
| MatrixBase<Derived>::forceAlignedAccessIf() | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_FORCEALIGNEDACCESS_H | ||||
							
								
								
									
										975
									
								
								latan/Eigen/src/Core/Functors.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										975
									
								
								latan/Eigen/src/Core/Functors.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,975 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_FUNCTORS_H | ||||
| #define EIGEN_FUNCTORS_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| // associative functors: | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the sum of two scalars | ||||
|   * | ||||
|   * \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, MatrixBase::sum() | ||||
|   */ | ||||
| template<typename Scalar> struct scalar_sum_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_sum_op) | ||||
|   EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; } | ||||
|   template<typename Packet> | ||||
|   EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const | ||||
|   { return internal::padd(a,b); } | ||||
|   template<typename Packet> | ||||
|   EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const | ||||
|   { return internal::predux(a); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_sum_op<Scalar> > { | ||||
|   enum { | ||||
|     Cost = NumTraits<Scalar>::AddCost, | ||||
|     PacketAccess = packet_traits<Scalar>::HasAdd | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the product of two scalars | ||||
|   * | ||||
|   * \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux() | ||||
|   */ | ||||
| template<typename LhsScalar,typename RhsScalar> struct scalar_product_op { | ||||
|   enum { | ||||
|     // TODO vectorize mixed product | ||||
|     Vectorizable = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasMul && packet_traits<RhsScalar>::HasMul | ||||
|   }; | ||||
|   typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type; | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_product_op) | ||||
|   EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a * b; } | ||||
|   template<typename Packet> | ||||
|   EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const | ||||
|   { return internal::pmul(a,b); } | ||||
|   template<typename Packet> | ||||
|   EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const | ||||
|   { return internal::predux_mul(a); } | ||||
| }; | ||||
| template<typename LhsScalar,typename RhsScalar> | ||||
| struct functor_traits<scalar_product_op<LhsScalar,RhsScalar> > { | ||||
|   enum { | ||||
|     Cost = (NumTraits<LhsScalar>::MulCost + NumTraits<RhsScalar>::MulCost)/2, // rough estimate! | ||||
|     PacketAccess = scalar_product_op<LhsScalar,RhsScalar>::Vectorizable | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the conjugate product of two scalars | ||||
|   * | ||||
|   * This is a short cut for conj(x) * y which is needed for optimization purpose; in Eigen2 support mode, this becomes x * conj(y) | ||||
|   */ | ||||
| template<typename LhsScalar,typename RhsScalar> struct scalar_conj_product_op { | ||||
|  | ||||
|   enum { | ||||
|     Conj = NumTraits<LhsScalar>::IsComplex | ||||
|   }; | ||||
|    | ||||
|   typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type; | ||||
|    | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_conj_product_op) | ||||
|   EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const | ||||
|   { return conj_helper<LhsScalar,RhsScalar,Conj,false>().pmul(a,b); } | ||||
|    | ||||
|   template<typename Packet> | ||||
|   EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const | ||||
|   { return conj_helper<Packet,Packet,Conj,false>().pmul(a,b); } | ||||
| }; | ||||
| template<typename LhsScalar,typename RhsScalar> | ||||
| struct functor_traits<scalar_conj_product_op<LhsScalar,RhsScalar> > { | ||||
|   enum { | ||||
|     Cost = NumTraits<LhsScalar>::MulCost, | ||||
|     PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMul | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the min of two scalars | ||||
|   * | ||||
|   * \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff() | ||||
|   */ | ||||
| template<typename Scalar> struct scalar_min_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_min_op) | ||||
|   EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { using std::min; return (min)(a, b); } | ||||
|   template<typename Packet> | ||||
|   EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const | ||||
|   { return internal::pmin(a,b); } | ||||
|   template<typename Packet> | ||||
|   EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const | ||||
|   { return internal::predux_min(a); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_min_op<Scalar> > { | ||||
|   enum { | ||||
|     Cost = NumTraits<Scalar>::AddCost, | ||||
|     PacketAccess = packet_traits<Scalar>::HasMin | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the max of two scalars | ||||
|   * | ||||
|   * \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff() | ||||
|   */ | ||||
| template<typename Scalar> struct scalar_max_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_max_op) | ||||
|   EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { using std::max; return (max)(a, b); } | ||||
|   template<typename Packet> | ||||
|   EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const | ||||
|   { return internal::pmax(a,b); } | ||||
|   template<typename Packet> | ||||
|   EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const | ||||
|   { return internal::predux_max(a); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_max_op<Scalar> > { | ||||
|   enum { | ||||
|     Cost = NumTraits<Scalar>::AddCost, | ||||
|     PacketAccess = packet_traits<Scalar>::HasMax | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the hypot of two scalars | ||||
|   * | ||||
|   * \sa MatrixBase::stableNorm(), class Redux | ||||
|   */ | ||||
| template<typename Scalar> struct scalar_hypot_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_hypot_op) | ||||
| //   typedef typename NumTraits<Scalar>::Real result_type; | ||||
|   EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const | ||||
|   { | ||||
|     using std::max; | ||||
|     using std::min; | ||||
|     Scalar p = (max)(_x, _y); | ||||
|     Scalar q = (min)(_x, _y); | ||||
|     Scalar qp = q/p; | ||||
|     return p * sqrt(Scalar(1) + qp*qp); | ||||
|   } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_hypot_op<Scalar> > { | ||||
|   enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess=0 }; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the pow of two scalars | ||||
|   */ | ||||
| template<typename Scalar, typename OtherScalar> struct scalar_binary_pow_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_binary_pow_op) | ||||
|   inline Scalar operator() (const Scalar& a, const OtherScalar& b) const { return internal::pow(a, b); } | ||||
| }; | ||||
| template<typename Scalar, typename OtherScalar> | ||||
| struct functor_traits<scalar_binary_pow_op<Scalar,OtherScalar> > { | ||||
|   enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; | ||||
| }; | ||||
|  | ||||
| // other binary functors: | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the difference of two scalars | ||||
|   * | ||||
|   * \sa class CwiseBinaryOp, MatrixBase::operator- | ||||
|   */ | ||||
| template<typename Scalar> struct scalar_difference_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_difference_op) | ||||
|   EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; } | ||||
|   template<typename Packet> | ||||
|   EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const | ||||
|   { return internal::psub(a,b); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_difference_op<Scalar> > { | ||||
|   enum { | ||||
|     Cost = NumTraits<Scalar>::AddCost, | ||||
|     PacketAccess = packet_traits<Scalar>::HasSub | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the quotient of two scalars | ||||
|   * | ||||
|   * \sa class CwiseBinaryOp, Cwise::operator/() | ||||
|   */ | ||||
| template<typename Scalar> struct scalar_quotient_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_quotient_op) | ||||
|   EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; } | ||||
|   template<typename Packet> | ||||
|   EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const | ||||
|   { return internal::pdiv(a,b); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_quotient_op<Scalar> > { | ||||
|   enum { | ||||
|     Cost = 2 * NumTraits<Scalar>::MulCost, | ||||
|     PacketAccess = packet_traits<Scalar>::HasDiv | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the and of two booleans | ||||
|   * | ||||
|   * \sa class CwiseBinaryOp, ArrayBase::operator&& | ||||
|   */ | ||||
| struct scalar_boolean_and_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_and_op) | ||||
|   EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a && b; } | ||||
| }; | ||||
| template<> struct functor_traits<scalar_boolean_and_op> { | ||||
|   enum { | ||||
|     Cost = NumTraits<bool>::AddCost, | ||||
|     PacketAccess = false | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the or of two booleans | ||||
|   * | ||||
|   * \sa class CwiseBinaryOp, ArrayBase::operator|| | ||||
|   */ | ||||
| struct scalar_boolean_or_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_or_op) | ||||
|   EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a || b; } | ||||
| }; | ||||
| template<> struct functor_traits<scalar_boolean_or_op> { | ||||
|   enum { | ||||
|     Cost = NumTraits<bool>::AddCost, | ||||
|     PacketAccess = false | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| // unary functors: | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the opposite of a scalar | ||||
|   * | ||||
|   * \sa class CwiseUnaryOp, MatrixBase::operator- | ||||
|   */ | ||||
| template<typename Scalar> struct scalar_opposite_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_opposite_op) | ||||
|   EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; } | ||||
|   template<typename Packet> | ||||
|   EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const | ||||
|   { return internal::pnegate(a); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_opposite_op<Scalar> > | ||||
| { enum { | ||||
|     Cost = NumTraits<Scalar>::AddCost, | ||||
|     PacketAccess = packet_traits<Scalar>::HasNegate }; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the absolute value of a scalar | ||||
|   * | ||||
|   * \sa class CwiseUnaryOp, Cwise::abs | ||||
|   */ | ||||
| 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 internal::abs(a); } | ||||
|   template<typename Packet> | ||||
|   EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const | ||||
|   { return internal::pabs(a); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_abs_op<Scalar> > | ||||
| { | ||||
|   enum { | ||||
|     Cost = NumTraits<Scalar>::AddCost, | ||||
|     PacketAccess = packet_traits<Scalar>::HasAbs | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the squared absolute value of a scalar | ||||
|   * | ||||
|   * \sa class CwiseUnaryOp, Cwise::abs2 | ||||
|   */ | ||||
| template<typename Scalar> struct scalar_abs2_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_abs2_op) | ||||
|   typedef typename NumTraits<Scalar>::Real result_type; | ||||
|   EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return internal::abs2(a); } | ||||
|   template<typename Packet> | ||||
|   EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const | ||||
|   { return internal::pmul(a,a); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_abs2_op<Scalar> > | ||||
| { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasAbs2 }; }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the conjugate of a complex value | ||||
|   * | ||||
|   * \sa class CwiseUnaryOp, MatrixBase::conjugate() | ||||
|   */ | ||||
| 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 internal::conj(a); } | ||||
|   template<typename Packet> | ||||
|   EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pconj(a); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_conjugate_op<Scalar> > | ||||
| { | ||||
|   enum { | ||||
|     Cost = NumTraits<Scalar>::IsComplex ? NumTraits<Scalar>::AddCost : 0, | ||||
|     PacketAccess = packet_traits<Scalar>::HasConj | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to cast a scalar to another type | ||||
|   * | ||||
|   * \sa class CwiseUnaryOp, MatrixBase::cast() | ||||
|   */ | ||||
| template<typename Scalar, typename NewType> | ||||
| struct scalar_cast_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_cast_op) | ||||
|   typedef NewType result_type; | ||||
|   EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return cast<Scalar, NewType>(a); } | ||||
| }; | ||||
| template<typename Scalar, typename NewType> | ||||
| struct functor_traits<scalar_cast_op<Scalar,NewType> > | ||||
| { enum { Cost = is_same<Scalar, NewType>::value ? 0 : NumTraits<NewType>::AddCost, PacketAccess = false }; }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to extract the real part of a complex | ||||
|   * | ||||
|   * \sa class CwiseUnaryOp, MatrixBase::real() | ||||
|   */ | ||||
| template<typename Scalar> | ||||
| struct scalar_real_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_real_op) | ||||
|   typedef typename NumTraits<Scalar>::Real result_type; | ||||
|   EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return internal::real(a); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_real_op<Scalar> > | ||||
| { enum { Cost = 0, PacketAccess = false }; }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to extract the imaginary part of a complex | ||||
|   * | ||||
|   * \sa class CwiseUnaryOp, MatrixBase::imag() | ||||
|   */ | ||||
| template<typename Scalar> | ||||
| struct scalar_imag_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_op) | ||||
|   typedef typename NumTraits<Scalar>::Real result_type; | ||||
|   EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return internal::imag(a); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_imag_op<Scalar> > | ||||
| { enum { Cost = 0, PacketAccess = false }; }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to extract the real part of a complex as a reference | ||||
|   * | ||||
|   * \sa class CwiseUnaryOp, MatrixBase::real() | ||||
|   */ | ||||
| template<typename Scalar> | ||||
| struct scalar_real_ref_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_real_ref_op) | ||||
|   typedef typename NumTraits<Scalar>::Real result_type; | ||||
|   EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return internal::real_ref(*const_cast<Scalar*>(&a)); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_real_ref_op<Scalar> > | ||||
| { enum { Cost = 0, PacketAccess = false }; }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to extract the imaginary part of a complex as a reference | ||||
|   * | ||||
|   * \sa class CwiseUnaryOp, MatrixBase::imag() | ||||
|   */ | ||||
| template<typename Scalar> | ||||
| struct scalar_imag_ref_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_ref_op) | ||||
|   typedef typename NumTraits<Scalar>::Real result_type; | ||||
|   EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return internal::imag_ref(*const_cast<Scalar*>(&a)); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_imag_ref_op<Scalar> > | ||||
| { enum { Cost = 0, PacketAccess = false }; }; | ||||
|  | ||||
| /** \internal | ||||
|   * | ||||
|   * \brief Template functor to compute the exponential of a scalar | ||||
|   * | ||||
|   * \sa class CwiseUnaryOp, Cwise::exp() | ||||
|   */ | ||||
| template<typename Scalar> struct scalar_exp_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_exp_op) | ||||
|   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); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_exp_op<Scalar> > | ||||
| { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasExp }; }; | ||||
|  | ||||
| /** \internal | ||||
|   * | ||||
|   * \brief Template functor to compute the logarithm of a scalar | ||||
|   * | ||||
|   * \sa class CwiseUnaryOp, Cwise::log() | ||||
|   */ | ||||
| template<typename Scalar> struct scalar_log_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_log_op) | ||||
|   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); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_log_op<Scalar> > | ||||
| { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasLog }; }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to multiply a scalar by a fixed other one | ||||
|   * | ||||
|   * \sa class CwiseUnaryOp, MatrixBase::operator*, MatrixBase::operator/ | ||||
|   */ | ||||
| /* NOTE why doing the pset1() in packetOp *is* an optimization ? | ||||
|  * indeed it seems better to declare m_other as a Packet and do the pset1() once | ||||
|  * in the constructor. However, in practice: | ||||
|  *  - GCC does not like m_other as a Packet and generate a load every time it needs it | ||||
|  *  - on the other hand GCC is able to moves the pset1() outside the loop :) | ||||
|  *  - simpler code ;) | ||||
|  * (ICC and gcc 4.4 seems to perform well in both cases, the issue is visible with y = a*x + b*y) | ||||
|  */ | ||||
| template<typename Scalar> | ||||
| struct scalar_multiple_op { | ||||
|   typedef typename packet_traits<Scalar>::type Packet; | ||||
|   // FIXME default copy constructors seems bugged with std::complex<> | ||||
|   EIGEN_STRONG_INLINE scalar_multiple_op(const scalar_multiple_op& other) : m_other(other.m_other) { } | ||||
|   EIGEN_STRONG_INLINE scalar_multiple_op(const Scalar& other) : m_other(other) { } | ||||
|   EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; } | ||||
|   EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const | ||||
|   { return internal::pmul(a, pset1<Packet>(m_other)); } | ||||
|   typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other; | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_multiple_op<Scalar> > | ||||
| { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; }; | ||||
|  | ||||
| template<typename Scalar1, typename Scalar2> | ||||
| struct scalar_multiple2_op { | ||||
|   typedef typename scalar_product_traits<Scalar1,Scalar2>::ReturnType result_type; | ||||
|   EIGEN_STRONG_INLINE scalar_multiple2_op(const scalar_multiple2_op& other) : m_other(other.m_other) { } | ||||
|   EIGEN_STRONG_INLINE scalar_multiple2_op(const Scalar2& other) : m_other(other) { } | ||||
|   EIGEN_STRONG_INLINE result_type operator() (const Scalar1& a) const { return a * m_other; } | ||||
|   typename add_const_on_value_type<typename NumTraits<Scalar2>::Nested>::type m_other; | ||||
| }; | ||||
| template<typename Scalar1,typename Scalar2> | ||||
| struct functor_traits<scalar_multiple2_op<Scalar1,Scalar2> > | ||||
| { enum { Cost = NumTraits<Scalar1>::MulCost, PacketAccess = false }; }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to divide a scalar by a fixed other one | ||||
|   * | ||||
|   * This functor is used to implement the quotient of a matrix by | ||||
|   * a scalar where the scalar type is not necessarily a floating point type. | ||||
|   * | ||||
|   * \sa class CwiseUnaryOp, MatrixBase::operator/ | ||||
|   */ | ||||
| template<typename Scalar> | ||||
| struct scalar_quotient1_op { | ||||
|   typedef typename packet_traits<Scalar>::type Packet; | ||||
|   // FIXME default copy constructors seems bugged with std::complex<> | ||||
|   EIGEN_STRONG_INLINE scalar_quotient1_op(const scalar_quotient1_op& other) : m_other(other.m_other) { } | ||||
|   EIGEN_STRONG_INLINE scalar_quotient1_op(const Scalar& other) : m_other(other) {} | ||||
|   EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a / m_other; } | ||||
|   EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const | ||||
|   { return internal::pdiv(a, pset1<Packet>(m_other)); } | ||||
|   typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other; | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_quotient1_op<Scalar> > | ||||
| { enum { Cost = 2 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasDiv }; }; | ||||
|  | ||||
| // nullary functors | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct scalar_constant_op { | ||||
|   typedef typename packet_traits<Scalar>::type Packet; | ||||
|   EIGEN_STRONG_INLINE scalar_constant_op(const scalar_constant_op& other) : m_other(other.m_other) { } | ||||
|   EIGEN_STRONG_INLINE scalar_constant_op(const Scalar& other) : m_other(other) { } | ||||
|   template<typename Index> | ||||
|   EIGEN_STRONG_INLINE const Scalar operator() (Index, Index = 0) const { return m_other; } | ||||
|   template<typename Index> | ||||
|   EIGEN_STRONG_INLINE const Packet packetOp(Index, Index = 0) const { return internal::pset1<Packet>(m_other); } | ||||
|   const Scalar m_other; | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_constant_op<Scalar> > | ||||
| // FIXME replace this packet test by a safe one | ||||
| { enum { Cost = 1, PacketAccess = packet_traits<Scalar>::Vectorizable, IsRepeatable = true }; }; | ||||
|  | ||||
| template<typename Scalar> struct scalar_identity_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_identity_op) | ||||
|   template<typename Index> | ||||
|   EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const { return row==col ? Scalar(1) : Scalar(0); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_identity_op<Scalar> > | ||||
| { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true }; }; | ||||
|  | ||||
| template <typename Scalar, bool RandomAccess> struct linspaced_op_impl; | ||||
|  | ||||
| // linear access for packet ops: | ||||
| // 1) initialization | ||||
| //   base = [low, ..., low] + ([step, ..., step] * [-size, ..., 0]) | ||||
| // 2) each step (where size is 1 for coeff access or PacketSize for packet access) | ||||
| //   base += [size*step, ..., size*step] | ||||
| // | ||||
| // TODO: Perhaps it's better to initialize lazily (so not in the constructor but in packetOp) | ||||
| //       in order to avoid the padd() in operator() ? | ||||
| template <typename Scalar> | ||||
| struct linspaced_op_impl<Scalar,false> | ||||
| { | ||||
|   typedef typename packet_traits<Scalar>::type Packet; | ||||
|  | ||||
|   linspaced_op_impl(Scalar low, Scalar step) : | ||||
|   m_low(low), m_step(step), | ||||
|   m_packetStep(pset1<Packet>(packet_traits<Scalar>::size*step)), | ||||
|   m_base(padd(pset1<Packet>(low), pmul(pset1<Packet>(step),plset<Scalar>(-packet_traits<Scalar>::size)))) {} | ||||
|  | ||||
|   template<typename Index> | ||||
|   EIGEN_STRONG_INLINE const Scalar operator() (Index i) const  | ||||
|   {  | ||||
|     m_base = padd(m_base, pset1<Packet>(m_step)); | ||||
|     return m_low+i*m_step;  | ||||
|   } | ||||
|  | ||||
|   template<typename Index> | ||||
|   EIGEN_STRONG_INLINE const Packet packetOp(Index) const { return m_base = padd(m_base,m_packetStep); } | ||||
|  | ||||
|   const Scalar m_low; | ||||
|   const Scalar m_step; | ||||
|   const Packet m_packetStep; | ||||
|   mutable Packet m_base; | ||||
| }; | ||||
|  | ||||
| // random access for packet ops: | ||||
| // 1) each step | ||||
| //   [low, ..., low] + ( [step, ..., step] * ( [i, ..., i] + [0, ..., size] ) ) | ||||
| template <typename Scalar> | ||||
| struct linspaced_op_impl<Scalar,true> | ||||
| { | ||||
|   typedef typename packet_traits<Scalar>::type Packet; | ||||
|  | ||||
|   linspaced_op_impl(Scalar low, Scalar step) : | ||||
|   m_low(low), m_step(step), | ||||
|   m_lowPacket(pset1<Packet>(m_low)), m_stepPacket(pset1<Packet>(m_step)), m_interPacket(plset<Scalar>(0)) {} | ||||
|  | ||||
|   template<typename Index> | ||||
|   EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return m_low+i*m_step; } | ||||
|  | ||||
|   template<typename Index> | ||||
|   EIGEN_STRONG_INLINE const Packet packetOp(Index i) const | ||||
|   { return internal::padd(m_lowPacket, pmul(m_stepPacket, padd(pset1<Packet>(i),m_interPacket))); } | ||||
|  | ||||
|   const Scalar m_low; | ||||
|   const Scalar m_step; | ||||
|   const Packet m_lowPacket; | ||||
|   const Packet m_stepPacket; | ||||
|   const Packet m_interPacket; | ||||
| }; | ||||
|  | ||||
| // ----- Linspace functor ---------------------------------------------------------------- | ||||
|  | ||||
| // Forward declaration (we default to random access which does not really give | ||||
| // us a speed gain when using packet access but it allows to use the functor in | ||||
| // nested expressions). | ||||
| template <typename Scalar, bool RandomAccess = true> struct linspaced_op; | ||||
| template <typename Scalar, bool RandomAccess> struct functor_traits< linspaced_op<Scalar,RandomAccess> > | ||||
| { enum { Cost = 1, PacketAccess = packet_traits<Scalar>::HasSetLinear, IsRepeatable = true }; }; | ||||
| template <typename Scalar, bool RandomAccess> struct linspaced_op | ||||
| { | ||||
|   typedef typename packet_traits<Scalar>::type Packet; | ||||
|   linspaced_op(Scalar low, Scalar high, int num_steps) : impl((num_steps==1 ? high : low), (num_steps==1 ? Scalar() : (high-low)/(num_steps-1))) {} | ||||
|  | ||||
|   template<typename Index> | ||||
|   EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return impl(i); } | ||||
|  | ||||
|   // We need this function when assigning e.g. a RowVectorXd to a MatrixXd since | ||||
|   // there row==0 and col is used for the actual iteration. | ||||
|   template<typename Index> | ||||
|   EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const  | ||||
|   { | ||||
|     eigen_assert(col==0 || row==0); | ||||
|     return impl(col + row); | ||||
|   } | ||||
|  | ||||
|   template<typename Index> | ||||
|   EIGEN_STRONG_INLINE const Packet packetOp(Index i) const { return impl.packetOp(i); } | ||||
|  | ||||
|   // We need this function when assigning e.g. a RowVectorXd to a MatrixXd since | ||||
|   // there row==0 and col is used for the actual iteration. | ||||
|   template<typename Index> | ||||
|   EIGEN_STRONG_INLINE const Packet packetOp(Index row, Index col) const | ||||
|   { | ||||
|     eigen_assert(col==0 || row==0); | ||||
|     return impl.packetOp(col + row); | ||||
|   } | ||||
|  | ||||
|   // This proxy object handles the actual required temporaries, the different | ||||
|   // implementations (random vs. sequential access) as well as the | ||||
|   // correct piping to size 2/4 packet operations. | ||||
|   const linspaced_op_impl<Scalar,RandomAccess> impl; | ||||
| }; | ||||
|  | ||||
| // all functors allow linear access, except scalar_identity_op. So we fix here a quick meta | ||||
| // to indicate whether a functor allows linear access, just always answering 'yes' except for | ||||
| // scalar_identity_op. | ||||
| // FIXME move this to functor_traits adding a functor_default | ||||
| template<typename Functor> struct functor_has_linear_access { enum { ret = 1 }; }; | ||||
| template<typename Scalar> struct functor_has_linear_access<scalar_identity_op<Scalar> > { enum { ret = 0 }; }; | ||||
|  | ||||
| // in CwiseBinaryOp, we require the Lhs and Rhs to have the same scalar type, except for multiplication | ||||
| // where we only require them to have the same _real_ scalar type so one may multiply, say, float by complex<float>. | ||||
| // FIXME move this to functor_traits adding a functor_default | ||||
| template<typename Functor> struct functor_allows_mixing_real_and_complex { enum { ret = 0 }; }; | ||||
| template<typename LhsScalar,typename RhsScalar> struct functor_allows_mixing_real_and_complex<scalar_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; }; | ||||
| template<typename LhsScalar,typename RhsScalar> struct functor_allows_mixing_real_and_complex<scalar_conj_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; }; | ||||
|  | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to add a scalar to a fixed other one | ||||
|   * \sa class CwiseUnaryOp, Array::operator+ | ||||
|   */ | ||||
| /* If you wonder why doing the pset1() in packetOp() is an optimization check scalar_multiple_op */ | ||||
| template<typename Scalar> | ||||
| struct scalar_add_op { | ||||
|   typedef typename packet_traits<Scalar>::type Packet; | ||||
|   // FIXME default copy constructors seems bugged with std::complex<> | ||||
|   inline scalar_add_op(const scalar_add_op& other) : m_other(other.m_other) { } | ||||
|   inline scalar_add_op(const Scalar& other) : m_other(other) { } | ||||
|   inline Scalar operator() (const Scalar& a) const { return a + m_other; } | ||||
|   inline const Packet packetOp(const Packet& a) const | ||||
|   { return internal::padd(a, pset1<Packet>(m_other)); } | ||||
|   const Scalar m_other; | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_add_op<Scalar> > | ||||
| { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasAdd }; }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the square root of a scalar | ||||
|   * \sa class CwiseUnaryOp, Cwise::sqrt() | ||||
|   */ | ||||
| template<typename Scalar> struct scalar_sqrt_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op) | ||||
|   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); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_sqrt_op<Scalar> > | ||||
| { enum { | ||||
|     Cost = 5 * NumTraits<Scalar>::MulCost, | ||||
|     PacketAccess = packet_traits<Scalar>::HasSqrt | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the cosine of a scalar | ||||
|   * \sa class CwiseUnaryOp, ArrayBase::cos() | ||||
|   */ | ||||
| template<typename Scalar> struct scalar_cos_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op) | ||||
|   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); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_cos_op<Scalar> > | ||||
| { | ||||
|   enum { | ||||
|     Cost = 5 * NumTraits<Scalar>::MulCost, | ||||
|     PacketAccess = packet_traits<Scalar>::HasCos | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the sine of a scalar | ||||
|   * \sa class CwiseUnaryOp, ArrayBase::sin() | ||||
|   */ | ||||
| template<typename Scalar> struct scalar_sin_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op) | ||||
|   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); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_sin_op<Scalar> > | ||||
| { | ||||
|   enum { | ||||
|     Cost = 5 * NumTraits<Scalar>::MulCost, | ||||
|     PacketAccess = packet_traits<Scalar>::HasSin | ||||
|   }; | ||||
| }; | ||||
|  | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the tan of a scalar | ||||
|   * \sa class CwiseUnaryOp, ArrayBase::tan() | ||||
|   */ | ||||
| template<typename Scalar> struct scalar_tan_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op) | ||||
|   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); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_tan_op<Scalar> > | ||||
| { | ||||
|   enum { | ||||
|     Cost = 5 * NumTraits<Scalar>::MulCost, | ||||
|     PacketAccess = packet_traits<Scalar>::HasTan | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the arc cosine of a scalar | ||||
|   * \sa class CwiseUnaryOp, ArrayBase::acos() | ||||
|   */ | ||||
| template<typename Scalar> struct scalar_acos_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op) | ||||
|   inline const Scalar operator() (const Scalar& a) const { return internal::acos(a); } | ||||
|   typedef typename packet_traits<Scalar>::type Packet; | ||||
|   inline Packet packetOp(const Packet& a) const { return internal::pacos(a); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_acos_op<Scalar> > | ||||
| { | ||||
|   enum { | ||||
|     Cost = 5 * NumTraits<Scalar>::MulCost, | ||||
|     PacketAccess = packet_traits<Scalar>::HasACos | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the arc sine of a scalar | ||||
|   * \sa class CwiseUnaryOp, ArrayBase::asin() | ||||
|   */ | ||||
| template<typename Scalar> struct scalar_asin_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op) | ||||
|   inline const Scalar operator() (const Scalar& a) const { return internal::asin(a); } | ||||
|   typedef typename packet_traits<Scalar>::type Packet; | ||||
|   inline Packet packetOp(const Packet& a) const { return internal::pasin(a); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_asin_op<Scalar> > | ||||
| { | ||||
|   enum { | ||||
|     Cost = 5 * NumTraits<Scalar>::MulCost, | ||||
|     PacketAccess = packet_traits<Scalar>::HasASin | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to raise a scalar to a power | ||||
|   * \sa class CwiseUnaryOp, Cwise::pow | ||||
|   */ | ||||
| template<typename Scalar> | ||||
| struct scalar_pow_op { | ||||
|   // FIXME default copy constructors seems bugged with std::complex<> | ||||
|   inline scalar_pow_op(const scalar_pow_op& other) : m_exponent(other.m_exponent) { } | ||||
|   inline scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {} | ||||
|   inline Scalar operator() (const Scalar& a) const { return internal::pow(a, m_exponent); } | ||||
|   const Scalar m_exponent; | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_pow_op<Scalar> > | ||||
| { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the quotient between a scalar and array entries. | ||||
|   * \sa class CwiseUnaryOp, Cwise::inverse() | ||||
|   */ | ||||
| template<typename Scalar> | ||||
| struct scalar_inverse_mult_op { | ||||
|   scalar_inverse_mult_op(const Scalar& other) : m_other(other) {} | ||||
|   inline Scalar operator() (const Scalar& a) const { return m_other / a; } | ||||
|   template<typename Packet> | ||||
|   inline const Packet packetOp(const Packet& a) const | ||||
|   { return internal::pdiv(pset1<Packet>(m_other),a); } | ||||
|   Scalar m_other; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the inverse of a scalar | ||||
|   * \sa class CwiseUnaryOp, Cwise::inverse() | ||||
|   */ | ||||
| template<typename Scalar> | ||||
| struct scalar_inverse_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_inverse_op) | ||||
|   inline Scalar operator() (const Scalar& a) const { return Scalar(1)/a; } | ||||
|   template<typename Packet> | ||||
|   inline const Packet packetOp(const Packet& a) const | ||||
|   { return internal::pdiv(pset1<Packet>(Scalar(1)),a); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_inverse_op<Scalar> > | ||||
| { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasDiv }; }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the square of a scalar | ||||
|   * \sa class CwiseUnaryOp, Cwise::square() | ||||
|   */ | ||||
| template<typename Scalar> | ||||
| struct scalar_square_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_square_op) | ||||
|   inline Scalar operator() (const Scalar& a) const { return a*a; } | ||||
|   template<typename Packet> | ||||
|   inline const Packet packetOp(const Packet& a) const | ||||
|   { return internal::pmul(a,a); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_square_op<Scalar> > | ||||
| { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Template functor to compute the cube of a scalar | ||||
|   * \sa class CwiseUnaryOp, Cwise::cube() | ||||
|   */ | ||||
| template<typename Scalar> | ||||
| struct scalar_cube_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_cube_op) | ||||
|   inline Scalar operator() (const Scalar& a) const { return a*a*a; } | ||||
|   template<typename Packet> | ||||
|   inline const Packet packetOp(const Packet& a) const | ||||
|   { return internal::pmul(a,pmul(a,a)); } | ||||
| }; | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_cube_op<Scalar> > | ||||
| { enum { Cost = 2*NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; }; | ||||
|  | ||||
| // default functor traits for STL functors: | ||||
|  | ||||
| template<typename T> | ||||
| struct functor_traits<std::multiplies<T> > | ||||
| { enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T> | ||||
| struct functor_traits<std::divides<T> > | ||||
| { enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T> | ||||
| struct functor_traits<std::plus<T> > | ||||
| { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T> | ||||
| struct functor_traits<std::minus<T> > | ||||
| { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T> | ||||
| struct functor_traits<std::negate<T> > | ||||
| { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T> | ||||
| struct functor_traits<std::logical_or<T> > | ||||
| { enum { Cost = 1, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T> | ||||
| struct functor_traits<std::logical_and<T> > | ||||
| { enum { Cost = 1, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T> | ||||
| struct functor_traits<std::logical_not<T> > | ||||
| { enum { Cost = 1, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T> | ||||
| struct functor_traits<std::greater<T> > | ||||
| { enum { Cost = 1, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T> | ||||
| struct functor_traits<std::less<T> > | ||||
| { enum { Cost = 1, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T> | ||||
| struct functor_traits<std::greater_equal<T> > | ||||
| { enum { Cost = 1, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T> | ||||
| struct functor_traits<std::less_equal<T> > | ||||
| { enum { Cost = 1, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T> | ||||
| struct functor_traits<std::equal_to<T> > | ||||
| { enum { Cost = 1, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T> | ||||
| struct functor_traits<std::not_equal_to<T> > | ||||
| { enum { Cost = 1, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T> | ||||
| struct functor_traits<std::binder2nd<T> > | ||||
| { enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T> | ||||
| struct functor_traits<std::binder1st<T> > | ||||
| { enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T> | ||||
| struct functor_traits<std::unary_negate<T> > | ||||
| { enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T> | ||||
| struct functor_traits<std::binary_negate<T> > | ||||
| { enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; }; | ||||
|  | ||||
| #ifdef EIGEN_STDEXT_SUPPORT | ||||
|  | ||||
| template<typename T0,typename T1> | ||||
| struct functor_traits<std::project1st<T0,T1> > | ||||
| { enum { Cost = 0, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T0,typename T1> | ||||
| struct functor_traits<std::project2nd<T0,T1> > | ||||
| { enum { Cost = 0, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T0,typename T1> | ||||
| struct functor_traits<std::select2nd<std::pair<T0,T1> > > | ||||
| { enum { Cost = 0, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T0,typename T1> | ||||
| struct functor_traits<std::select1st<std::pair<T0,T1> > > | ||||
| { enum { Cost = 0, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T0,typename T1> | ||||
| struct functor_traits<std::unary_compose<T0,T1> > | ||||
| { enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost, PacketAccess = false }; }; | ||||
|  | ||||
| template<typename T0,typename T1,typename T2> | ||||
| struct functor_traits<std::binary_compose<T0,T1,T2> > | ||||
| { enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost + functor_traits<T2>::Cost, PacketAccess = false }; }; | ||||
|  | ||||
| #endif // EIGEN_STDEXT_SUPPORT | ||||
|  | ||||
| // allow to add new functors and specializations of functor_traits from outside Eigen. | ||||
| // this macro is really needed because functor_traits must be specialized after it is declared but before it is used... | ||||
| #ifdef EIGEN_FUNCTORS_PLUGIN | ||||
| #include EIGEN_FUNCTORS_PLUGIN | ||||
| #endif | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_FUNCTORS_H | ||||
							
								
								
									
										150
									
								
								latan/Eigen/src/Core/Fuzzy.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								latan/Eigen/src/Core/Fuzzy.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,150 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_FUZZY_H | ||||
| #define EIGEN_FUZZY_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| namespace internal | ||||
| { | ||||
|  | ||||
| template<typename Derived, typename OtherDerived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger> | ||||
| struct isApprox_selector | ||||
| { | ||||
|   static bool run(const Derived& x, const OtherDerived& y, typename Derived::RealScalar prec) | ||||
|   { | ||||
|     using std::min; | ||||
|     typename internal::nested<Derived,2>::type nested(x); | ||||
|     typename internal::nested<OtherDerived,2>::type otherNested(y); | ||||
|     return (nested - otherNested).cwiseAbs2().sum() <= prec * prec * (min)(nested.cwiseAbs2().sum(), otherNested.cwiseAbs2().sum()); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived, typename OtherDerived> | ||||
| struct isApprox_selector<Derived, OtherDerived, true> | ||||
| { | ||||
|   static bool run(const Derived& x, const OtherDerived& y, typename Derived::RealScalar) | ||||
|   { | ||||
|     return x.matrix() == y.matrix(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived, typename OtherDerived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger> | ||||
| struct isMuchSmallerThan_object_selector | ||||
| { | ||||
|   static bool run(const Derived& x, const OtherDerived& y, typename Derived::RealScalar prec) | ||||
|   { | ||||
|     return x.cwiseAbs2().sum() <= abs2(prec) * y.cwiseAbs2().sum(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived, typename OtherDerived> | ||||
| struct isMuchSmallerThan_object_selector<Derived, OtherDerived, true> | ||||
| { | ||||
|   static bool run(const Derived& x, const OtherDerived&, typename Derived::RealScalar) | ||||
|   { | ||||
|     return x.matrix() == Derived::Zero(x.rows(), x.cols()).matrix(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger> | ||||
| struct isMuchSmallerThan_scalar_selector | ||||
| { | ||||
|   static bool run(const Derived& x, const typename Derived::RealScalar& y, typename Derived::RealScalar prec) | ||||
|   { | ||||
|     return x.cwiseAbs2().sum() <= abs2(prec * y); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived> | ||||
| struct isMuchSmallerThan_scalar_selector<Derived, true> | ||||
| { | ||||
|   static bool run(const Derived& x, const typename Derived::RealScalar&, typename Derived::RealScalar) | ||||
|   { | ||||
|     return x.matrix() == Derived::Zero(x.rows(), x.cols()).matrix(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
|  | ||||
| /** \returns \c true if \c *this is approximately equal to \a other, within the precision | ||||
|   * determined by \a prec. | ||||
|   * | ||||
|   * \note The fuzzy compares are done multiplicatively. Two vectors \f$ v \f$ and \f$ w \f$ | ||||
|   * are considered to be approximately equal within precision \f$ p \f$ if | ||||
|   * \f[ \Vert v - w \Vert \leqslant p\,\min(\Vert v\Vert, \Vert w\Vert). \f] | ||||
|   * For matrices, the comparison is done using the Hilbert-Schmidt norm (aka Frobenius norm | ||||
|   * L2 norm). | ||||
|   * | ||||
|   * \note Because of the multiplicativeness of this comparison, one can't use this function | ||||
|   * to check whether \c *this is approximately equal to the zero matrix or vector. | ||||
|   * Indeed, \c isApprox(zero) returns false unless \c *this itself is exactly the zero matrix | ||||
|   * or vector. If you want to test whether \c *this is zero, use internal::isMuchSmallerThan(const | ||||
|   * RealScalar&, RealScalar) instead. | ||||
|   * | ||||
|   * \sa internal::isMuchSmallerThan(const RealScalar&, RealScalar) const | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| bool DenseBase<Derived>::isApprox( | ||||
|   const DenseBase<OtherDerived>& other, | ||||
|   RealScalar prec | ||||
| ) const | ||||
| { | ||||
|   return internal::isApprox_selector<Derived, OtherDerived>::run(derived(), other.derived(), prec); | ||||
| } | ||||
|  | ||||
| /** \returns \c true if the norm of \c *this is much smaller than \a other, | ||||
|   * within the precision determined by \a prec. | ||||
|   * | ||||
|   * \note The fuzzy compares are done multiplicatively. A vector \f$ v \f$ is | ||||
|   * considered to be much smaller than \f$ x \f$ within precision \f$ p \f$ if | ||||
|   * \f[ \Vert v \Vert \leqslant p\,\vert x\vert. \f] | ||||
|   * | ||||
|   * For matrices, the comparison is done using the Hilbert-Schmidt norm. For this reason, | ||||
|   * the value of the reference scalar \a other should come from the Hilbert-Schmidt norm | ||||
|   * of a reference matrix of same dimensions. | ||||
|   * | ||||
|   * \sa isApprox(), isMuchSmallerThan(const DenseBase<OtherDerived>&, RealScalar) const | ||||
|   */ | ||||
| template<typename Derived> | ||||
| bool DenseBase<Derived>::isMuchSmallerThan( | ||||
|   const typename NumTraits<Scalar>::Real& other, | ||||
|   RealScalar prec | ||||
| ) const | ||||
| { | ||||
|   return internal::isMuchSmallerThan_scalar_selector<Derived>::run(derived(), other, prec); | ||||
| } | ||||
|  | ||||
| /** \returns \c true if the norm of \c *this is much smaller than the norm of \a other, | ||||
|   * within the precision determined by \a prec. | ||||
|   * | ||||
|   * \note The fuzzy compares are done multiplicatively. A vector \f$ v \f$ is | ||||
|   * considered to be much smaller than a vector \f$ w \f$ within precision \f$ p \f$ if | ||||
|   * \f[ \Vert v \Vert \leqslant p\,\Vert w\Vert. \f] | ||||
|   * For matrices, the comparison is done using the Hilbert-Schmidt norm. | ||||
|   * | ||||
|   * \sa isApprox(), isMuchSmallerThan(const RealScalar&, RealScalar) const | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| bool DenseBase<Derived>::isMuchSmallerThan( | ||||
|   const DenseBase<OtherDerived>& other, | ||||
|   RealScalar prec | ||||
| ) const | ||||
| { | ||||
|   return internal::isMuchSmallerThan_object_selector<Derived, OtherDerived>::run(derived(), other.derived(), prec); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_FUZZY_H | ||||
							
								
								
									
										613
									
								
								latan/Eigen/src/Core/GeneralProduct.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										613
									
								
								latan/Eigen/src/Core/GeneralProduct.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,613 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_GENERAL_PRODUCT_H | ||||
| #define EIGEN_GENERAL_PRODUCT_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class GeneralProduct | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Expression of the product of two general matrices or vectors | ||||
|   * | ||||
|   * \param LhsNested the type used to store the left-hand side | ||||
|   * \param RhsNested the type used to store the right-hand side | ||||
|   * \param ProductMode the type of the product | ||||
|   * | ||||
|   * This class represents an expression of the product of two general matrices. | ||||
|   * We call a general matrix, a dense matrix with full storage. For instance, | ||||
|   * This excludes triangular, selfadjoint, and sparse matrices. | ||||
|   * It is the return type of the operator* between general matrices. Its template | ||||
|   * arguments are determined automatically by ProductReturnType. Therefore, | ||||
|   * GeneralProduct should never be used direclty. To determine the result type of a | ||||
|   * function which involves a matrix product, use ProductReturnType::Type. | ||||
|   * | ||||
|   * \sa ProductReturnType, MatrixBase::operator*(const MatrixBase<OtherDerived>&) | ||||
|   */ | ||||
| template<typename Lhs, typename Rhs, int ProductType = internal::product_type<Lhs,Rhs>::value> | ||||
| class GeneralProduct; | ||||
|  | ||||
| enum { | ||||
|   Large = 2, | ||||
|   Small = 3 | ||||
| }; | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<int Rows, int Cols, int Depth> struct product_type_selector; | ||||
|  | ||||
| template<int Size, int MaxSize> struct product_size_category | ||||
| { | ||||
|   enum { is_large = MaxSize == Dynamic || | ||||
|                     Size >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD, | ||||
|          value = is_large  ? Large | ||||
|                : Size == 1 ? 1 | ||||
|                            : Small | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| template<typename Lhs, typename Rhs> struct product_type | ||||
| { | ||||
|   typedef typename remove_all<Lhs>::type _Lhs; | ||||
|   typedef typename remove_all<Rhs>::type _Rhs; | ||||
|   enum { | ||||
|     MaxRows  = _Lhs::MaxRowsAtCompileTime, | ||||
|     Rows  = _Lhs::RowsAtCompileTime, | ||||
|     MaxCols  = _Rhs::MaxColsAtCompileTime, | ||||
|     Cols  = _Rhs::ColsAtCompileTime, | ||||
|     MaxDepth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::MaxColsAtCompileTime, | ||||
|                                            _Rhs::MaxRowsAtCompileTime), | ||||
|     Depth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::ColsAtCompileTime, | ||||
|                                         _Rhs::RowsAtCompileTime), | ||||
|     LargeThreshold = EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD | ||||
|   }; | ||||
|  | ||||
|   // the splitting into different lines of code here, introducing the _select enums and the typedef below, | ||||
|   // is to work around an internal compiler error with gcc 4.1 and 4.2. | ||||
| private: | ||||
|   enum { | ||||
|     rows_select = product_size_category<Rows,MaxRows>::value, | ||||
|     cols_select = product_size_category<Cols,MaxCols>::value, | ||||
|     depth_select = product_size_category<Depth,MaxDepth>::value | ||||
|   }; | ||||
|   typedef product_type_selector<rows_select, cols_select, depth_select> selector; | ||||
|  | ||||
| public: | ||||
|   enum { | ||||
|     value = selector::ret | ||||
|   }; | ||||
| #ifdef EIGEN_DEBUG_PRODUCT | ||||
|   static void debug() | ||||
|   { | ||||
|       EIGEN_DEBUG_VAR(Rows); | ||||
|       EIGEN_DEBUG_VAR(Cols); | ||||
|       EIGEN_DEBUG_VAR(Depth); | ||||
|       EIGEN_DEBUG_VAR(rows_select); | ||||
|       EIGEN_DEBUG_VAR(cols_select); | ||||
|       EIGEN_DEBUG_VAR(depth_select); | ||||
|       EIGEN_DEBUG_VAR(value); | ||||
|   } | ||||
| #endif | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* The following allows to select the kind of product at compile time | ||||
|  * based on the three dimensions of the product. | ||||
|  * This is a compile time mapping from {1,Small,Large}^3 -> {product types} */ | ||||
| // FIXME I'm not sure the current mapping is the ideal one. | ||||
| template<int M, int N>  struct product_type_selector<M,N,1>              { enum { ret = OuterProduct }; }; | ||||
| template<int Depth>     struct product_type_selector<1,    1,    Depth>  { enum { ret = InnerProduct }; }; | ||||
| template<>              struct product_type_selector<1,    1,    1>      { enum { ret = InnerProduct }; }; | ||||
| template<>              struct product_type_selector<Small,1,    Small>  { enum { ret = CoeffBasedProductMode }; }; | ||||
| template<>              struct product_type_selector<1,    Small,Small>  { enum { ret = CoeffBasedProductMode }; }; | ||||
| template<>              struct product_type_selector<Small,Small,Small>  { enum { ret = CoeffBasedProductMode }; }; | ||||
| template<>              struct product_type_selector<Small, Small, 1>    { enum { ret = LazyCoeffBasedProductMode }; }; | ||||
| template<>              struct product_type_selector<Small, Large, 1>    { enum { ret = LazyCoeffBasedProductMode }; }; | ||||
| template<>              struct product_type_selector<Large, Small, 1>    { enum { ret = LazyCoeffBasedProductMode }; }; | ||||
| template<>              struct product_type_selector<1,    Large,Small>  { enum { ret = CoeffBasedProductMode }; }; | ||||
| template<>              struct product_type_selector<1,    Large,Large>  { enum { ret = GemvProduct }; }; | ||||
| template<>              struct product_type_selector<1,    Small,Large>  { enum { ret = CoeffBasedProductMode }; }; | ||||
| template<>              struct product_type_selector<Large,1,    Small>  { enum { ret = CoeffBasedProductMode }; }; | ||||
| template<>              struct product_type_selector<Large,1,    Large>  { enum { ret = GemvProduct }; }; | ||||
| template<>              struct product_type_selector<Small,1,    Large>  { enum { ret = CoeffBasedProductMode }; }; | ||||
| template<>              struct product_type_selector<Small,Small,Large>  { enum { ret = GemmProduct }; }; | ||||
| template<>              struct product_type_selector<Large,Small,Large>  { enum { ret = GemmProduct }; }; | ||||
| template<>              struct product_type_selector<Small,Large,Large>  { enum { ret = GemmProduct }; }; | ||||
| template<>              struct product_type_selector<Large,Large,Large>  { enum { ret = GemmProduct }; }; | ||||
| template<>              struct product_type_selector<Large,Small,Small>  { enum { ret = GemmProduct }; }; | ||||
| template<>              struct product_type_selector<Small,Large,Small>  { enum { ret = GemmProduct }; }; | ||||
| template<>              struct product_type_selector<Large,Large,Small>  { enum { ret = GemmProduct }; }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /** \class ProductReturnType | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Helper class to get the correct and optimized returned type of operator* | ||||
|   * | ||||
|   * \param Lhs the type of the left-hand side | ||||
|   * \param Rhs the type of the right-hand side | ||||
|   * \param ProductMode the type of the product (determined automatically by internal::product_mode) | ||||
|   * | ||||
|   * This class defines the typename Type representing the optimized product expression | ||||
|   * between two matrix expressions. In practice, using ProductReturnType<Lhs,Rhs>::Type | ||||
|   * is the recommended way to define the result type of a function returning an expression | ||||
|   * which involve a matrix product. The class Product should never be | ||||
|   * used directly. | ||||
|   * | ||||
|   * \sa class Product, MatrixBase::operator*(const MatrixBase<OtherDerived>&) | ||||
|   */ | ||||
| template<typename Lhs, typename Rhs, int ProductType> | ||||
| struct ProductReturnType | ||||
| { | ||||
|   // TODO use the nested type to reduce instanciations ???? | ||||
| //   typedef typename internal::nested<Lhs,Rhs::ColsAtCompileTime>::type LhsNested; | ||||
| //   typedef typename internal::nested<Rhs,Lhs::RowsAtCompileTime>::type RhsNested; | ||||
|  | ||||
|   typedef GeneralProduct<Lhs/*Nested*/, Rhs/*Nested*/, ProductType> Type; | ||||
| }; | ||||
|  | ||||
| template<typename Lhs, typename Rhs> | ||||
| struct ProductReturnType<Lhs,Rhs,CoeffBasedProductMode> | ||||
| { | ||||
|   typedef typename internal::nested<Lhs, Rhs::ColsAtCompileTime, typename internal::plain_matrix_type<Lhs>::type >::type LhsNested; | ||||
|   typedef typename internal::nested<Rhs, Lhs::RowsAtCompileTime, typename internal::plain_matrix_type<Rhs>::type >::type RhsNested; | ||||
|   typedef CoeffBasedProduct<LhsNested, RhsNested, EvalBeforeAssigningBit | EvalBeforeNestingBit> Type; | ||||
| }; | ||||
|  | ||||
| template<typename Lhs, typename Rhs> | ||||
| struct ProductReturnType<Lhs,Rhs,LazyCoeffBasedProductMode> | ||||
| { | ||||
|   typedef typename internal::nested<Lhs, Rhs::ColsAtCompileTime, typename internal::plain_matrix_type<Lhs>::type >::type LhsNested; | ||||
|   typedef typename internal::nested<Rhs, Lhs::RowsAtCompileTime, typename internal::plain_matrix_type<Rhs>::type >::type RhsNested; | ||||
|   typedef CoeffBasedProduct<LhsNested, RhsNested, NestByRefBit> Type; | ||||
| }; | ||||
|  | ||||
| // this is a workaround for sun CC | ||||
| template<typename Lhs, typename Rhs> | ||||
| struct LazyProductReturnType : public ProductReturnType<Lhs,Rhs,LazyCoeffBasedProductMode> | ||||
| {}; | ||||
|  | ||||
| /*********************************************************************** | ||||
| *  Implementation of Inner Vector Vector Product | ||||
| ***********************************************************************/ | ||||
|  | ||||
| // FIXME : maybe the "inner product" could return a Scalar | ||||
| // instead of a 1x1 matrix ?? | ||||
| // Pro: more natural for the user | ||||
| // Cons: this could be a problem if in a meta unrolled algorithm a matrix-matrix | ||||
| // product ends up to a row-vector times col-vector product... To tackle this use | ||||
| // case, we could have a specialization for Block<MatrixType,1,1> with: operator=(Scalar x); | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename Lhs, typename Rhs> | ||||
| struct traits<GeneralProduct<Lhs,Rhs,InnerProduct> > | ||||
|  : traits<Matrix<typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType,1,1> > | ||||
| {}; | ||||
|  | ||||
| } | ||||
|  | ||||
| template<typename Lhs, typename Rhs> | ||||
| class GeneralProduct<Lhs, Rhs, InnerProduct> | ||||
|   : internal::no_assignment_operator, | ||||
|     public Matrix<typename internal::scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType,1,1> | ||||
| { | ||||
|     typedef Matrix<typename internal::scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType,1,1> Base; | ||||
|   public: | ||||
|     GeneralProduct(const Lhs& lhs, const Rhs& rhs) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::RealScalar, typename Rhs::RealScalar>::value), | ||||
|         YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) | ||||
|  | ||||
|       Base::coeffRef(0,0) = (lhs.transpose().cwiseProduct(rhs)).sum(); | ||||
|     } | ||||
|  | ||||
|     /** Convertion to scalar */ | ||||
|     operator const typename Base::Scalar() const { | ||||
|       return Base::coeff(0,0); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| /*********************************************************************** | ||||
| *  Implementation of Outer Vector Vector Product | ||||
| ***********************************************************************/ | ||||
|  | ||||
| namespace internal { | ||||
| template<int StorageOrder> struct outer_product_selector; | ||||
|  | ||||
| template<typename Lhs, typename Rhs> | ||||
| struct traits<GeneralProduct<Lhs,Rhs,OuterProduct> > | ||||
|  : traits<ProductBase<GeneralProduct<Lhs,Rhs,OuterProduct>, Lhs, Rhs> > | ||||
| {}; | ||||
|  | ||||
| } | ||||
|  | ||||
| template<typename Lhs, typename Rhs> | ||||
| class GeneralProduct<Lhs, Rhs, OuterProduct> | ||||
|   : public ProductBase<GeneralProduct<Lhs,Rhs,OuterProduct>, Lhs, Rhs> | ||||
| { | ||||
|   public: | ||||
|     EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct) | ||||
|  | ||||
|     GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::RealScalar, typename Rhs::RealScalar>::value), | ||||
|         YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) | ||||
|     } | ||||
|  | ||||
|     template<typename Dest> void scaleAndAddTo(Dest& dest, Scalar alpha) const | ||||
|     { | ||||
|       internal::outer_product_selector<(int(Dest::Flags)&RowMajorBit) ? RowMajor : ColMajor>::run(*this, dest, alpha); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<> struct outer_product_selector<ColMajor> { | ||||
|   template<typename ProductType, typename Dest> | ||||
|   static EIGEN_DONT_INLINE void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) { | ||||
|     typedef typename Dest::Index Index; | ||||
|     // FIXME make sure lhs is sequentially stored | ||||
|     // FIXME not very good if rhs is real and lhs complex while alpha is real too | ||||
|     const Index cols = dest.cols(); | ||||
|     for (Index j=0; j<cols; ++j) | ||||
|       dest.col(j) += (alpha * prod.rhs().coeff(j)) * prod.lhs(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct outer_product_selector<RowMajor> { | ||||
|   template<typename ProductType, typename Dest> | ||||
|   static EIGEN_DONT_INLINE void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) { | ||||
|     typedef typename Dest::Index Index; | ||||
|     // FIXME make sure rhs is sequentially stored | ||||
|     // FIXME not very good if lhs is real and rhs complex while alpha is real too | ||||
|     const Index rows = dest.rows(); | ||||
|     for (Index i=0; i<rows; ++i) | ||||
|       dest.row(i) += (alpha * prod.lhs().coeff(i)) * prod.rhs(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /*********************************************************************** | ||||
| *  Implementation of General Matrix Vector Product | ||||
| ***********************************************************************/ | ||||
|  | ||||
| /*  According to the shape/flags of the matrix we have to distinghish 3 different cases: | ||||
|  *   1 - the matrix is col-major, BLAS compatible and M is large => call fast BLAS-like colmajor routine | ||||
|  *   2 - the matrix is row-major, BLAS compatible and N is large => call fast BLAS-like rowmajor routine | ||||
|  *   3 - all other cases are handled using a simple loop along the outer-storage direction. | ||||
|  *  Therefore we need a lower level meta selector. | ||||
|  *  Furthermore, if the matrix is the rhs, then the product has to be transposed. | ||||
|  */ | ||||
| namespace internal { | ||||
|  | ||||
| template<typename Lhs, typename Rhs> | ||||
| struct traits<GeneralProduct<Lhs,Rhs,GemvProduct> > | ||||
|  : traits<ProductBase<GeneralProduct<Lhs,Rhs,GemvProduct>, Lhs, Rhs> > | ||||
| {}; | ||||
|  | ||||
| template<int Side, int StorageOrder, bool BlasCompatible> | ||||
| struct gemv_selector; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| template<typename Lhs, typename Rhs> | ||||
| class GeneralProduct<Lhs, Rhs, GemvProduct> | ||||
|   : public ProductBase<GeneralProduct<Lhs,Rhs,GemvProduct>, Lhs, Rhs> | ||||
| { | ||||
|   public: | ||||
|     EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct) | ||||
|  | ||||
|     typedef typename Lhs::Scalar LhsScalar; | ||||
|     typedef typename Rhs::Scalar RhsScalar; | ||||
|  | ||||
|     GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) | ||||
|     { | ||||
| //       EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::Scalar, typename Rhs::Scalar>::value), | ||||
| //         YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) | ||||
|     } | ||||
|  | ||||
|     enum { Side = Lhs::IsVectorAtCompileTime ? OnTheLeft : OnTheRight }; | ||||
|     typedef typename internal::conditional<int(Side)==OnTheRight,_LhsNested,_RhsNested>::type MatrixType; | ||||
|  | ||||
|     template<typename Dest> void scaleAndAddTo(Dest& dst, Scalar alpha) const | ||||
|     { | ||||
|       eigen_assert(m_lhs.rows() == dst.rows() && m_rhs.cols() == dst.cols()); | ||||
|       internal::gemv_selector<Side,(int(MatrixType::Flags)&RowMajorBit) ? RowMajor : ColMajor, | ||||
|                        bool(internal::blas_traits<MatrixType>::HasUsableDirectAccess)>::run(*this, dst, alpha); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| // The vector is on the left => transposition | ||||
| template<int StorageOrder, bool BlasCompatible> | ||||
| struct gemv_selector<OnTheLeft,StorageOrder,BlasCompatible> | ||||
| { | ||||
|   template<typename ProductType, typename Dest> | ||||
|   static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) | ||||
|   { | ||||
|     Transpose<Dest> destT(dest); | ||||
|     enum { OtherStorageOrder = StorageOrder == RowMajor ? ColMajor : RowMajor }; | ||||
|     gemv_selector<OnTheRight,OtherStorageOrder,BlasCompatible> | ||||
|       ::run(GeneralProduct<Transpose<const typename ProductType::_RhsNested>,Transpose<const typename ProductType::_LhsNested>, GemvProduct> | ||||
|         (prod.rhs().transpose(), prod.lhs().transpose()), destT, alpha); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar,int Size,int MaxSize,bool Cond> struct gemv_static_vector_if; | ||||
|  | ||||
| template<typename Scalar,int Size,int MaxSize> | ||||
| struct gemv_static_vector_if<Scalar,Size,MaxSize,false> | ||||
| { | ||||
|   EIGEN_STRONG_INLINE  Scalar* data() { eigen_internal_assert(false && "should never be called"); return 0; } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar,int Size> | ||||
| struct gemv_static_vector_if<Scalar,Size,Dynamic,true> | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Scalar* data() { return 0; } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar,int Size,int MaxSize> | ||||
| struct gemv_static_vector_if<Scalar,Size,MaxSize,true> | ||||
| { | ||||
|   #if EIGEN_ALIGN_STATICALLY | ||||
|   internal::plain_array<Scalar,EIGEN_SIZE_MIN_PREFER_FIXED(Size,MaxSize),0> m_data; | ||||
|   EIGEN_STRONG_INLINE Scalar* data() { return m_data.array; } | ||||
|   #else | ||||
|   // Some architectures cannot align on the stack, | ||||
|   // => let's manually enforce alignment by allocating more data and return the address of the first aligned element. | ||||
|   enum { | ||||
|     ForceAlignment  = internal::packet_traits<Scalar>::Vectorizable, | ||||
|     PacketSize      = internal::packet_traits<Scalar>::size | ||||
|   }; | ||||
|   internal::plain_array<Scalar,EIGEN_SIZE_MIN_PREFER_FIXED(Size,MaxSize)+(ForceAlignment?PacketSize:0),0> m_data; | ||||
|   EIGEN_STRONG_INLINE Scalar* data() { | ||||
|     return ForceAlignment | ||||
|             ? reinterpret_cast<Scalar*>((reinterpret_cast<size_t>(m_data.array) & ~(size_t(15))) + 16) | ||||
|             : m_data.array; | ||||
|   } | ||||
|   #endif | ||||
| }; | ||||
|  | ||||
| template<> struct gemv_selector<OnTheRight,ColMajor,true> | ||||
| { | ||||
|   template<typename ProductType, typename Dest> | ||||
|   static inline void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) | ||||
|   { | ||||
|     typedef typename ProductType::Index Index; | ||||
|     typedef typename ProductType::LhsScalar   LhsScalar; | ||||
|     typedef typename ProductType::RhsScalar   RhsScalar; | ||||
|     typedef typename ProductType::Scalar      ResScalar; | ||||
|     typedef typename ProductType::RealScalar  RealScalar; | ||||
|     typedef typename ProductType::ActualLhsType ActualLhsType; | ||||
|     typedef typename ProductType::ActualRhsType ActualRhsType; | ||||
|     typedef typename ProductType::LhsBlasTraits LhsBlasTraits; | ||||
|     typedef typename ProductType::RhsBlasTraits RhsBlasTraits; | ||||
|     typedef Map<Matrix<ResScalar,Dynamic,1>, Aligned> MappedDest; | ||||
|  | ||||
|     ActualLhsType actualLhs = LhsBlasTraits::extract(prod.lhs()); | ||||
|     ActualRhsType actualRhs = RhsBlasTraits::extract(prod.rhs()); | ||||
|  | ||||
|     ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs()) | ||||
|                                   * RhsBlasTraits::extractScalarFactor(prod.rhs()); | ||||
|  | ||||
|     enum { | ||||
|       // FIXME find a way to allow an inner stride on the result if packet_traits<Scalar>::size==1 | ||||
|       // on, the other hand it is good for the cache to pack the vector anyways... | ||||
|       EvalToDestAtCompileTime = Dest::InnerStrideAtCompileTime==1, | ||||
|       ComplexByReal = (NumTraits<LhsScalar>::IsComplex) && (!NumTraits<RhsScalar>::IsComplex), | ||||
|       MightCannotUseDest = (Dest::InnerStrideAtCompileTime!=1) || ComplexByReal | ||||
|     }; | ||||
|  | ||||
|     gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest; | ||||
|  | ||||
|     bool alphaIsCompatible = (!ComplexByReal) || (imag(actualAlpha)==RealScalar(0)); | ||||
|     bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible; | ||||
|      | ||||
|     RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha); | ||||
|  | ||||
|     ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(), | ||||
|                                                   evalToDest ? dest.data() : static_dest.data()); | ||||
|      | ||||
|     if(!evalToDest) | ||||
|     { | ||||
|       #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN | ||||
|       int size = dest.size(); | ||||
|       EIGEN_DENSE_STORAGE_CTOR_PLUGIN | ||||
|       #endif | ||||
|       if(!alphaIsCompatible) | ||||
|       { | ||||
|         MappedDest(actualDestPtr, dest.size()).setZero(); | ||||
|         compatibleAlpha = RhsScalar(1); | ||||
|       } | ||||
|       else | ||||
|         MappedDest(actualDestPtr, dest.size()) = dest; | ||||
|     } | ||||
|  | ||||
|     general_matrix_vector_product | ||||
|       <Index,LhsScalar,ColMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsBlasTraits::NeedToConjugate>::run( | ||||
|         actualLhs.rows(), actualLhs.cols(), | ||||
|         actualLhs.data(), actualLhs.outerStride(), | ||||
|         actualRhs.data(), actualRhs.innerStride(), | ||||
|         actualDestPtr, 1, | ||||
|         compatibleAlpha); | ||||
|  | ||||
|     if (!evalToDest) | ||||
|     { | ||||
|       if(!alphaIsCompatible) | ||||
|         dest += actualAlpha * MappedDest(actualDestPtr, dest.size()); | ||||
|       else | ||||
|         dest = MappedDest(actualDestPtr, dest.size()); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct gemv_selector<OnTheRight,RowMajor,true> | ||||
| { | ||||
|   template<typename ProductType, typename Dest> | ||||
|   static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) | ||||
|   { | ||||
|     typedef typename ProductType::LhsScalar LhsScalar; | ||||
|     typedef typename ProductType::RhsScalar RhsScalar; | ||||
|     typedef typename ProductType::Scalar    ResScalar; | ||||
|     typedef typename ProductType::Index Index; | ||||
|     typedef typename ProductType::ActualLhsType ActualLhsType; | ||||
|     typedef typename ProductType::ActualRhsType ActualRhsType; | ||||
|     typedef typename ProductType::_ActualRhsType _ActualRhsType; | ||||
|     typedef typename ProductType::LhsBlasTraits LhsBlasTraits; | ||||
|     typedef typename ProductType::RhsBlasTraits RhsBlasTraits; | ||||
|  | ||||
|     typename add_const<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(prod.lhs()); | ||||
|     typename add_const<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(prod.rhs()); | ||||
|  | ||||
|     ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs()) | ||||
|                                   * RhsBlasTraits::extractScalarFactor(prod.rhs()); | ||||
|  | ||||
|     enum { | ||||
|       // FIXME find a way to allow an inner stride on the result if packet_traits<Scalar>::size==1 | ||||
|       // on, the other hand it is good for the cache to pack the vector anyways... | ||||
|       DirectlyUseRhs = _ActualRhsType::InnerStrideAtCompileTime==1 | ||||
|     }; | ||||
|  | ||||
|     gemv_static_vector_if<RhsScalar,_ActualRhsType::SizeAtCompileTime,_ActualRhsType::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs; | ||||
|  | ||||
|     ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(), | ||||
|         DirectlyUseRhs ? const_cast<RhsScalar*>(actualRhs.data()) : static_rhs.data()); | ||||
|  | ||||
|     if(!DirectlyUseRhs) | ||||
|     { | ||||
|       #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN | ||||
|       int size = actualRhs.size(); | ||||
|       EIGEN_DENSE_STORAGE_CTOR_PLUGIN | ||||
|       #endif | ||||
|       Map<typename _ActualRhsType::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs; | ||||
|     } | ||||
|  | ||||
|     general_matrix_vector_product | ||||
|       <Index,LhsScalar,RowMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsBlasTraits::NeedToConjugate>::run( | ||||
|         actualLhs.rows(), actualLhs.cols(), | ||||
|         actualLhs.data(), actualLhs.outerStride(), | ||||
|         actualRhsPtr, 1, | ||||
|         dest.data(), dest.innerStride(), | ||||
|         actualAlpha); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct gemv_selector<OnTheRight,ColMajor,false> | ||||
| { | ||||
|   template<typename ProductType, typename Dest> | ||||
|   static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) | ||||
|   { | ||||
|     typedef typename Dest::Index Index; | ||||
|     // TODO makes sure dest is sequentially stored in memory, otherwise use a temp | ||||
|     const Index size = prod.rhs().rows(); | ||||
|     for(Index k=0; k<size; ++k) | ||||
|       dest += (alpha*prod.rhs().coeff(k)) * prod.lhs().col(k); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct gemv_selector<OnTheRight,RowMajor,false> | ||||
| { | ||||
|   template<typename ProductType, typename Dest> | ||||
|   static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) | ||||
|   { | ||||
|     typedef typename Dest::Index Index; | ||||
|     // TODO makes sure rhs is sequentially stored in memory, otherwise use a temp | ||||
|     const Index rows = prod.rows(); | ||||
|     for(Index i=0; i<rows; ++i) | ||||
|       dest.coeffRef(i) += alpha * (prod.lhs().row(i).cwiseProduct(prod.rhs().transpose())).sum(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /*************************************************************************** | ||||
| * Implementation of matrix base methods | ||||
| ***************************************************************************/ | ||||
|  | ||||
| /** \returns the matrix product of \c *this and \a other. | ||||
|   * | ||||
|   * \note If instead of the matrix product you want the coefficient-wise product, see Cwise::operator*(). | ||||
|   * | ||||
|   * \sa lazyProduct(), operator*=(const MatrixBase&), Cwise::operator*() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| inline const typename ProductReturnType<Derived, OtherDerived>::Type | ||||
| MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const | ||||
| { | ||||
|   // A note regarding the function declaration: In MSVC, this function will sometimes | ||||
|   // not be inlined since DenseStorage is an unwindable object for dynamic | ||||
|   // matrices and product types are holding a member to store the result. | ||||
|   // Thus it does not help tagging this function with EIGEN_STRONG_INLINE. | ||||
|   enum { | ||||
|     ProductIsValid =  Derived::ColsAtCompileTime==Dynamic | ||||
|                    || OtherDerived::RowsAtCompileTime==Dynamic | ||||
|                    || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime), | ||||
|     AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime, | ||||
|     SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived) | ||||
|   }; | ||||
|   // note to the lost user: | ||||
|   //    * for a dot product use: v1.dot(v2) | ||||
|   //    * for a coeff-wise product use: v1.cwiseProduct(v2) | ||||
|   EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes), | ||||
|     INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS) | ||||
|   EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors), | ||||
|     INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION) | ||||
|   EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) | ||||
| #ifdef EIGEN_DEBUG_PRODUCT | ||||
|   internal::product_type<Derived,OtherDerived>::debug(); | ||||
| #endif | ||||
|   return typename ProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation. | ||||
|   * | ||||
|   * The returned product will behave like any other expressions: the coefficients of the product will be | ||||
|   * computed once at a time as requested. This might be useful in some extremely rare cases when only | ||||
|   * a small and no coherent fraction of the result's coefficients have to be computed. | ||||
|   * | ||||
|   * \warning This version of the matrix product can be much much slower. So use it only if you know | ||||
|   * what you are doing and that you measured a true speed improvement. | ||||
|   * | ||||
|   * \sa operator*(const MatrixBase&) | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| const typename LazyProductReturnType<Derived,OtherDerived>::Type | ||||
| MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const | ||||
| { | ||||
|   enum { | ||||
|     ProductIsValid =  Derived::ColsAtCompileTime==Dynamic | ||||
|                    || OtherDerived::RowsAtCompileTime==Dynamic | ||||
|                    || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime), | ||||
|     AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime, | ||||
|     SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived) | ||||
|   }; | ||||
|   // note to the lost user: | ||||
|   //    * for a dot product use: v1.dot(v2) | ||||
|   //    * for a coeff-wise product use: v1.cwiseProduct(v2) | ||||
|   EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes), | ||||
|     INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS) | ||||
|   EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors), | ||||
|     INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION) | ||||
|   EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) | ||||
|  | ||||
|   return typename LazyProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_PRODUCT_H | ||||
							
								
								
									
										328
									
								
								latan/Eigen/src/Core/GenericPacketMath.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										328
									
								
								latan/Eigen/src/Core/GenericPacketMath.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,328 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_GENERIC_PACKET_MATH_H | ||||
| #define EIGEN_GENERIC_PACKET_MATH_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| /** \internal | ||||
|   * \file GenericPacketMath.h | ||||
|   * | ||||
|   * Default implementation for types not supported by the vectorization. | ||||
|   * In practice these functions are provided to make easier the writing | ||||
|   * of generic vectorized code. | ||||
|   */ | ||||
|  | ||||
| #ifndef EIGEN_DEBUG_ALIGNED_LOAD | ||||
| #define EIGEN_DEBUG_ALIGNED_LOAD | ||||
| #endif | ||||
|  | ||||
| #ifndef EIGEN_DEBUG_UNALIGNED_LOAD | ||||
| #define EIGEN_DEBUG_UNALIGNED_LOAD | ||||
| #endif | ||||
|  | ||||
| #ifndef EIGEN_DEBUG_ALIGNED_STORE | ||||
| #define EIGEN_DEBUG_ALIGNED_STORE | ||||
| #endif | ||||
|  | ||||
| #ifndef EIGEN_DEBUG_UNALIGNED_STORE | ||||
| #define EIGEN_DEBUG_UNALIGNED_STORE | ||||
| #endif | ||||
|  | ||||
| struct default_packet_traits | ||||
| { | ||||
|   enum { | ||||
|     HasAdd    = 1, | ||||
|     HasSub    = 1, | ||||
|     HasMul    = 1, | ||||
|     HasNegate = 1, | ||||
|     HasAbs    = 1, | ||||
|     HasAbs2   = 1, | ||||
|     HasMin    = 1, | ||||
|     HasMax    = 1, | ||||
|     HasConj   = 1, | ||||
|     HasSetLinear = 1, | ||||
|  | ||||
|     HasDiv    = 0, | ||||
|     HasSqrt   = 0, | ||||
|     HasExp    = 0, | ||||
|     HasLog    = 0, | ||||
|     HasPow    = 0, | ||||
|  | ||||
|     HasSin    = 0, | ||||
|     HasCos    = 0, | ||||
|     HasTan    = 0, | ||||
|     HasASin   = 0, | ||||
|     HasACos   = 0, | ||||
|     HasATan   = 0 | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| template<typename T> struct packet_traits : default_packet_traits | ||||
| { | ||||
|   typedef T type; | ||||
|   enum { | ||||
|     Vectorizable = 0, | ||||
|     size = 1, | ||||
|     AlignedOnScalar = 0 | ||||
|   }; | ||||
|   enum { | ||||
|     HasAdd    = 0, | ||||
|     HasSub    = 0, | ||||
|     HasMul    = 0, | ||||
|     HasNegate = 0, | ||||
|     HasAbs    = 0, | ||||
|     HasAbs2   = 0, | ||||
|     HasMin    = 0, | ||||
|     HasMax    = 0, | ||||
|     HasConj   = 0, | ||||
|     HasSetLinear = 0 | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /** \internal \returns a + b (coeff-wise) */ | ||||
| template<typename Packet> inline Packet | ||||
| padd(const Packet& a, | ||||
|         const Packet& b) { return a+b; } | ||||
|  | ||||
| /** \internal \returns a - b (coeff-wise) */ | ||||
| template<typename Packet> inline Packet | ||||
| psub(const Packet& a, | ||||
|         const Packet& b) { return a-b; } | ||||
|  | ||||
| /** \internal \returns -a (coeff-wise) */ | ||||
| template<typename Packet> inline Packet | ||||
| pnegate(const Packet& a) { return -a; } | ||||
|  | ||||
| /** \internal \returns conj(a) (coeff-wise) */ | ||||
| template<typename Packet> inline Packet | ||||
| pconj(const Packet& a) { return conj(a); } | ||||
|  | ||||
| /** \internal \returns a * b (coeff-wise) */ | ||||
| template<typename Packet> inline Packet | ||||
| pmul(const Packet& a, | ||||
|         const Packet& b) { return a*b; } | ||||
|  | ||||
| /** \internal \returns a / b (coeff-wise) */ | ||||
| template<typename Packet> inline Packet | ||||
| pdiv(const Packet& a, | ||||
|         const Packet& b) { return a/b; } | ||||
|  | ||||
| /** \internal \returns the min of \a a and \a b  (coeff-wise) */ | ||||
| template<typename Packet> inline Packet | ||||
| pmin(const Packet& a, | ||||
|         const Packet& b) { using std::min; return (min)(a, b); } | ||||
|  | ||||
| /** \internal \returns the max of \a a and \a b  (coeff-wise) */ | ||||
| template<typename Packet> inline Packet | ||||
| pmax(const Packet& a, | ||||
|         const Packet& b) { using std::max; return (max)(a, b); } | ||||
|  | ||||
| /** \internal \returns the absolute value of \a a */ | ||||
| template<typename Packet> inline Packet | ||||
| pabs(const Packet& a) { return abs(a); } | ||||
|  | ||||
| /** \internal \returns the bitwise and of \a a and \a b */ | ||||
| template<typename Packet> inline Packet | ||||
| pand(const Packet& a, const Packet& b) { return a & b; } | ||||
|  | ||||
| /** \internal \returns the bitwise or of \a a and \a b */ | ||||
| template<typename Packet> inline Packet | ||||
| por(const Packet& a, const Packet& b) { return a | b; } | ||||
|  | ||||
| /** \internal \returns the bitwise xor of \a a and \a b */ | ||||
| template<typename Packet> inline Packet | ||||
| pxor(const Packet& a, const Packet& b) { return a ^ b; } | ||||
|  | ||||
| /** \internal \returns the bitwise andnot of \a a and \a b */ | ||||
| template<typename Packet> inline Packet | ||||
| pandnot(const Packet& a, const Packet& b) { return a & (!b); } | ||||
|  | ||||
| /** \internal \returns a packet version of \a *from, from must be 16 bytes aligned */ | ||||
| template<typename Packet> inline Packet | ||||
| pload(const typename unpacket_traits<Packet>::type* from) { return *from; } | ||||
|  | ||||
| /** \internal \returns a packet version of \a *from, (un-aligned load) */ | ||||
| template<typename Packet> inline Packet | ||||
| ploadu(const typename unpacket_traits<Packet>::type* from) { return *from; } | ||||
|  | ||||
| /** \internal \returns a packet with elements of \a *from duplicated, e.g.: (from[0],from[0],from[1],from[1]) */ | ||||
| template<typename Packet> inline Packet | ||||
| ploaddup(const typename unpacket_traits<Packet>::type* from) { return *from; } | ||||
|  | ||||
| /** \internal \returns a packet with constant coefficients \a a, e.g.: (a,a,a,a) */ | ||||
| template<typename Packet> inline Packet | ||||
| pset1(const typename unpacket_traits<Packet>::type& a) { return a; } | ||||
|  | ||||
| /** \internal \brief Returns a packet with coefficients (a,a+1,...,a+packet_size-1). */ | ||||
| template<typename Scalar> inline typename packet_traits<Scalar>::type | ||||
| plset(const Scalar& a) { return a; } | ||||
|  | ||||
| /** \internal copy the packet \a from to \a *to, \a to must be 16 bytes aligned */ | ||||
| template<typename Scalar, typename Packet> inline void pstore(Scalar* to, const Packet& from) | ||||
| { (*to) = from; } | ||||
|  | ||||
| /** \internal copy the packet \a from to \a *to, (un-aligned store) */ | ||||
| template<typename Scalar, typename Packet> inline void pstoreu(Scalar* to, const Packet& from) | ||||
| { (*to) = from; } | ||||
|  | ||||
| /** \internal tries to do cache prefetching of \a addr */ | ||||
| template<typename Scalar> inline void prefetch(const Scalar* addr) | ||||
| { | ||||
| #if !defined(_MSC_VER) | ||||
| __builtin_prefetch(addr); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| /** \internal \returns the first element of a packet */ | ||||
| template<typename Packet> inline typename unpacket_traits<Packet>::type pfirst(const Packet& a) | ||||
| { return a; } | ||||
|  | ||||
| /** \internal \returns a packet where the element i contains the sum of the packet of \a vec[i] */ | ||||
| template<typename Packet> inline Packet | ||||
| preduxp(const Packet* vecs) { return vecs[0]; } | ||||
|  | ||||
| /** \internal \returns the sum of the elements of \a a*/ | ||||
| template<typename Packet> inline typename unpacket_traits<Packet>::type predux(const Packet& a) | ||||
| { return a; } | ||||
|  | ||||
| /** \internal \returns the product of the elements of \a a*/ | ||||
| template<typename Packet> inline typename unpacket_traits<Packet>::type predux_mul(const Packet& a) | ||||
| { return a; } | ||||
|  | ||||
| /** \internal \returns the min of the elements of \a a*/ | ||||
| template<typename Packet> inline typename unpacket_traits<Packet>::type predux_min(const Packet& a) | ||||
| { return a; } | ||||
|  | ||||
| /** \internal \returns the max of the elements of \a a*/ | ||||
| template<typename Packet> inline typename unpacket_traits<Packet>::type predux_max(const Packet& a) | ||||
| { return a; } | ||||
|  | ||||
| /** \internal \returns the reversed elements of \a a*/ | ||||
| template<typename Packet> inline Packet preverse(const Packet& a) | ||||
| { return a; } | ||||
|  | ||||
|  | ||||
| /** \internal \returns \a a with real and imaginary part flipped (for complex type only) */ | ||||
| template<typename Packet> inline Packet pcplxflip(const Packet& a) | ||||
| { return Packet(imag(a),real(a)); } | ||||
|  | ||||
| /************************** | ||||
| * Special math functions | ||||
| ***************************/ | ||||
|  | ||||
| /** \internal \returns the sine of \a a (coeff-wise) */ | ||||
| template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS | ||||
| Packet psin(const Packet& a) { return sin(a); } | ||||
|  | ||||
| /** \internal \returns the cosine of \a a (coeff-wise) */ | ||||
| template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS | ||||
| Packet pcos(const Packet& a) { return cos(a); } | ||||
|  | ||||
| /** \internal \returns the tan of \a a (coeff-wise) */ | ||||
| template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS | ||||
| Packet ptan(const Packet& a) { return tan(a); } | ||||
|  | ||||
| /** \internal \returns the arc sine of \a a (coeff-wise) */ | ||||
| template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS | ||||
| Packet pasin(const Packet& a) { return asin(a); } | ||||
|  | ||||
| /** \internal \returns the arc cosine of \a a (coeff-wise) */ | ||||
| template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS | ||||
| Packet pacos(const Packet& a) { return acos(a); } | ||||
|  | ||||
| /** \internal \returns the exp of \a a (coeff-wise) */ | ||||
| template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS | ||||
| Packet pexp(const Packet& a) { return exp(a); } | ||||
|  | ||||
| /** \internal \returns the log of \a a (coeff-wise) */ | ||||
| template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS | ||||
| Packet plog(const Packet& a) { return log(a); } | ||||
|  | ||||
| /** \internal \returns the square-root of \a a (coeff-wise) */ | ||||
| template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS | ||||
| Packet psqrt(const Packet& a) { return sqrt(a); } | ||||
|  | ||||
| /*************************************************************************** | ||||
| * The following functions might not have to be overwritten for vectorized types | ||||
| ***************************************************************************/ | ||||
|  | ||||
| /** \internal copy a packet with constant coeficient \a a (e.g., [a,a,a,a]) to \a *to. \a to must be 16 bytes aligned */ | ||||
| // NOTE: this function must really be templated on the packet type (think about different packet types for the same scalar type) | ||||
| template<typename Packet> | ||||
| inline void pstore1(typename unpacket_traits<Packet>::type* to, const typename unpacket_traits<Packet>::type& a) | ||||
| { | ||||
|   pstore(to, pset1<Packet>(a)); | ||||
| } | ||||
|  | ||||
| /** \internal \returns a * b + c (coeff-wise) */ | ||||
| template<typename Packet> inline Packet | ||||
| pmadd(const Packet&  a, | ||||
|          const Packet&  b, | ||||
|          const Packet&  c) | ||||
| { return padd(pmul(a, b),c); } | ||||
|  | ||||
| /** \internal \returns a packet version of \a *from. | ||||
|   * If LoadMode equals #Aligned, \a from must be 16 bytes aligned */ | ||||
| template<typename Packet, int LoadMode> | ||||
| inline Packet ploadt(const typename unpacket_traits<Packet>::type* from) | ||||
| { | ||||
|   if(LoadMode == Aligned) | ||||
|     return pload<Packet>(from); | ||||
|   else | ||||
|     return ploadu<Packet>(from); | ||||
| } | ||||
|  | ||||
| /** \internal copy the packet \a from to \a *to. | ||||
|   * If StoreMode equals #Aligned, \a to must be 16 bytes aligned */ | ||||
| template<typename Scalar, typename Packet, int LoadMode> | ||||
| inline void pstoret(Scalar* to, const Packet& from) | ||||
| { | ||||
|   if(LoadMode == Aligned) | ||||
|     pstore(to, from); | ||||
|   else | ||||
|     pstoreu(to, from); | ||||
| } | ||||
|  | ||||
| /** \internal default implementation of palign() allowing partial specialization */ | ||||
| template<int Offset,typename PacketType> | ||||
| struct palign_impl | ||||
| { | ||||
|   // by default data are aligned, so there is nothing to be done :) | ||||
|   static inline void run(PacketType&, const PacketType&) {} | ||||
| }; | ||||
|  | ||||
| /** \internal update \a first using the concatenation of the \a Offset last elements | ||||
|   * of \a first and packet_size minus \a Offset first elements of \a second */ | ||||
| template<int Offset,typename PacketType> | ||||
| inline void palign(PacketType& first, const PacketType& second) | ||||
| { | ||||
|   palign_impl<Offset,PacketType>::run(first,second); | ||||
| } | ||||
|  | ||||
| /*************************************************************************** | ||||
| * Fast complex products (GCC generates a function call which is very slow) | ||||
| ***************************************************************************/ | ||||
|  | ||||
| template<> inline std::complex<float> pmul(const std::complex<float>& a, const std::complex<float>& b) | ||||
| { return std::complex<float>(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); } | ||||
|  | ||||
| template<> inline std::complex<double> pmul(const std::complex<double>& a, const std::complex<double>& b) | ||||
| { return std::complex<double>(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); } | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_GENERIC_PACKET_MATH_H | ||||
|  | ||||
							
								
								
									
										103
									
								
								latan/Eigen/src/Core/GlobalFunctions.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								latan/Eigen/src/Core/GlobalFunctions.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_GLOBAL_FUNCTIONS_H | ||||
| #define EIGEN_GLOBAL_FUNCTIONS_H | ||||
|  | ||||
| #define EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(NAME,FUNCTOR) \ | ||||
|   template<typename Derived> \ | ||||
|   inline const Eigen::CwiseUnaryOp<Eigen::internal::FUNCTOR<typename Derived::Scalar>, const Derived> \ | ||||
|   NAME(const Eigen::ArrayBase<Derived>& x) { \ | ||||
|     return x.derived(); \ | ||||
|   } | ||||
|  | ||||
| #define EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(NAME,FUNCTOR) \ | ||||
|   \ | ||||
|   template<typename Derived> \ | ||||
|   struct NAME##_retval<ArrayBase<Derived> > \ | ||||
|   { \ | ||||
|     typedef const Eigen::CwiseUnaryOp<Eigen::internal::FUNCTOR<typename Derived::Scalar>, const Derived> type; \ | ||||
|   }; \ | ||||
|   template<typename Derived> \ | ||||
|   struct NAME##_impl<ArrayBase<Derived> > \ | ||||
|   { \ | ||||
|     static inline typename NAME##_retval<ArrayBase<Derived> >::type run(const Eigen::ArrayBase<Derived>& x) \ | ||||
|     { \ | ||||
|       return x.derived(); \ | ||||
|     } \ | ||||
|   }; | ||||
|  | ||||
|  | ||||
| namespace std | ||||
| { | ||||
|   EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(real,scalar_real_op) | ||||
|   EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(imag,scalar_imag_op) | ||||
|   EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(sin,scalar_sin_op) | ||||
|   EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(cos,scalar_cos_op) | ||||
|   EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(asin,scalar_asin_op) | ||||
|   EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(acos,scalar_acos_op) | ||||
|   EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(tan,scalar_tan_op) | ||||
|   EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(exp,scalar_exp_op) | ||||
|   EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(log,scalar_log_op) | ||||
|   EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(abs,scalar_abs_op) | ||||
|   EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(sqrt,scalar_sqrt_op) | ||||
|  | ||||
|   template<typename Derived> | ||||
|   inline const Eigen::CwiseUnaryOp<Eigen::internal::scalar_pow_op<typename Derived::Scalar>, const Derived> | ||||
|   pow(const Eigen::ArrayBase<Derived>& x, const typename Derived::Scalar& exponent) { | ||||
|     return x.derived().pow(exponent); | ||||
|   } | ||||
|  | ||||
|   template<typename Derived> | ||||
|   inline const Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename Derived::Scalar>, const Derived, const Derived> | ||||
|   pow(const Eigen::ArrayBase<Derived>& x, const Eigen::ArrayBase<Derived>& exponents)  | ||||
|   { | ||||
|     return Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename Derived::Scalar>, const Derived, const Derived>( | ||||
|       x.derived(), | ||||
|       exponents.derived() | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|  | ||||
| namespace Eigen | ||||
| { | ||||
|   /** | ||||
|   * \brief Component-wise division of a scalar by array elements. | ||||
|   **/ | ||||
|   template <typename Derived> | ||||
|   inline const Eigen::CwiseUnaryOp<Eigen::internal::scalar_inverse_mult_op<typename Derived::Scalar>, const Derived> | ||||
|     operator/(typename Derived::Scalar s, const Eigen::ArrayBase<Derived>& a) | ||||
|   { | ||||
|     return Eigen::CwiseUnaryOp<Eigen::internal::scalar_inverse_mult_op<typename Derived::Scalar>, const Derived>( | ||||
|       a.derived(), | ||||
|       Eigen::internal::scalar_inverse_mult_op<typename Derived::Scalar>(s)   | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   namespace internal | ||||
|   { | ||||
|     EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(real,scalar_real_op) | ||||
|     EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(imag,scalar_imag_op) | ||||
|     EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(sin,scalar_sin_op) | ||||
|     EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(cos,scalar_cos_op) | ||||
|     EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(asin,scalar_asin_op) | ||||
|     EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(acos,scalar_acos_op) | ||||
|     EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(tan,scalar_tan_op) | ||||
|     EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(exp,scalar_exp_op) | ||||
|     EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(log,scalar_log_op) | ||||
|     EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(abs,scalar_abs_op) | ||||
|     EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(abs2,scalar_abs2_op) | ||||
|     EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(sqrt,scalar_sqrt_op) | ||||
|   } | ||||
| } | ||||
|  | ||||
| // TODO: cleanly disable those functions that are not supported on Array (internal::real_ref, internal::random, internal::isApprox...) | ||||
|  | ||||
| #endif // EIGEN_GLOBAL_FUNCTIONS_H | ||||
							
								
								
									
										249
									
								
								latan/Eigen/src/Core/IO.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										249
									
								
								latan/Eigen/src/Core/IO.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,249 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_IO_H | ||||
| #define EIGEN_IO_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| enum { DontAlignCols = 1 }; | ||||
| enum { StreamPrecision = -1, | ||||
|        FullPrecision = -2 }; | ||||
|  | ||||
| namespace internal { | ||||
| template<typename Derived> | ||||
| std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt); | ||||
| } | ||||
|  | ||||
| /** \class IOFormat | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Stores a set of parameters controlling the way matrices are printed | ||||
|   * | ||||
|   * List of available parameters: | ||||
|   *  - \b precision number of digits for floating point values, or one of the special constants \c StreamPrecision and \c FullPrecision. | ||||
|   *                 The default is the special value \c StreamPrecision which means to use the | ||||
|   *                 stream's own precision setting, as set for instance using \c cout.precision(3). The other special value | ||||
|   *                 \c FullPrecision means that the number of digits will be computed to match the full precision of each floating-point | ||||
|   *                 type. | ||||
|   *  - \b flags an OR-ed combination of flags, the default value is 0, the only currently available flag is \c DontAlignCols which | ||||
|   *             allows to disable the alignment of columns, resulting in faster code. | ||||
|   *  - \b coeffSeparator string printed between two coefficients of the same row | ||||
|   *  - \b rowSeparator string printed between two rows | ||||
|   *  - \b rowPrefix string printed at the beginning of each row | ||||
|   *  - \b rowSuffix string printed at the end of each row | ||||
|   *  - \b matPrefix string printed at the beginning of the matrix | ||||
|   *  - \b matSuffix string printed at the end of the matrix | ||||
|   * | ||||
|   * Example: \include IOFormat.cpp | ||||
|   * Output: \verbinclude IOFormat.out | ||||
|   * | ||||
|   * \sa DenseBase::format(), class WithFormat | ||||
|   */ | ||||
| struct IOFormat | ||||
| { | ||||
|   /** Default contructor, see class IOFormat for the meaning of the parameters */ | ||||
|   IOFormat(int _precision = StreamPrecision, int _flags = 0, | ||||
|     const std::string& _coeffSeparator = " ", | ||||
|     const std::string& _rowSeparator = "\n", const std::string& _rowPrefix="", const std::string& _rowSuffix="", | ||||
|     const std::string& _matPrefix="", const std::string& _matSuffix="") | ||||
|   : matPrefix(_matPrefix), matSuffix(_matSuffix), rowPrefix(_rowPrefix), rowSuffix(_rowSuffix), rowSeparator(_rowSeparator), | ||||
|     coeffSeparator(_coeffSeparator), precision(_precision), flags(_flags) | ||||
|   { | ||||
|     rowSpacer = ""; | ||||
|     int i = int(matSuffix.length())-1; | ||||
|     while (i>=0 && matSuffix[i]!='\n') | ||||
|     { | ||||
|       rowSpacer += ' '; | ||||
|       i--; | ||||
|     } | ||||
|   } | ||||
|   std::string matPrefix, matSuffix; | ||||
|   std::string rowPrefix, rowSuffix, rowSeparator, rowSpacer; | ||||
|   std::string coeffSeparator; | ||||
|   int precision; | ||||
|   int flags; | ||||
| }; | ||||
|  | ||||
| /** \class WithFormat | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Pseudo expression providing matrix output with given format | ||||
|   * | ||||
|   * \param ExpressionType the type of the object on which IO stream operations are performed | ||||
|   * | ||||
|   * This class represents an expression with stream operators controlled by a given IOFormat. | ||||
|   * It is the return type of DenseBase::format() | ||||
|   * and most of the time this is the only way it is used. | ||||
|   * | ||||
|   * See class IOFormat for some examples. | ||||
|   * | ||||
|   * \sa DenseBase::format(), class IOFormat | ||||
|   */ | ||||
| template<typename ExpressionType> | ||||
| class WithFormat | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     WithFormat(const ExpressionType& matrix, const IOFormat& format) | ||||
|       : m_matrix(matrix), m_format(format) | ||||
|     {} | ||||
|  | ||||
|     friend std::ostream & operator << (std::ostream & s, const WithFormat& wf) | ||||
|     { | ||||
|       return internal::print_matrix(s, wf.m_matrix.eval(), wf.m_format); | ||||
|     } | ||||
|  | ||||
|   protected: | ||||
|     const typename ExpressionType::Nested m_matrix; | ||||
|     IOFormat m_format; | ||||
| }; | ||||
|  | ||||
| /** \returns a WithFormat proxy object allowing to print a matrix the with given | ||||
|   * format \a fmt. | ||||
|   * | ||||
|   * See class IOFormat for some examples. | ||||
|   * | ||||
|   * \sa class IOFormat, class WithFormat | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline const WithFormat<Derived> | ||||
| DenseBase<Derived>::format(const IOFormat& fmt) const | ||||
| { | ||||
|   return WithFormat<Derived>(derived(), fmt); | ||||
| } | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename Scalar, bool IsInteger> | ||||
| struct significant_decimals_default_impl | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|   static inline int run() | ||||
|   { | ||||
|     using std::ceil; | ||||
|     return cast<RealScalar,int>(ceil(-log(NumTraits<RealScalar>::epsilon())/log(RealScalar(10)))); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct significant_decimals_default_impl<Scalar, true> | ||||
| { | ||||
|   static inline int run() | ||||
|   { | ||||
|     return 0; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct significant_decimals_impl | ||||
|   : significant_decimals_default_impl<Scalar, NumTraits<Scalar>::IsInteger> | ||||
| {}; | ||||
|  | ||||
| /** \internal | ||||
|   * print the matrix \a _m to the output stream \a s using the output format \a fmt */ | ||||
| template<typename Derived> | ||||
| std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt) | ||||
| { | ||||
|   if(_m.size() == 0) | ||||
|   { | ||||
|     s << fmt.matPrefix << fmt.matSuffix; | ||||
|     return s; | ||||
|   } | ||||
|    | ||||
|   typename Derived::Nested m = _m; | ||||
|   typedef typename Derived::Scalar Scalar; | ||||
|   typedef typename Derived::Index Index; | ||||
|  | ||||
|   Index width = 0; | ||||
|  | ||||
|   std::streamsize explicit_precision; | ||||
|   if(fmt.precision == StreamPrecision) | ||||
|   { | ||||
|     explicit_precision = 0; | ||||
|   } | ||||
|   else if(fmt.precision == FullPrecision) | ||||
|   { | ||||
|     if (NumTraits<Scalar>::IsInteger) | ||||
|     { | ||||
|       explicit_precision = 0; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|       explicit_precision = significant_decimals_impl<Scalar>::run(); | ||||
|     } | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     explicit_precision = fmt.precision; | ||||
|   } | ||||
|  | ||||
|   bool align_cols = !(fmt.flags & DontAlignCols); | ||||
|   if(align_cols) | ||||
|   { | ||||
|     // compute the largest width | ||||
|     for(Index j = 1; j < m.cols(); ++j) | ||||
|       for(Index i = 0; i < m.rows(); ++i) | ||||
|       { | ||||
|         std::stringstream sstr; | ||||
|         if(explicit_precision) sstr.precision(explicit_precision); | ||||
|         sstr << m.coeff(i,j); | ||||
|         width = std::max<Index>(width, Index(sstr.str().length())); | ||||
|       } | ||||
|   } | ||||
|   std::streamsize old_precision = 0; | ||||
|   if(explicit_precision) old_precision = s.precision(explicit_precision); | ||||
|   s << fmt.matPrefix; | ||||
|   for(Index i = 0; i < m.rows(); ++i) | ||||
|   { | ||||
|     if (i) | ||||
|       s << fmt.rowSpacer; | ||||
|     s << fmt.rowPrefix; | ||||
|     if(width) s.width(width); | ||||
|     s << m.coeff(i, 0); | ||||
|     for(Index j = 1; j < m.cols(); ++j) | ||||
|     { | ||||
|       s << fmt.coeffSeparator; | ||||
|       if (width) s.width(width); | ||||
|       s << m.coeff(i, j); | ||||
|     } | ||||
|     s << fmt.rowSuffix; | ||||
|     if( i < m.rows() - 1) | ||||
|       s << fmt.rowSeparator; | ||||
|   } | ||||
|   s << fmt.matSuffix; | ||||
|   if(explicit_precision) s.precision(old_precision); | ||||
|   return s; | ||||
| } | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /** \relates DenseBase | ||||
|   * | ||||
|   * Outputs the matrix, to the given stream. | ||||
|   * | ||||
|   * If you wish to print the matrix with a format different than the default, use DenseBase::format(). | ||||
|   * | ||||
|   * It is also possible to change the default format by defining EIGEN_DEFAULT_IO_FORMAT before including Eigen headers. | ||||
|   * If not defined, this will automatically be defined to Eigen::IOFormat(), that is the Eigen::IOFormat with default parameters. | ||||
|   * | ||||
|   * \sa DenseBase::format() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| std::ostream & operator << | ||||
| (std::ostream & s, | ||||
|  const DenseBase<Derived> & m) | ||||
| { | ||||
|   return internal::print_matrix(s, m.eval(), EIGEN_DEFAULT_IO_FORMAT); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_IO_H | ||||
							
								
								
									
										192
									
								
								latan/Eigen/src/Core/Map.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								latan/Eigen/src/Core/Map.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,192 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_MAP_H | ||||
| #define EIGEN_MAP_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class Map | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief A matrix or vector expression mapping an existing array of data. | ||||
|   * | ||||
|   * \tparam PlainObjectType the equivalent matrix type of the mapped data | ||||
|   * \tparam MapOptions specifies whether the pointer is \c #Aligned, or \c #Unaligned. | ||||
|   *                The default is \c #Unaligned. | ||||
|   * \tparam StrideType optionally specifies strides. By default, Map assumes the memory layout | ||||
|   *                   of an ordinary, contiguous array. This can be overridden by specifying strides. | ||||
|   *                   The type passed here must be a specialization of the Stride template, see examples below. | ||||
|   * | ||||
|   * This class represents a matrix or vector expression mapping an existing array of data. | ||||
|   * It can be used to let Eigen interface without any overhead with non-Eigen data structures, | ||||
|   * such as plain C arrays or structures from other libraries. By default, it assumes that the | ||||
|   * data is laid out contiguously in memory. You can however override this by explicitly specifying | ||||
|   * inner and outer strides. | ||||
|   * | ||||
|   * Here's an example of simply mapping a contiguous array as a \ref TopicStorageOrders "column-major" matrix: | ||||
|   * \include Map_simple.cpp | ||||
|   * Output: \verbinclude Map_simple.out | ||||
|   * | ||||
|   * If you need to map non-contiguous arrays, you can do so by specifying strides: | ||||
|   * | ||||
|   * Here's an example of mapping an array as a vector, specifying an inner stride, that is, the pointer | ||||
|   * increment between two consecutive coefficients. Here, we're specifying the inner stride as a compile-time | ||||
|   * fixed value. | ||||
|   * \include Map_inner_stride.cpp | ||||
|   * Output: \verbinclude Map_inner_stride.out | ||||
|   * | ||||
|   * Here's an example of mapping an array while specifying an outer stride. Here, since we're mapping | ||||
|   * as a column-major matrix, 'outer stride' means the pointer increment between two consecutive columns. | ||||
|   * Here, we're specifying the outer stride as a runtime parameter. Note that here \c OuterStride<> is | ||||
|   * a short version of \c OuterStride<Dynamic> because the default template parameter of OuterStride | ||||
|   * is  \c Dynamic | ||||
|   * \include Map_outer_stride.cpp | ||||
|   * Output: \verbinclude Map_outer_stride.out | ||||
|   * | ||||
|   * For more details and for an example of specifying both an inner and an outer stride, see class Stride. | ||||
|   * | ||||
|   * \b Tip: to change the array of data mapped by a Map object, you can use the C++ | ||||
|   * placement new syntax: | ||||
|   * | ||||
|   * Example: \include Map_placement_new.cpp | ||||
|   * Output: \verbinclude Map_placement_new.out | ||||
|   * | ||||
|   * This class is the return type of PlainObjectBase::Map() but can also be used directly. | ||||
|   * | ||||
|   * \sa PlainObjectBase::Map(), \ref TopicStorageOrders | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename PlainObjectType, int MapOptions, typename StrideType> | ||||
| struct traits<Map<PlainObjectType, MapOptions, StrideType> > | ||||
|   : public traits<PlainObjectType> | ||||
| { | ||||
|   typedef traits<PlainObjectType> TraitsBase; | ||||
|   typedef typename PlainObjectType::Index Index; | ||||
|   typedef typename PlainObjectType::Scalar Scalar; | ||||
|   enum { | ||||
|     InnerStrideAtCompileTime = StrideType::InnerStrideAtCompileTime == 0 | ||||
|                              ? int(PlainObjectType::InnerStrideAtCompileTime) | ||||
|                              : int(StrideType::InnerStrideAtCompileTime), | ||||
|     OuterStrideAtCompileTime = StrideType::OuterStrideAtCompileTime == 0 | ||||
|                              ? int(PlainObjectType::OuterStrideAtCompileTime) | ||||
|                              : int(StrideType::OuterStrideAtCompileTime), | ||||
|     HasNoInnerStride = InnerStrideAtCompileTime == 1, | ||||
|     HasNoOuterStride = StrideType::OuterStrideAtCompileTime == 0, | ||||
|     HasNoStride = HasNoInnerStride && HasNoOuterStride, | ||||
|     IsAligned = bool(EIGEN_ALIGN) && ((int(MapOptions)&Aligned)==Aligned), | ||||
|     IsDynamicSize = PlainObjectType::SizeAtCompileTime==Dynamic, | ||||
|     KeepsPacketAccess = bool(HasNoInnerStride) | ||||
|                         && ( bool(IsDynamicSize) | ||||
|                            || HasNoOuterStride | ||||
|                            || ( OuterStrideAtCompileTime!=Dynamic | ||||
|                            && ((static_cast<int>(sizeof(Scalar))*OuterStrideAtCompileTime)%16)==0 ) ), | ||||
|     Flags0 = TraitsBase::Flags & (~NestByRefBit), | ||||
|     Flags1 = IsAligned ? (int(Flags0) | AlignedBit) : (int(Flags0) & ~AlignedBit), | ||||
|     Flags2 = (bool(HasNoStride) || bool(PlainObjectType::IsVectorAtCompileTime)) | ||||
|            ? int(Flags1) : int(Flags1 & ~LinearAccessBit), | ||||
|     Flags3 = is_lvalue<PlainObjectType>::value ? int(Flags2) : (int(Flags2) & ~LvalueBit), | ||||
|     Flags = KeepsPacketAccess ? int(Flags3) : (int(Flags3) & ~PacketAccessBit) | ||||
|   }; | ||||
| private: | ||||
|   enum { Options }; // Expressions don't have Options | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename PlainObjectType, int MapOptions, typename StrideType> class Map | ||||
|   : public MapBase<Map<PlainObjectType, MapOptions, StrideType> > | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef MapBase<Map> Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(Map) | ||||
|  | ||||
|     typedef typename Base::PointerType PointerType; | ||||
| #if EIGEN2_SUPPORT_STAGE <= STAGE30_FULL_EIGEN3_API | ||||
|     typedef const Scalar* PointerArgType; | ||||
|     inline PointerType cast_to_pointer_type(PointerArgType ptr) { return const_cast<PointerType>(ptr); } | ||||
| #else | ||||
|     typedef PointerType PointerArgType; | ||||
|     inline PointerType cast_to_pointer_type(PointerArgType ptr) { return ptr; } | ||||
| #endif | ||||
|  | ||||
|     inline Index innerStride() const | ||||
|     { | ||||
|       return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1; | ||||
|     } | ||||
|  | ||||
|     inline Index outerStride() const | ||||
|     { | ||||
|       return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer() | ||||
|            : IsVectorAtCompileTime ? this->size() | ||||
|            : int(Flags)&RowMajorBit ? this->cols() | ||||
|            : this->rows(); | ||||
|     } | ||||
|  | ||||
|     /** Constructor in the fixed-size case. | ||||
|       * | ||||
|       * \param data pointer to the array to map | ||||
|       * \param stride optional Stride object, passing the strides. | ||||
|       */ | ||||
|     inline Map(PointerArgType data, const StrideType& stride = StrideType()) | ||||
|       : Base(cast_to_pointer_type(data)), m_stride(stride) | ||||
|     { | ||||
|       PlainObjectType::Base::_check_template_params(); | ||||
|     } | ||||
|  | ||||
|     /** Constructor in the dynamic-size vector case. | ||||
|       * | ||||
|       * \param data pointer to the array to map | ||||
|       * \param size the size of the vector expression | ||||
|       * \param stride optional Stride object, passing the strides. | ||||
|       */ | ||||
|     inline Map(PointerArgType data, Index size, const StrideType& stride = StrideType()) | ||||
|       : Base(cast_to_pointer_type(data), size), m_stride(stride) | ||||
|     { | ||||
|       PlainObjectType::Base::_check_template_params(); | ||||
|     } | ||||
|  | ||||
|     /** Constructor in the dynamic-size matrix case. | ||||
|       * | ||||
|       * \param data pointer to the array to map | ||||
|       * \param rows the number of rows of the matrix expression | ||||
|       * \param cols the number of columns of the matrix expression | ||||
|       * \param stride optional Stride object, passing the strides. | ||||
|       */ | ||||
|     inline Map(PointerArgType data, Index rows, Index cols, const StrideType& stride = StrideType()) | ||||
|       : Base(cast_to_pointer_type(data), rows, cols), m_stride(stride) | ||||
|     { | ||||
|       PlainObjectType::Base::_check_template_params(); | ||||
|     } | ||||
|  | ||||
|     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map) | ||||
|  | ||||
|   protected: | ||||
|     StrideType m_stride; | ||||
| }; | ||||
|  | ||||
| template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> | ||||
| inline Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> | ||||
|   ::Array(const Scalar *data) | ||||
| { | ||||
|   this->_set_noalias(Eigen::Map<const Array>(data)); | ||||
| } | ||||
|  | ||||
| template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> | ||||
| inline Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> | ||||
|   ::Matrix(const Scalar *data) | ||||
| { | ||||
|   this->_set_noalias(Eigen::Map<const Matrix>(data)); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_MAP_H | ||||
							
								
								
									
										242
									
								
								latan/Eigen/src/Core/MapBase.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								latan/Eigen/src/Core/MapBase.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,242 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_MAPBASE_H | ||||
| #define EIGEN_MAPBASE_H | ||||
|  | ||||
| #define EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) \ | ||||
|       EIGEN_STATIC_ASSERT((int(internal::traits<Derived>::Flags) & LinearAccessBit) || Derived::IsVectorAtCompileTime, \ | ||||
|                           YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT) | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class MapBase | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Base class for Map and Block expression with direct access | ||||
|   * | ||||
|   * \sa class Map, class Block | ||||
|   */ | ||||
| template<typename Derived> class MapBase<Derived, ReadOnlyAccessors> | ||||
|   : public internal::dense_xpr_base<Derived>::type | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef typename internal::dense_xpr_base<Derived>::type Base; | ||||
|     enum { | ||||
|       RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime, | ||||
|       ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime, | ||||
|       SizeAtCompileTime = Base::SizeAtCompileTime | ||||
|     }; | ||||
|  | ||||
|     typedef typename internal::traits<Derived>::StorageKind StorageKind; | ||||
|     typedef typename internal::traits<Derived>::Index Index; | ||||
|     typedef typename internal::traits<Derived>::Scalar Scalar; | ||||
|     typedef typename internal::packet_traits<Scalar>::type PacketScalar; | ||||
|     typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|     typedef typename internal::conditional< | ||||
|                          bool(internal::is_lvalue<Derived>::value), | ||||
|                          Scalar *, | ||||
|                          const Scalar *>::type | ||||
|                      PointerType; | ||||
|  | ||||
|     using Base::derived; | ||||
| //    using Base::RowsAtCompileTime; | ||||
| //    using Base::ColsAtCompileTime; | ||||
| //    using Base::SizeAtCompileTime; | ||||
|     using Base::MaxRowsAtCompileTime; | ||||
|     using Base::MaxColsAtCompileTime; | ||||
|     using Base::MaxSizeAtCompileTime; | ||||
|     using Base::IsVectorAtCompileTime; | ||||
|     using Base::Flags; | ||||
|     using Base::IsRowMajor; | ||||
|  | ||||
|     using Base::rows; | ||||
|     using Base::cols; | ||||
|     using Base::size; | ||||
|     using Base::coeff; | ||||
|     using Base::coeffRef; | ||||
|     using Base::lazyAssign; | ||||
|     using Base::eval; | ||||
|  | ||||
|     using Base::innerStride; | ||||
|     using Base::outerStride; | ||||
|     using Base::rowStride; | ||||
|     using Base::colStride; | ||||
|  | ||||
|     // bug 217 - compile error on ICC 11.1 | ||||
|     using Base::operator=; | ||||
|  | ||||
|     typedef typename Base::CoeffReturnType CoeffReturnType; | ||||
|  | ||||
|     inline Index rows() const { return m_rows.value(); } | ||||
|     inline Index cols() const { return m_cols.value(); } | ||||
|  | ||||
|     /** Returns a pointer to the first coefficient of the matrix or vector. | ||||
|       * | ||||
|       * \note When addressing this data, make sure to honor the strides returned by innerStride() and outerStride(). | ||||
|       * | ||||
|       * \sa innerStride(), outerStride() | ||||
|       */ | ||||
|     inline const Scalar* data() const { return m_data; } | ||||
|  | ||||
|     inline const Scalar& coeff(Index row, Index col) const | ||||
|     { | ||||
|       return m_data[col * colStride() + row * rowStride()]; | ||||
|     } | ||||
|  | ||||
|     inline const Scalar& coeff(Index index) const | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) | ||||
|       return m_data[index * innerStride()]; | ||||
|     } | ||||
|  | ||||
|     inline const Scalar& coeffRef(Index row, Index col) const | ||||
|     { | ||||
|       return this->m_data[col * colStride() + row * rowStride()]; | ||||
|     } | ||||
|  | ||||
|     inline const Scalar& coeffRef(Index index) const | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) | ||||
|       return this->m_data[index * innerStride()]; | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline PacketScalar packet(Index row, Index col) const | ||||
|     { | ||||
|       return internal::ploadt<PacketScalar, LoadMode> | ||||
|                (m_data + (col * colStride() + row * rowStride())); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline PacketScalar packet(Index index) const | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) | ||||
|       return internal::ploadt<PacketScalar, LoadMode>(m_data + index * innerStride()); | ||||
|     } | ||||
|  | ||||
|     inline MapBase(PointerType data) : m_data(data), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) | ||||
|       checkSanity(); | ||||
|     } | ||||
|  | ||||
|     inline MapBase(PointerType data, Index size) | ||||
|             : m_data(data), | ||||
|               m_rows(RowsAtCompileTime == Dynamic ? size : Index(RowsAtCompileTime)), | ||||
|               m_cols(ColsAtCompileTime == Dynamic ? size : Index(ColsAtCompileTime)) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|       eigen_assert(size >= 0); | ||||
|       eigen_assert(data == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == size); | ||||
|       checkSanity(); | ||||
|     } | ||||
|  | ||||
|     inline MapBase(PointerType data, Index rows, Index cols) | ||||
|             : m_data(data), m_rows(rows), m_cols(cols) | ||||
|     { | ||||
|       eigen_assert( (data == 0) | ||||
|               || (   rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) | ||||
|                   && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols))); | ||||
|       checkSanity(); | ||||
|     } | ||||
|  | ||||
|   protected: | ||||
|  | ||||
|     void checkSanity() const | ||||
|     { | ||||
|       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) % 16) == 0) | ||||
|                    && "data is not aligned"); | ||||
|     } | ||||
|  | ||||
|     PointerType m_data; | ||||
|     const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows; | ||||
|     const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols; | ||||
| }; | ||||
|  | ||||
| template<typename Derived> class MapBase<Derived, WriteAccessors> | ||||
|   : public MapBase<Derived, ReadOnlyAccessors> | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef MapBase<Derived, ReadOnlyAccessors> Base; | ||||
|  | ||||
|     typedef typename Base::Scalar Scalar; | ||||
|     typedef typename Base::PacketScalar PacketScalar; | ||||
|     typedef typename Base::Index Index; | ||||
|     typedef typename Base::PointerType PointerType; | ||||
|  | ||||
|     using Base::derived; | ||||
|     using Base::rows; | ||||
|     using Base::cols; | ||||
|     using Base::size; | ||||
|     using Base::coeff; | ||||
|     using Base::coeffRef; | ||||
|  | ||||
|     using Base::innerStride; | ||||
|     using Base::outerStride; | ||||
|     using Base::rowStride; | ||||
|     using Base::colStride; | ||||
|  | ||||
|     typedef typename internal::conditional< | ||||
|                     internal::is_lvalue<Derived>::value, | ||||
|                     Scalar, | ||||
|                     const Scalar | ||||
|                   >::type ScalarWithConstIfNotLvalue; | ||||
|  | ||||
|     inline const Scalar* data() const { return this->m_data; } | ||||
|     inline ScalarWithConstIfNotLvalue* data() { return this->m_data; } // no const-cast here so non-const-correct code will give a compile error | ||||
|  | ||||
|     inline ScalarWithConstIfNotLvalue& coeffRef(Index row, Index col) | ||||
|     { | ||||
|       return this->m_data[col * colStride() + row * rowStride()]; | ||||
|     } | ||||
|  | ||||
|     inline ScalarWithConstIfNotLvalue& coeffRef(Index index) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) | ||||
|       return this->m_data[index * innerStride()]; | ||||
|     } | ||||
|  | ||||
|     template<int StoreMode> | ||||
|     inline void writePacket(Index row, Index col, const PacketScalar& x) | ||||
|     { | ||||
|       internal::pstoret<Scalar, PacketScalar, StoreMode> | ||||
|                (this->m_data + (col * colStride() + row * rowStride()), x); | ||||
|     } | ||||
|  | ||||
|     template<int StoreMode> | ||||
|     inline void writePacket(Index index, const PacketScalar& x) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) | ||||
|       internal::pstoret<Scalar, PacketScalar, StoreMode> | ||||
|                 (this->m_data + index * innerStride(), x); | ||||
|     } | ||||
|  | ||||
|     explicit inline MapBase(PointerType data) : Base(data) {} | ||||
|     inline MapBase(PointerType data, Index size) : Base(data, size) {} | ||||
|     inline MapBase(PointerType data, Index rows, Index cols) : Base(data, rows, cols) {} | ||||
|  | ||||
|     Derived& operator=(const MapBase& other) | ||||
|     { | ||||
|       Base::Base::operator=(other); | ||||
|       return derived(); | ||||
|     } | ||||
|  | ||||
|     using Base::Base::operator=; | ||||
| }; | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_MAPBASE_H | ||||
							
								
								
									
										842
									
								
								latan/Eigen/src/Core/MathFunctions.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										842
									
								
								latan/Eigen/src/Core/MathFunctions.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,842 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_MATHFUNCTIONS_H | ||||
| #define EIGEN_MATHFUNCTIONS_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| /** \internal \struct global_math_functions_filtering_base | ||||
|   * | ||||
|   * What it does: | ||||
|   * Defines a typedef 'type' as follows: | ||||
|   * - if type T has a member typedef Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl, then | ||||
|   *   global_math_functions_filtering_base<T>::type is a typedef for it. | ||||
|   * - otherwise, global_math_functions_filtering_base<T>::type is a typedef for T. | ||||
|   * | ||||
|   * How it's used: | ||||
|   * To allow to defined the global math functions (like sin...) in certain cases, like the Array expressions. | ||||
|   * When you do sin(array1+array2), the object array1+array2 has a complicated expression type, all what you want to know | ||||
|   * is that it inherits ArrayBase. So we implement a partial specialization of sin_impl for ArrayBase<Derived>. | ||||
|   * So we must make sure to use sin_impl<ArrayBase<Derived> > and not sin_impl<Derived>, otherwise our partial specialization | ||||
|   * won't be used. How does sin know that? That's exactly what global_math_functions_filtering_base tells it. | ||||
|   * | ||||
|   * How it's implemented: | ||||
|   * SFINAE in the style of enable_if. Highly susceptible of breaking compilers. With GCC, it sure does work, but if you replace | ||||
|   * the typename dummy by an integer template parameter, it doesn't work anymore! | ||||
|   */ | ||||
|  | ||||
| template<typename T, typename dummy = void> | ||||
| struct global_math_functions_filtering_base | ||||
| { | ||||
|   typedef T type; | ||||
| }; | ||||
|  | ||||
| template<typename T> struct always_void { typedef void type; }; | ||||
|  | ||||
| template<typename T> | ||||
| struct global_math_functions_filtering_base | ||||
|   <T, | ||||
|    typename always_void<typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl>::type | ||||
|   > | ||||
| { | ||||
|   typedef typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl type; | ||||
| }; | ||||
|  | ||||
| #define EIGEN_MATHFUNC_IMPL(func, scalar) func##_impl<typename global_math_functions_filtering_base<scalar>::type> | ||||
| #define EIGEN_MATHFUNC_RETVAL(func, scalar) typename func##_retval<typename global_math_functions_filtering_base<scalar>::type>::type | ||||
|  | ||||
|  | ||||
| /**************************************************************************** | ||||
| * Implementation of real                                                 * | ||||
| ****************************************************************************/ | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct real_impl | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|   static inline RealScalar run(const Scalar& x) | ||||
|   { | ||||
|     return x; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename RealScalar> | ||||
| struct real_impl<std::complex<RealScalar> > | ||||
| { | ||||
|   static inline RealScalar run(const std::complex<RealScalar>& x) | ||||
|   { | ||||
|     using std::real; | ||||
|     return real(x); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct real_retval | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real type; | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x) | ||||
| { | ||||
|   return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x); | ||||
| } | ||||
|  | ||||
| /**************************************************************************** | ||||
| * Implementation of imag                                                 * | ||||
| ****************************************************************************/ | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct imag_impl | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|   static inline RealScalar run(const Scalar&) | ||||
|   { | ||||
|     return RealScalar(0); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename RealScalar> | ||||
| struct imag_impl<std::complex<RealScalar> > | ||||
| { | ||||
|   static inline RealScalar run(const std::complex<RealScalar>& x) | ||||
|   { | ||||
|     using std::imag; | ||||
|     return imag(x); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct imag_retval | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real type; | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x) | ||||
| { | ||||
|   return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x); | ||||
| } | ||||
|  | ||||
| /**************************************************************************** | ||||
| * Implementation of real_ref                                             * | ||||
| ****************************************************************************/ | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct real_ref_impl | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|   static inline RealScalar& run(Scalar& x) | ||||
|   { | ||||
|     return reinterpret_cast<RealScalar*>(&x)[0]; | ||||
|   } | ||||
|   static inline const RealScalar& run(const Scalar& x) | ||||
|   { | ||||
|     return reinterpret_cast<const RealScalar*>(&x)[0]; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct real_ref_retval | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real & type; | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| inline typename add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(const Scalar& x) | ||||
| { | ||||
|   return real_ref_impl<Scalar>::run(x); | ||||
| } | ||||
|  | ||||
| template<typename Scalar> | ||||
| inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x) | ||||
| { | ||||
|   return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x); | ||||
| } | ||||
|  | ||||
| /**************************************************************************** | ||||
| * Implementation of imag_ref                                             * | ||||
| ****************************************************************************/ | ||||
|  | ||||
| template<typename Scalar, bool IsComplex> | ||||
| struct imag_ref_default_impl | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|   static inline RealScalar& run(Scalar& x) | ||||
|   { | ||||
|     return reinterpret_cast<RealScalar*>(&x)[1]; | ||||
|   } | ||||
|   static inline const RealScalar& run(const Scalar& x) | ||||
|   { | ||||
|     return reinterpret_cast<RealScalar*>(&x)[1]; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct imag_ref_default_impl<Scalar, false> | ||||
| { | ||||
|   static inline Scalar run(Scalar&) | ||||
|   { | ||||
|     return Scalar(0); | ||||
|   } | ||||
|   static inline const Scalar run(const Scalar&) | ||||
|   { | ||||
|     return Scalar(0); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct imag_ref_impl : imag_ref_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {}; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct imag_ref_retval | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real & type; | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| inline typename add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x) | ||||
| { | ||||
|   return imag_ref_impl<Scalar>::run(x); | ||||
| } | ||||
|  | ||||
| template<typename Scalar> | ||||
| inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x) | ||||
| { | ||||
|   return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x); | ||||
| } | ||||
|  | ||||
| /**************************************************************************** | ||||
| * Implementation of conj                                                 * | ||||
| ****************************************************************************/ | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct conj_impl | ||||
| { | ||||
|   static inline Scalar run(const Scalar& x) | ||||
|   { | ||||
|     return x; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename RealScalar> | ||||
| struct conj_impl<std::complex<RealScalar> > | ||||
| { | ||||
|   static inline std::complex<RealScalar> run(const std::complex<RealScalar>& x) | ||||
|   { | ||||
|     using std::conj; | ||||
|     return conj(x); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct conj_retval | ||||
| { | ||||
|   typedef Scalar type; | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x) | ||||
| { | ||||
|   return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x); | ||||
| } | ||||
|  | ||||
| /**************************************************************************** | ||||
| * Implementation of abs                                                  * | ||||
| ****************************************************************************/ | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct abs_impl | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|   static inline RealScalar run(const Scalar& x) | ||||
|   { | ||||
|     using std::abs; | ||||
|     return abs(x); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct abs_retval | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real type; | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| inline EIGEN_MATHFUNC_RETVAL(abs, Scalar) abs(const Scalar& x) | ||||
| { | ||||
|   return EIGEN_MATHFUNC_IMPL(abs, Scalar)::run(x); | ||||
| } | ||||
|  | ||||
| /**************************************************************************** | ||||
| * Implementation of abs2                                                 * | ||||
| ****************************************************************************/ | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct abs2_impl | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|   static inline RealScalar run(const Scalar& x) | ||||
|   { | ||||
|     return x*x; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename RealScalar> | ||||
| struct abs2_impl<std::complex<RealScalar> > | ||||
| { | ||||
|   static inline RealScalar run(const std::complex<RealScalar>& x) | ||||
|   { | ||||
|     return real(x)*real(x) + imag(x)*imag(x); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct abs2_retval | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real type; | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x) | ||||
| { | ||||
|   return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x); | ||||
| } | ||||
|  | ||||
| /**************************************************************************** | ||||
| * Implementation of norm1                                                * | ||||
| ****************************************************************************/ | ||||
|  | ||||
| template<typename Scalar, bool IsComplex> | ||||
| struct norm1_default_impl | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|   static inline RealScalar run(const Scalar& x) | ||||
|   { | ||||
|     return abs(real(x)) + abs(imag(x)); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct norm1_default_impl<Scalar, false> | ||||
| { | ||||
|   static inline Scalar run(const Scalar& x) | ||||
|   { | ||||
|     return abs(x); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct norm1_impl : norm1_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {}; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct norm1_retval | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real type; | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x) | ||||
| { | ||||
|   return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x); | ||||
| } | ||||
|  | ||||
| /**************************************************************************** | ||||
| * Implementation of hypot                                                * | ||||
| ****************************************************************************/ | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct hypot_impl | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|   static inline RealScalar run(const Scalar& x, const Scalar& y) | ||||
|   { | ||||
|     using std::max; | ||||
|     using std::min; | ||||
|     RealScalar _x = abs(x); | ||||
|     RealScalar _y = abs(y); | ||||
|     RealScalar p = (max)(_x, _y); | ||||
|     RealScalar q = (min)(_x, _y); | ||||
|     RealScalar qp = q/p; | ||||
|     return p * sqrt(RealScalar(1) + qp*qp); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct hypot_retval | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real type; | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y) | ||||
| { | ||||
|   return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y); | ||||
| } | ||||
|  | ||||
| /**************************************************************************** | ||||
| * Implementation of cast                                                 * | ||||
| ****************************************************************************/ | ||||
|  | ||||
| template<typename OldType, typename NewType> | ||||
| struct cast_impl | ||||
| { | ||||
|   static inline NewType run(const OldType& x) | ||||
|   { | ||||
|     return static_cast<NewType>(x); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // here, for once, we're plainly returning NewType: we don't want cast to do weird things. | ||||
|  | ||||
| template<typename OldType, typename NewType> | ||||
| inline NewType cast(const OldType& x) | ||||
| { | ||||
|   return cast_impl<OldType, NewType>::run(x); | ||||
| } | ||||
|  | ||||
| /**************************************************************************** | ||||
| * Implementation of sqrt                                                 * | ||||
| ****************************************************************************/ | ||||
|  | ||||
| template<typename Scalar, bool IsInteger> | ||||
| struct sqrt_default_impl | ||||
| { | ||||
|   static inline Scalar run(const Scalar& x) | ||||
|   { | ||||
|     using std::sqrt; | ||||
|     return sqrt(x); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct sqrt_default_impl<Scalar, true> | ||||
| { | ||||
|   static inline Scalar run(const Scalar&) | ||||
|   { | ||||
| #ifdef EIGEN2_SUPPORT | ||||
|     eigen_assert(!NumTraits<Scalar>::IsInteger); | ||||
| #else | ||||
|     EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar) | ||||
| #endif | ||||
|     return Scalar(0); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct sqrt_impl : sqrt_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {}; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct sqrt_retval | ||||
| { | ||||
|   typedef Scalar type; | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| inline EIGEN_MATHFUNC_RETVAL(sqrt, Scalar) sqrt(const Scalar& x) | ||||
| { | ||||
|   return EIGEN_MATHFUNC_IMPL(sqrt, Scalar)::run(x); | ||||
| } | ||||
|  | ||||
| /**************************************************************************** | ||||
| * Implementation of standard unary real functions (exp, log, sin, cos, ...  * | ||||
| ****************************************************************************/ | ||||
|  | ||||
| // This macro instanciate all the necessary template mechanism which is common to all unary real functions. | ||||
| #define EIGEN_MATHFUNC_STANDARD_REAL_UNARY(NAME) \ | ||||
|   template<typename Scalar, bool IsInteger> struct NAME##_default_impl {            \ | ||||
|     static inline Scalar run(const Scalar& x) { using std::NAME; return NAME(x); }  \ | ||||
|   };                                                                                \ | ||||
|   template<typename Scalar> struct NAME##_default_impl<Scalar, true> {              \ | ||||
|     static inline Scalar run(const Scalar&) {                                       \ | ||||
|       EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)                                       \ | ||||
|       return Scalar(0);                                                             \ | ||||
|     }                                                                               \ | ||||
|   };                                                                                \ | ||||
|   template<typename Scalar> struct NAME##_impl                                      \ | ||||
|     : NAME##_default_impl<Scalar, NumTraits<Scalar>::IsInteger>                     \ | ||||
|   {};                                                                               \ | ||||
|   template<typename Scalar> struct NAME##_retval { typedef Scalar type; };          \ | ||||
|   template<typename Scalar>                                                         \ | ||||
|   inline EIGEN_MATHFUNC_RETVAL(NAME, Scalar) NAME(const Scalar& x) {                \ | ||||
|     return EIGEN_MATHFUNC_IMPL(NAME, Scalar)::run(x);                               \ | ||||
|   } | ||||
|  | ||||
| EIGEN_MATHFUNC_STANDARD_REAL_UNARY(exp) | ||||
| EIGEN_MATHFUNC_STANDARD_REAL_UNARY(log) | ||||
| EIGEN_MATHFUNC_STANDARD_REAL_UNARY(sin) | ||||
| EIGEN_MATHFUNC_STANDARD_REAL_UNARY(cos) | ||||
| EIGEN_MATHFUNC_STANDARD_REAL_UNARY(tan) | ||||
| EIGEN_MATHFUNC_STANDARD_REAL_UNARY(asin) | ||||
| EIGEN_MATHFUNC_STANDARD_REAL_UNARY(acos) | ||||
|  | ||||
| /**************************************************************************** | ||||
| * Implementation of atan2                                                * | ||||
| ****************************************************************************/ | ||||
|  | ||||
| template<typename Scalar, bool IsInteger> | ||||
| struct atan2_default_impl | ||||
| { | ||||
|   typedef Scalar retval; | ||||
|   static inline Scalar run(const Scalar& x, const Scalar& y) | ||||
|   { | ||||
|     using std::atan2; | ||||
|     return atan2(x, y); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct atan2_default_impl<Scalar, true> | ||||
| { | ||||
|   static inline Scalar run(const Scalar&, const Scalar&) | ||||
|   { | ||||
|     EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar) | ||||
|     return Scalar(0); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct atan2_impl : atan2_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {}; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct atan2_retval | ||||
| { | ||||
|   typedef Scalar type; | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| inline EIGEN_MATHFUNC_RETVAL(atan2, Scalar) atan2(const Scalar& x, const Scalar& y) | ||||
| { | ||||
|   return EIGEN_MATHFUNC_IMPL(atan2, Scalar)::run(x, y); | ||||
| } | ||||
|  | ||||
| /**************************************************************************** | ||||
| * Implementation of pow                                                  * | ||||
| ****************************************************************************/ | ||||
|  | ||||
| template<typename Scalar, bool IsInteger> | ||||
| struct pow_default_impl | ||||
| { | ||||
|   typedef Scalar retval; | ||||
|   static inline Scalar run(const Scalar& x, const Scalar& y) | ||||
|   { | ||||
|     using std::pow; | ||||
|     return pow(x, y); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct pow_default_impl<Scalar, true> | ||||
| { | ||||
|   static inline Scalar run(Scalar x, Scalar y) | ||||
|   { | ||||
|     Scalar res(1); | ||||
|     eigen_assert(!NumTraits<Scalar>::IsSigned || y >= 0); | ||||
|     if(y & 1) res *= x; | ||||
|     y >>= 1; | ||||
|     while(y) | ||||
|     { | ||||
|       x *= x; | ||||
|       if(y&1) res *= x; | ||||
|       y >>= 1; | ||||
|     } | ||||
|     return res; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct pow_impl : pow_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {}; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct pow_retval | ||||
| { | ||||
|   typedef Scalar type; | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y) | ||||
| { | ||||
|   return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y); | ||||
| } | ||||
|  | ||||
| /**************************************************************************** | ||||
| * Implementation of random                                               * | ||||
| ****************************************************************************/ | ||||
|  | ||||
| template<typename Scalar, | ||||
|          bool IsComplex, | ||||
|          bool IsInteger> | ||||
| struct random_default_impl {}; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct random_impl : random_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {}; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct random_retval | ||||
| { | ||||
|   typedef Scalar type; | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y); | ||||
| template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(); | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct random_default_impl<Scalar, false, false> | ||||
| { | ||||
|   static inline Scalar run(const Scalar& x, const Scalar& y) | ||||
|   { | ||||
|     return x + (y-x) * Scalar(std::rand()) / Scalar(RAND_MAX); | ||||
|   } | ||||
|   static inline Scalar run() | ||||
|   { | ||||
|     return run(Scalar(NumTraits<Scalar>::IsSigned ? -1 : 0), Scalar(1)); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| enum { | ||||
|   floor_log2_terminate, | ||||
|   floor_log2_move_up, | ||||
|   floor_log2_move_down, | ||||
|   floor_log2_bogus | ||||
| }; | ||||
|  | ||||
| template<unsigned int n, int lower, int upper> struct floor_log2_selector | ||||
| { | ||||
|   enum { middle = (lower + upper) / 2, | ||||
|          value = (upper <= lower + 1) ? int(floor_log2_terminate) | ||||
|                : (n < (1 << middle)) ? int(floor_log2_move_down) | ||||
|                : (n==0) ? int(floor_log2_bogus) | ||||
|                : int(floor_log2_move_up) | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| template<unsigned int n, | ||||
|          int lower = 0, | ||||
|          int upper = sizeof(unsigned int) * CHAR_BIT - 1, | ||||
|          int selector = floor_log2_selector<n, lower, upper>::value> | ||||
| struct floor_log2 {}; | ||||
|  | ||||
| template<unsigned int n, int lower, int upper> | ||||
| struct floor_log2<n, lower, upper, floor_log2_move_down> | ||||
| { | ||||
|   enum { value = floor_log2<n, lower, floor_log2_selector<n, lower, upper>::middle>::value }; | ||||
| }; | ||||
|  | ||||
| template<unsigned int n, int lower, int upper> | ||||
| struct floor_log2<n, lower, upper, floor_log2_move_up> | ||||
| { | ||||
|   enum { value = floor_log2<n, floor_log2_selector<n, lower, upper>::middle, upper>::value }; | ||||
| }; | ||||
|  | ||||
| template<unsigned int n, int lower, int upper> | ||||
| struct floor_log2<n, lower, upper, floor_log2_terminate> | ||||
| { | ||||
|   enum { value = (n >= ((unsigned int)(1) << (lower+1))) ? lower+1 : lower }; | ||||
| }; | ||||
|  | ||||
| template<unsigned int n, int lower, int upper> | ||||
| struct floor_log2<n, lower, upper, floor_log2_bogus> | ||||
| { | ||||
|   // no value, error at compile time | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct random_default_impl<Scalar, false, true> | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::NonInteger NonInteger; | ||||
|  | ||||
|   static inline Scalar run(const Scalar& x, const Scalar& y) | ||||
|   { | ||||
|     return x + Scalar((NonInteger(y)-x+1) * std::rand() / (RAND_MAX + NonInteger(1))); | ||||
|   } | ||||
|  | ||||
|   static inline Scalar run() | ||||
|   { | ||||
| #ifdef EIGEN_MAKING_DOCS | ||||
|     return run(Scalar(NumTraits<Scalar>::IsSigned ? -10 : 0), Scalar(10)); | ||||
| #else | ||||
|     enum { rand_bits = floor_log2<(unsigned int)(RAND_MAX)+1>::value, | ||||
|            scalar_bits = sizeof(Scalar) * CHAR_BIT, | ||||
|            shift = EIGEN_PLAIN_ENUM_MAX(0, int(rand_bits) - int(scalar_bits)) | ||||
|     }; | ||||
|     Scalar x = Scalar(std::rand() >> shift); | ||||
|     Scalar offset = NumTraits<Scalar>::IsSigned ? Scalar(1 << (rand_bits-1)) : Scalar(0); | ||||
|     return x - offset; | ||||
| #endif | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct random_default_impl<Scalar, true, false> | ||||
| { | ||||
|   static inline Scalar run(const Scalar& x, const Scalar& y) | ||||
|   { | ||||
|     return Scalar(random(real(x), real(y)), | ||||
|                   random(imag(x), imag(y))); | ||||
|   } | ||||
|   static inline Scalar run() | ||||
|   { | ||||
|     typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|     return Scalar(random<RealScalar>(), random<RealScalar>()); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y) | ||||
| { | ||||
|   return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(x, y); | ||||
| } | ||||
|  | ||||
| template<typename Scalar> | ||||
| inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random() | ||||
| { | ||||
|   return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(); | ||||
| } | ||||
|  | ||||
| /**************************************************************************** | ||||
| * Implementation of fuzzy comparisons                                       * | ||||
| ****************************************************************************/ | ||||
|  | ||||
| template<typename Scalar, | ||||
|          bool IsComplex, | ||||
|          bool IsInteger> | ||||
| struct scalar_fuzzy_default_impl {}; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct scalar_fuzzy_default_impl<Scalar, false, false> | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|   template<typename OtherScalar> | ||||
|   static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec) | ||||
|   { | ||||
|     return abs(x) <= abs(y) * prec; | ||||
|   } | ||||
|   static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec) | ||||
|   { | ||||
|     using std::min; | ||||
|     return abs(x - y) <= (min)(abs(x), abs(y)) * prec; | ||||
|   } | ||||
|   static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar& prec) | ||||
|   { | ||||
|     return x <= y || isApprox(x, y, prec); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct scalar_fuzzy_default_impl<Scalar, false, true> | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|   template<typename OtherScalar> | ||||
|   static inline bool isMuchSmallerThan(const Scalar& x, const Scalar&, const RealScalar&) | ||||
|   { | ||||
|     return x == Scalar(0); | ||||
|   } | ||||
|   static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar&) | ||||
|   { | ||||
|     return x == y; | ||||
|   } | ||||
|   static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar&) | ||||
|   { | ||||
|     return x <= y; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct scalar_fuzzy_default_impl<Scalar, true, false> | ||||
| { | ||||
|   typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|   template<typename OtherScalar> | ||||
|   static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec) | ||||
|   { | ||||
|     return abs2(x) <= abs2(y) * prec * prec; | ||||
|   } | ||||
|   static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec) | ||||
|   { | ||||
|     using std::min; | ||||
|     return abs2(x - y) <= (min)(abs2(x), abs2(y)) * prec * prec; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {}; | ||||
|  | ||||
| template<typename Scalar, typename OtherScalar> | ||||
| inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, | ||||
|                                    typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) | ||||
| { | ||||
|   return scalar_fuzzy_impl<Scalar>::template isMuchSmallerThan<OtherScalar>(x, y, precision); | ||||
| } | ||||
|  | ||||
| template<typename Scalar> | ||||
| inline bool isApprox(const Scalar& x, const Scalar& y, | ||||
|                           typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) | ||||
| { | ||||
|   return scalar_fuzzy_impl<Scalar>::isApprox(x, y, precision); | ||||
| } | ||||
|  | ||||
| template<typename Scalar> | ||||
| inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, | ||||
|                                     typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) | ||||
| { | ||||
|   return scalar_fuzzy_impl<Scalar>::isApproxOrLessThan(x, y, precision); | ||||
| } | ||||
|  | ||||
| /****************************************** | ||||
| ***  The special case of the  bool type *** | ||||
| ******************************************/ | ||||
|  | ||||
| template<> struct random_impl<bool> | ||||
| { | ||||
|   static inline bool run() | ||||
|   { | ||||
|     return random<int>(0,1)==0 ? false : true; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct scalar_fuzzy_impl<bool> | ||||
| { | ||||
|   typedef bool RealScalar; | ||||
|    | ||||
|   template<typename OtherScalar> | ||||
|   static inline bool isMuchSmallerThan(const bool& x, const bool&, const bool&) | ||||
|   { | ||||
|     return !x; | ||||
|   } | ||||
|    | ||||
|   static inline bool isApprox(bool x, bool y, bool) | ||||
|   { | ||||
|     return x == y; | ||||
|   } | ||||
|  | ||||
|   static inline bool isApproxOrLessThan(const bool& x, const bool& y, const bool&) | ||||
|   { | ||||
|     return (!x) || y; | ||||
|   } | ||||
|    | ||||
| }; | ||||
|  | ||||
| /**************************************************************************** | ||||
| * Special functions                                                          * | ||||
| ****************************************************************************/ | ||||
|  | ||||
| // std::isfinite is non standard, so let's define our own version, | ||||
| // even though it is not very efficient. | ||||
| template<typename T> bool (isfinite)(const T& x) | ||||
| { | ||||
|   return x<NumTraits<T>::highest() && x>NumTraits<T>::lowest(); | ||||
| } | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_MATHFUNCTIONS_H | ||||
							
								
								
									
										405
									
								
								latan/Eigen/src/Core/Matrix.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										405
									
								
								latan/Eigen/src/Core/Matrix.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,405 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_MATRIX_H | ||||
| #define EIGEN_MATRIX_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| /** \class Matrix | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief The matrix class, also used for vectors and row-vectors | ||||
|   * | ||||
|   * The %Matrix class is the work-horse for all \em dense (\ref dense "note") matrices and vectors within Eigen. | ||||
|   * Vectors are matrices with one column, and row-vectors are matrices with one row. | ||||
|   * | ||||
|   * The %Matrix class encompasses \em both fixed-size and dynamic-size objects (\ref fixedsize "note"). | ||||
|   * | ||||
|   * The first three template parameters are required: | ||||
|   * \tparam _Scalar \anchor matrix_tparam_scalar Numeric type, e.g. float, double, int or std::complex<float>. | ||||
|   *                 User defined sclar types are supported as well (see \ref user_defined_scalars "here"). | ||||
|   * \tparam _Rows Number of rows, or \b Dynamic | ||||
|   * \tparam _Cols Number of columns, or \b Dynamic | ||||
|   * | ||||
|   * The remaining template parameters are optional -- in most cases you don't have to worry about them. | ||||
|   * \tparam _Options \anchor matrix_tparam_options A combination of either \b #RowMajor or \b #ColMajor, and of either | ||||
|   *                 \b #AutoAlign or \b #DontAlign. | ||||
|   *                 The former controls \ref TopicStorageOrders "storage order", and defaults to column-major. The latter controls alignment, which is required | ||||
|   *                 for vectorization. It defaults to aligning matrices except for fixed sizes that aren't a multiple of the packet size. | ||||
|   * \tparam _MaxRows Maximum number of rows. Defaults to \a _Rows (\ref maxrows "note"). | ||||
|   * \tparam _MaxCols Maximum number of columns. Defaults to \a _Cols (\ref maxrows "note"). | ||||
|   * | ||||
|   * Eigen provides a number of typedefs covering the usual cases. Here are some examples: | ||||
|   * | ||||
|   * \li \c Matrix2d is a 2x2 square matrix of doubles (\c Matrix<double, 2, 2>) | ||||
|   * \li \c Vector4f is a vector of 4 floats (\c Matrix<float, 4, 1>) | ||||
|   * \li \c RowVector3i is a row-vector of 3 ints (\c Matrix<int, 1, 3>) | ||||
|   * | ||||
|   * \li \c MatrixXf is a dynamic-size matrix of floats (\c Matrix<float, Dynamic, Dynamic>) | ||||
|   * \li \c VectorXf is a dynamic-size vector of floats (\c Matrix<float, Dynamic, 1>) | ||||
|   * | ||||
|   * \li \c Matrix2Xf is a partially fixed-size (dynamic-size) matrix of floats (\c Matrix<float, 2, Dynamic>) | ||||
|   * \li \c MatrixX3d is a partially dynamic-size (fixed-size) matrix of double (\c Matrix<double, Dynamic, 3>) | ||||
|   * | ||||
|   * See \link matrixtypedefs this page \endlink for a complete list of predefined \em %Matrix and \em Vector typedefs. | ||||
|   * | ||||
|   * You can access elements of vectors and matrices using normal subscripting: | ||||
|   * | ||||
|   * \code | ||||
|   * Eigen::VectorXd v(10); | ||||
|   * v[0] = 0.1; | ||||
|   * v[1] = 0.2; | ||||
|   * v(0) = 0.3; | ||||
|   * v(1) = 0.4; | ||||
|   * | ||||
|   * Eigen::MatrixXi m(10, 10); | ||||
|   * m(0, 1) = 1; | ||||
|   * m(0, 2) = 2; | ||||
|   * m(0, 3) = 3; | ||||
|   * \endcode | ||||
|   * | ||||
|   * This class can be extended with the help of the plugin mechanism described on the page | ||||
|   * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_MATRIX_PLUGIN. | ||||
|   * | ||||
|   * <i><b>Some notes:</b></i> | ||||
|   * | ||||
|   * <dl> | ||||
|   * <dt><b>\anchor dense Dense versus sparse:</b></dt> | ||||
|   * <dd>This %Matrix class handles dense, not sparse matrices and vectors. For sparse matrices and vectors, see the Sparse module. | ||||
|   * | ||||
|   * Dense matrices and vectors are plain usual arrays of coefficients. All the coefficients are stored, in an ordinary contiguous array. | ||||
|   * This is unlike Sparse matrices and vectors where the coefficients are stored as a list of nonzero coefficients.</dd> | ||||
|   * | ||||
|   * <dt><b>\anchor fixedsize Fixed-size versus dynamic-size:</b></dt> | ||||
|   * <dd>Fixed-size means that the numbers of rows and columns are known are compile-time. In this case, Eigen allocates the array | ||||
|   * of coefficients as a fixed-size array, as a class member. This makes sense for very small matrices, typically up to 4x4, sometimes up | ||||
|   * to 16x16. Larger matrices should be declared as dynamic-size even if one happens to know their size at compile-time. | ||||
|   * | ||||
|   * Dynamic-size means that the numbers of rows or columns are not necessarily known at compile-time. In this case they are runtime | ||||
|   * variables, and the array of coefficients is allocated dynamically on the heap. | ||||
|   * | ||||
|   * Note that \em dense matrices, be they Fixed-size or Dynamic-size, <em>do not</em> expand dynamically in the sense of a std::map. | ||||
|   * If you want this behavior, see the Sparse module.</dd> | ||||
|   * | ||||
|   * <dt><b>\anchor maxrows _MaxRows and _MaxCols:</b></dt> | ||||
|   * <dd>In most cases, one just leaves these parameters to the default values. | ||||
|   * These parameters mean the maximum size of rows and columns that the matrix may have. They are useful in cases | ||||
|   * when the exact numbers of rows and columns are not known are compile-time, but it is known at compile-time that they cannot | ||||
|   * exceed a certain value. This happens when taking dynamic-size blocks inside fixed-size matrices: in this case _MaxRows and _MaxCols | ||||
|   * are the dimensions of the original matrix, while _Rows and _Cols are Dynamic.</dd> | ||||
|   * </dl> | ||||
|   * | ||||
|   * \see MatrixBase for the majority of the API methods for matrices, \ref TopicClassHierarchy,  | ||||
|   * \ref TopicStorageOrders  | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> | ||||
| struct traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > | ||||
| { | ||||
|   typedef _Scalar Scalar; | ||||
|   typedef Dense StorageKind; | ||||
|   typedef DenseIndex Index; | ||||
|   typedef MatrixXpr XprKind; | ||||
|   enum { | ||||
|     RowsAtCompileTime = _Rows, | ||||
|     ColsAtCompileTime = _Cols, | ||||
|     MaxRowsAtCompileTime = _MaxRows, | ||||
|     MaxColsAtCompileTime = _MaxCols, | ||||
|     Flags = compute_matrix_flags<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ret, | ||||
|     CoeffReadCost = NumTraits<Scalar>::ReadCost, | ||||
|     Options = _Options, | ||||
|     InnerStrideAtCompileTime = 1, | ||||
|     OuterStrideAtCompileTime = (Options&RowMajor) ? ColsAtCompileTime : RowsAtCompileTime | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> | ||||
| class Matrix | ||||
|   : public PlainObjectBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     /** \brief Base class typedef. | ||||
|       * \sa PlainObjectBase | ||||
|       */ | ||||
|     typedef PlainObjectBase<Matrix> Base; | ||||
|  | ||||
|     enum { Options = _Options }; | ||||
|  | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(Matrix) | ||||
|  | ||||
|     typedef typename Base::PlainObject PlainObject; | ||||
|  | ||||
|     using Base::base; | ||||
|     using Base::coeffRef; | ||||
|  | ||||
|     /** | ||||
|       * \brief Assigns matrices to each other. | ||||
|       * | ||||
|       * \note This is a special case of the templated operator=. Its purpose is | ||||
|       * to prevent a default operator= from hiding the templated operator=. | ||||
|       * | ||||
|       * \callgraph | ||||
|       */ | ||||
|     EIGEN_STRONG_INLINE Matrix& operator=(const Matrix& other) | ||||
|     { | ||||
|       return Base::_set(other); | ||||
|     } | ||||
|  | ||||
|     /** \internal | ||||
|       * \brief Copies the value of the expression \a other into \c *this with automatic resizing. | ||||
|       * | ||||
|       * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), | ||||
|       * it will be initialized. | ||||
|       * | ||||
|       * Note that copying a row-vector into a vector (and conversely) is allowed. | ||||
|       * The resizing, if any, is then done in the appropriate way so that row-vectors | ||||
|       * remain row-vectors and vectors remain vectors. | ||||
|       */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE Matrix& operator=(const MatrixBase<OtherDerived>& other) | ||||
|     { | ||||
|       return Base::_set(other); | ||||
|     } | ||||
|  | ||||
|     /* Here, doxygen failed to copy the brief information when using \copydoc */ | ||||
|  | ||||
|     /** | ||||
|       * \brief Copies the generic expression \a other into *this. | ||||
|       * \copydetails DenseBase::operator=(const EigenBase<OtherDerived> &other) | ||||
|       */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE Matrix& operator=(const EigenBase<OtherDerived> &other) | ||||
|     { | ||||
|       return Base::operator=(other); | ||||
|     } | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE Matrix& operator=(const ReturnByValue<OtherDerived>& func) | ||||
|     { | ||||
|       return Base::operator=(func); | ||||
|     } | ||||
|  | ||||
|     /** \brief Default constructor. | ||||
|       * | ||||
|       * For fixed-size matrices, does nothing. | ||||
|       * | ||||
|       * For dynamic-size matrices, creates an empty matrix of size 0. Does not allocate any array. Such a matrix | ||||
|       * is called a null matrix. This constructor is the unique way to create null matrices: resizing | ||||
|       * a matrix to 0 is not supported. | ||||
|       * | ||||
|       * \sa resize(Index,Index) | ||||
|       */ | ||||
|     EIGEN_STRONG_INLINE explicit Matrix() : Base() | ||||
|     { | ||||
|       Base::_check_template_params(); | ||||
|       EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED | ||||
|     } | ||||
|  | ||||
|     // FIXME is it still needed | ||||
|     Matrix(internal::constructor_without_unaligned_array_assert) | ||||
|       : Base(internal::constructor_without_unaligned_array_assert()) | ||||
|     { Base::_check_template_params(); EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED } | ||||
|  | ||||
|     /** \brief Constructs a vector or row-vector with given dimension. \only_for_vectors | ||||
|       * | ||||
|       * Note that this is only useful for dynamic-size vectors. For fixed-size vectors, | ||||
|       * it is redundant to pass the dimension here, so it makes more sense to use the default | ||||
|       * constructor Matrix() instead. | ||||
|       */ | ||||
|     EIGEN_STRONG_INLINE explicit Matrix(Index dim) | ||||
|       : Base(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim) | ||||
|     { | ||||
|       Base::_check_template_params(); | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix) | ||||
|       eigen_assert(dim >= 0); | ||||
|       eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim); | ||||
|       EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED | ||||
|     } | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     template<typename T0, typename T1> | ||||
|     EIGEN_STRONG_INLINE Matrix(const T0& x, const T1& y) | ||||
|     { | ||||
|       Base::_check_template_params(); | ||||
|       Base::template _init2<T0,T1>(x, y); | ||||
|     } | ||||
|     #else | ||||
|     /** \brief Constructs an uninitialized matrix with \a rows rows and \a cols columns. | ||||
|       * | ||||
|       * This is useful for dynamic-size matrices. For fixed-size matrices, | ||||
|       * it is redundant to pass these parameters, so one should use the default constructor | ||||
|       * Matrix() instead. */ | ||||
|     Matrix(Index rows, Index cols); | ||||
|     /** \brief Constructs an initialized 2D vector with given coefficients */ | ||||
|     Matrix(const Scalar& x, const Scalar& y); | ||||
|     #endif | ||||
|  | ||||
|     /** \brief Constructs an initialized 3D vector with given coefficients */ | ||||
|     EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z) | ||||
|     { | ||||
|       Base::_check_template_params(); | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 3) | ||||
|       m_storage.data()[0] = x; | ||||
|       m_storage.data()[1] = y; | ||||
|       m_storage.data()[2] = z; | ||||
|     } | ||||
|     /** \brief Constructs an initialized 4D vector with given coefficients */ | ||||
|     EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w) | ||||
|     { | ||||
|       Base::_check_template_params(); | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 4) | ||||
|       m_storage.data()[0] = x; | ||||
|       m_storage.data()[1] = y; | ||||
|       m_storage.data()[2] = z; | ||||
|       m_storage.data()[3] = w; | ||||
|     } | ||||
|  | ||||
|     explicit Matrix(const Scalar *data); | ||||
|  | ||||
|     /** \brief Constructor copying the value of the expression \a other */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE Matrix(const MatrixBase<OtherDerived>& other) | ||||
|              : Base(other.rows() * other.cols(), other.rows(), other.cols()) | ||||
|     { | ||||
|       // This test resides here, to bring the error messages closer to the user. Normally, these checks | ||||
|       // are performed deeply within the library, thus causing long and scary error traces. | ||||
|       EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value), | ||||
|         YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) | ||||
|  | ||||
|       Base::_check_template_params(); | ||||
|       Base::_set_noalias(other); | ||||
|     } | ||||
|     /** \brief Copy constructor */ | ||||
|     EIGEN_STRONG_INLINE Matrix(const Matrix& other) | ||||
|             : Base(other.rows() * other.cols(), other.rows(), other.cols()) | ||||
|     { | ||||
|       Base::_check_template_params(); | ||||
|       Base::_set_noalias(other); | ||||
|     } | ||||
|     /** \brief Copy constructor with in-place evaluation */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE Matrix(const ReturnByValue<OtherDerived>& other) | ||||
|     { | ||||
|       Base::_check_template_params(); | ||||
|       Base::resize(other.rows(), other.cols()); | ||||
|       other.evalTo(*this); | ||||
|     } | ||||
|  | ||||
|     /** \brief Copy constructor for generic expressions. | ||||
|       * \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) | ||||
|       */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE Matrix(const EigenBase<OtherDerived> &other) | ||||
|       : Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) | ||||
|     { | ||||
|       Base::_check_template_params(); | ||||
|       Base::resize(other.rows(), other.cols()); | ||||
|       // FIXME/CHECK: isn't *this = other.derived() more efficient. it allows to | ||||
|       //              go for pure _set() implementations, right? | ||||
|       *this = other; | ||||
|     } | ||||
|  | ||||
|     /** \internal | ||||
|       * \brief Override MatrixBase::swap() since for dynamic-sized matrices | ||||
|       * of same type it is enough to swap the data pointers. | ||||
|       */ | ||||
|     template<typename OtherDerived> | ||||
|     void swap(MatrixBase<OtherDerived> const & other) | ||||
|     { this->_swap(other.derived()); } | ||||
|  | ||||
|     inline Index innerStride() const { return 1; } | ||||
|     inline Index outerStride() const { return this->innerSize(); } | ||||
|  | ||||
|     /////////// Geometry module /////////// | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     explicit Matrix(const RotationBase<OtherDerived,ColsAtCompileTime>& r); | ||||
|     template<typename OtherDerived> | ||||
|     Matrix& operator=(const RotationBase<OtherDerived,ColsAtCompileTime>& r); | ||||
|  | ||||
|     #ifdef EIGEN2_SUPPORT | ||||
|     template<typename OtherDerived> | ||||
|     explicit Matrix(const eigen2_RotationBase<OtherDerived,ColsAtCompileTime>& r); | ||||
|     template<typename OtherDerived> | ||||
|     Matrix& operator=(const eigen2_RotationBase<OtherDerived,ColsAtCompileTime>& r); | ||||
|     #endif | ||||
|  | ||||
|     // allow to extend Matrix outside Eigen | ||||
|     #ifdef EIGEN_MATRIX_PLUGIN | ||||
|     #include EIGEN_MATRIX_PLUGIN | ||||
|     #endif | ||||
|  | ||||
|   protected: | ||||
|     template <typename Derived, typename OtherDerived, bool IsVector> | ||||
|     friend struct internal::conservative_resize_like_impl; | ||||
|  | ||||
|     using Base::m_storage; | ||||
| }; | ||||
|  | ||||
| /** \defgroup matrixtypedefs Global matrix typedefs | ||||
|   * | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * Eigen defines several typedef shortcuts for most common matrix and vector types. | ||||
|   * | ||||
|   * The general patterns are the following: | ||||
|   * | ||||
|   * \c MatrixSizeType where \c Size can be \c 2,\c 3,\c 4 for fixed size square matrices or \c X for dynamic size, | ||||
|   * and where \c Type can be \c i for integer, \c f for float, \c d for double, \c cf for complex float, \c cd | ||||
|   * for complex double. | ||||
|   * | ||||
|   * For example, \c Matrix3d is a fixed-size 3x3 matrix type of doubles, and \c MatrixXf is a dynamic-size matrix of floats. | ||||
|   * | ||||
|   * There are also \c VectorSizeType and \c RowVectorSizeType which are self-explanatory. For example, \c Vector4cf is | ||||
|   * a fixed-size vector of 4 complex floats. | ||||
|   * | ||||
|   * \sa class Matrix | ||||
|   */ | ||||
|  | ||||
| #define EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix)   \ | ||||
| /** \ingroup matrixtypedefs */                                    \ | ||||
| typedef Matrix<Type, Size, Size> Matrix##SizeSuffix##TypeSuffix;  \ | ||||
| /** \ingroup matrixtypedefs */                                    \ | ||||
| typedef Matrix<Type, Size, 1>    Vector##SizeSuffix##TypeSuffix;  \ | ||||
| /** \ingroup matrixtypedefs */                                    \ | ||||
| typedef Matrix<Type, 1, Size>    RowVector##SizeSuffix##TypeSuffix; | ||||
|  | ||||
| #define EIGEN_MAKE_FIXED_TYPEDEFS(Type, TypeSuffix, Size)         \ | ||||
| /** \ingroup matrixtypedefs */                                    \ | ||||
| typedef Matrix<Type, Size, Dynamic> Matrix##Size##X##TypeSuffix;  \ | ||||
| /** \ingroup matrixtypedefs */                                    \ | ||||
| typedef Matrix<Type, Dynamic, Size> Matrix##X##Size##TypeSuffix; | ||||
|  | ||||
| #define EIGEN_MAKE_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \ | ||||
| EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 2, 2) \ | ||||
| EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 3, 3) \ | ||||
| EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 4, 4) \ | ||||
| EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Dynamic, X) \ | ||||
| EIGEN_MAKE_FIXED_TYPEDEFS(Type, TypeSuffix, 2) \ | ||||
| EIGEN_MAKE_FIXED_TYPEDEFS(Type, TypeSuffix, 3) \ | ||||
| EIGEN_MAKE_FIXED_TYPEDEFS(Type, TypeSuffix, 4) | ||||
|  | ||||
| EIGEN_MAKE_TYPEDEFS_ALL_SIZES(int,                  i) | ||||
| EIGEN_MAKE_TYPEDEFS_ALL_SIZES(float,                f) | ||||
| EIGEN_MAKE_TYPEDEFS_ALL_SIZES(double,               d) | ||||
| EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex<float>,  cf) | ||||
| EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex<double>, cd) | ||||
|  | ||||
| #undef EIGEN_MAKE_TYPEDEFS_ALL_SIZES | ||||
| #undef EIGEN_MAKE_TYPEDEFS | ||||
| #undef EIGEN_MAKE_FIXED_TYPEDEFS | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_MATRIX_H | ||||
							
								
								
									
										511
									
								
								latan/Eigen/src/Core/MatrixBase.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										511
									
								
								latan/Eigen/src/Core/MatrixBase.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,511 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_MATRIXBASE_H | ||||
| #define EIGEN_MATRIXBASE_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| /** \class MatrixBase | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Base class for all dense matrices, vectors, and expressions | ||||
|   * | ||||
|   * This class is the base that is inherited by all matrix, vector, and related expression | ||||
|   * types. Most of the Eigen API is contained in this class, and its base classes. Other important | ||||
|   * classes for the Eigen API are Matrix, and VectorwiseOp. | ||||
|   * | ||||
|   * Note that some methods are defined in other modules such as the \ref LU_Module LU module | ||||
|   * for all functions related to matrix inversions. | ||||
|   * | ||||
|   * \tparam Derived is the derived type, e.g. a matrix type, or an expression, etc. | ||||
|   * | ||||
|   * When writing a function taking Eigen objects as argument, if you want your function | ||||
|   * to take as argument any matrix, vector, or expression, just let it take a | ||||
|   * MatrixBase argument. As an example, here is a function printFirstRow which, given | ||||
|   * a matrix, vector, or expression \a x, prints the first row of \a x. | ||||
|   * | ||||
|   * \code | ||||
|     template<typename Derived> | ||||
|     void printFirstRow(const Eigen::MatrixBase<Derived>& x) | ||||
|     { | ||||
|       cout << x.row(0) << endl; | ||||
|     } | ||||
|   * \endcode | ||||
|   * | ||||
|   * This class can be extended with the help of the plugin mechanism described on the page | ||||
|   * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_MATRIXBASE_PLUGIN. | ||||
|   * | ||||
|   * \sa \ref TopicClassHierarchy | ||||
|   */ | ||||
| template<typename Derived> class MatrixBase | ||||
|   : public DenseBase<Derived> | ||||
| { | ||||
|   public: | ||||
| #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     typedef MatrixBase StorageBaseType; | ||||
|     typedef typename internal::traits<Derived>::StorageKind StorageKind; | ||||
|     typedef typename internal::traits<Derived>::Index Index; | ||||
|     typedef typename internal::traits<Derived>::Scalar Scalar; | ||||
|     typedef typename internal::packet_traits<Scalar>::type PacketScalar; | ||||
|     typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|  | ||||
|     typedef DenseBase<Derived> Base; | ||||
|     using Base::RowsAtCompileTime; | ||||
|     using Base::ColsAtCompileTime; | ||||
|     using Base::SizeAtCompileTime; | ||||
|     using Base::MaxRowsAtCompileTime; | ||||
|     using Base::MaxColsAtCompileTime; | ||||
|     using Base::MaxSizeAtCompileTime; | ||||
|     using Base::IsVectorAtCompileTime; | ||||
|     using Base::Flags; | ||||
|     using Base::CoeffReadCost; | ||||
|  | ||||
|     using Base::derived; | ||||
|     using Base::const_cast_derived; | ||||
|     using Base::rows; | ||||
|     using Base::cols; | ||||
|     using Base::size; | ||||
|     using Base::coeff; | ||||
|     using Base::coeffRef; | ||||
|     using Base::lazyAssign; | ||||
|     using Base::eval; | ||||
|     using Base::operator+=; | ||||
|     using Base::operator-=; | ||||
|     using Base::operator*=; | ||||
|     using Base::operator/=; | ||||
|  | ||||
|     typedef typename Base::CoeffReturnType CoeffReturnType; | ||||
|     typedef typename Base::ConstTransposeReturnType ConstTransposeReturnType; | ||||
|     typedef typename Base::RowXpr RowXpr; | ||||
|     typedef typename Base::ColXpr ColXpr; | ||||
| #endif // not EIGEN_PARSED_BY_DOXYGEN | ||||
|  | ||||
|  | ||||
|  | ||||
| #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /** type of the equivalent square matrix */ | ||||
|     typedef Matrix<Scalar,EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime), | ||||
|                           EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType; | ||||
| #endif // not EIGEN_PARSED_BY_DOXYGEN | ||||
|  | ||||
|     /** \returns the size of the main diagonal, which is min(rows(),cols()). | ||||
|       * \sa rows(), cols(), SizeAtCompileTime. */ | ||||
|     inline Index diagonalSize() const { return (std::min)(rows(),cols()); } | ||||
|  | ||||
|     /** \brief The plain matrix type corresponding to this expression. | ||||
|       * | ||||
|       * This is not necessarily exactly the return type of eval(). In the case of plain matrices, | ||||
|       * the return type of eval() is a const reference to a matrix, not a matrix! It is however guaranteed | ||||
|       * that the return type of eval() is either PlainObject or const PlainObject&. | ||||
|       */ | ||||
|     typedef Matrix<typename internal::traits<Derived>::Scalar, | ||||
|                 internal::traits<Derived>::RowsAtCompileTime, | ||||
|                 internal::traits<Derived>::ColsAtCompileTime, | ||||
|                 AutoAlign | (internal::traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor), | ||||
|                 internal::traits<Derived>::MaxRowsAtCompileTime, | ||||
|                 internal::traits<Derived>::MaxColsAtCompileTime | ||||
|           > PlainObject; | ||||
|  | ||||
| #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /** \internal Represents a matrix with all coefficients equal to one another*/ | ||||
|     typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Derived> ConstantReturnType; | ||||
|     /** \internal the return type of MatrixBase::adjoint() */ | ||||
|     typedef typename internal::conditional<NumTraits<Scalar>::IsComplex, | ||||
|                         CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, ConstTransposeReturnType>, | ||||
|                         ConstTransposeReturnType | ||||
|                      >::type AdjointReturnType; | ||||
|     /** \internal Return type of eigenvalues() */ | ||||
|     typedef Matrix<std::complex<RealScalar>, internal::traits<Derived>::ColsAtCompileTime, 1, ColMajor> EigenvaluesReturnType; | ||||
|     /** \internal the return type of identity */ | ||||
|     typedef CwiseNullaryOp<internal::scalar_identity_op<Scalar>,Derived> IdentityReturnType; | ||||
|     /** \internal the return type of unit vectors */ | ||||
|     typedef Block<const CwiseNullaryOp<internal::scalar_identity_op<Scalar>, SquareMatrixType>, | ||||
|                   internal::traits<Derived>::RowsAtCompileTime, | ||||
|                   internal::traits<Derived>::ColsAtCompileTime> BasisReturnType; | ||||
| #endif // not EIGEN_PARSED_BY_DOXYGEN | ||||
|  | ||||
| #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::MatrixBase | ||||
| #   include "../plugins/CommonCwiseUnaryOps.h" | ||||
| #   include "../plugins/CommonCwiseBinaryOps.h" | ||||
| #   include "../plugins/MatrixCwiseUnaryOps.h" | ||||
| #   include "../plugins/MatrixCwiseBinaryOps.h" | ||||
| #   ifdef EIGEN_MATRIXBASE_PLUGIN | ||||
| #     include EIGEN_MATRIXBASE_PLUGIN | ||||
| #   endif | ||||
| #undef EIGEN_CURRENT_STORAGE_BASE_CLASS | ||||
|  | ||||
|     /** Special case of the template operator=, in order to prevent the compiler | ||||
|       * from generating a default operator= (issue hit with g++ 4.1) | ||||
|       */ | ||||
|     Derived& operator=(const MatrixBase& other); | ||||
|  | ||||
|     // We cannot inherit here via Base::operator= since it is causing | ||||
|     // trouble with MSVC. | ||||
|  | ||||
|     template <typename OtherDerived> | ||||
|     Derived& operator=(const DenseBase<OtherDerived>& other); | ||||
|  | ||||
|     template <typename OtherDerived> | ||||
|     Derived& operator=(const EigenBase<OtherDerived>& other); | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     Derived& operator=(const ReturnByValue<OtherDerived>& other); | ||||
|  | ||||
| #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     template<typename ProductDerived, typename Lhs, typename Rhs> | ||||
|     Derived& lazyAssign(const ProductBase<ProductDerived, Lhs,Rhs>& other); | ||||
| #endif // not EIGEN_PARSED_BY_DOXYGEN | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     Derived& operator+=(const MatrixBase<OtherDerived>& other); | ||||
|     template<typename OtherDerived> | ||||
|     Derived& operator-=(const MatrixBase<OtherDerived>& other); | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     const typename ProductReturnType<Derived,OtherDerived>::Type | ||||
|     operator*(const MatrixBase<OtherDerived> &other) const; | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     const typename LazyProductReturnType<Derived,OtherDerived>::Type | ||||
|     lazyProduct(const MatrixBase<OtherDerived> &other) const; | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     Derived& operator*=(const EigenBase<OtherDerived>& other); | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     void applyOnTheLeft(const EigenBase<OtherDerived>& other); | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     void applyOnTheRight(const EigenBase<OtherDerived>& other); | ||||
|  | ||||
|     template<typename DiagonalDerived> | ||||
|     const DiagonalProduct<Derived, DiagonalDerived, OnTheRight> | ||||
|     operator*(const DiagonalBase<DiagonalDerived> &diagonal) const; | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     typename internal::scalar_product_traits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType | ||||
|     dot(const MatrixBase<OtherDerived>& other) const; | ||||
|  | ||||
|     #ifdef EIGEN2_SUPPORT | ||||
|       template<typename OtherDerived> | ||||
|       Scalar eigen2_dot(const MatrixBase<OtherDerived>& other) const; | ||||
|     #endif | ||||
|  | ||||
|     RealScalar squaredNorm() const; | ||||
|     RealScalar norm() const; | ||||
|     RealScalar stableNorm() const; | ||||
|     RealScalar blueNorm() const; | ||||
|     RealScalar hypotNorm() const; | ||||
|     const PlainObject normalized() const; | ||||
|     void normalize(); | ||||
|  | ||||
|     const AdjointReturnType adjoint() const; | ||||
|     void adjointInPlace(); | ||||
|  | ||||
|     typedef Diagonal<Derived> DiagonalReturnType; | ||||
|     DiagonalReturnType diagonal(); | ||||
|     typedef const Diagonal<const Derived> ConstDiagonalReturnType; | ||||
|     const ConstDiagonalReturnType diagonal() const; | ||||
|  | ||||
|     template<int Index> struct DiagonalIndexReturnType { typedef Diagonal<Derived,Index> Type; }; | ||||
|     template<int Index> struct ConstDiagonalIndexReturnType { typedef const Diagonal<const Derived,Index> Type; }; | ||||
|  | ||||
|     template<int Index> typename DiagonalIndexReturnType<Index>::Type diagonal(); | ||||
|     template<int Index> typename ConstDiagonalIndexReturnType<Index>::Type diagonal() const; | ||||
|  | ||||
|     // Note: The "MatrixBase::" prefixes are added to help MSVC9 to match these declarations with the later implementations. | ||||
|     // On the other hand they confuse MSVC8... | ||||
|     #if (defined _MSC_VER) && (_MSC_VER >= 1500) // 2008 or later | ||||
|     typename MatrixBase::template DiagonalIndexReturnType<Dynamic>::Type diagonal(Index index); | ||||
|     typename MatrixBase::template ConstDiagonalIndexReturnType<Dynamic>::Type diagonal(Index index) const; | ||||
|     #else | ||||
|     typename DiagonalIndexReturnType<Dynamic>::Type diagonal(Index index); | ||||
|     typename ConstDiagonalIndexReturnType<Dynamic>::Type diagonal(Index index) const; | ||||
|     #endif | ||||
|  | ||||
|     #ifdef EIGEN2_SUPPORT | ||||
|     template<unsigned int Mode> typename internal::eigen2_part_return_type<Derived, Mode>::type part(); | ||||
|     template<unsigned int Mode> const typename internal::eigen2_part_return_type<Derived, Mode>::type part() const; | ||||
|      | ||||
|     // huuuge hack. make Eigen2's matrix.part<Diagonal>() work in eigen3. Problem: Diagonal is now a class template instead | ||||
|     // of an integer constant. Solution: overload the part() method template wrt template parameters list. | ||||
|     template<template<typename T, int N> class U> | ||||
|     const DiagonalWrapper<ConstDiagonalReturnType> part() const | ||||
|     { return diagonal().asDiagonal(); } | ||||
|     #endif // EIGEN2_SUPPORT | ||||
|  | ||||
|     template<unsigned int Mode> struct TriangularViewReturnType { typedef TriangularView<Derived, Mode> Type; }; | ||||
|     template<unsigned int Mode> struct ConstTriangularViewReturnType { typedef const TriangularView<const Derived, Mode> Type; }; | ||||
|  | ||||
|     template<unsigned int Mode> typename TriangularViewReturnType<Mode>::Type triangularView(); | ||||
|     template<unsigned int Mode> typename ConstTriangularViewReturnType<Mode>::Type triangularView() const; | ||||
|  | ||||
|     template<unsigned int UpLo> struct SelfAdjointViewReturnType { typedef SelfAdjointView<Derived, UpLo> Type; }; | ||||
|     template<unsigned int UpLo> struct ConstSelfAdjointViewReturnType { typedef const SelfAdjointView<const Derived, UpLo> Type; }; | ||||
|  | ||||
|     template<unsigned int UpLo> typename SelfAdjointViewReturnType<UpLo>::Type selfadjointView(); | ||||
|     template<unsigned int UpLo> typename ConstSelfAdjointViewReturnType<UpLo>::Type selfadjointView() const; | ||||
|  | ||||
|     const SparseView<Derived> sparseView(const Scalar& m_reference = Scalar(0), | ||||
|                                          typename NumTraits<Scalar>::Real m_epsilon = NumTraits<Scalar>::dummy_precision()) const; | ||||
|     static const IdentityReturnType Identity(); | ||||
|     static const IdentityReturnType Identity(Index rows, Index cols); | ||||
|     static const BasisReturnType Unit(Index size, Index i); | ||||
|     static const BasisReturnType Unit(Index i); | ||||
|     static const BasisReturnType UnitX(); | ||||
|     static const BasisReturnType UnitY(); | ||||
|     static const BasisReturnType UnitZ(); | ||||
|     static const BasisReturnType UnitW(); | ||||
|  | ||||
|     const DiagonalWrapper<const Derived> asDiagonal() const; | ||||
|     const PermutationWrapper<const Derived> asPermutation() const; | ||||
|  | ||||
|     Derived& setIdentity(); | ||||
|     Derived& setIdentity(Index rows, Index cols); | ||||
|  | ||||
|     bool isIdentity(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; | ||||
|     bool isDiagonal(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; | ||||
|  | ||||
|     bool isUpperTriangular(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; | ||||
|     bool isLowerTriangular(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     bool isOrthogonal(const MatrixBase<OtherDerived>& other, | ||||
|                       RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; | ||||
|     bool isUnitary(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const; | ||||
|  | ||||
|     /** \returns true if each coefficients of \c *this and \a other are all exactly equal. | ||||
|       * \warning When using floating point scalar values you probably should rather use a | ||||
|       *          fuzzy comparison such as isApprox() | ||||
|       * \sa isApprox(), operator!= */ | ||||
|     template<typename OtherDerived> | ||||
|     inline bool operator==(const MatrixBase<OtherDerived>& other) const | ||||
|     { return cwiseEqual(other).all(); } | ||||
|  | ||||
|     /** \returns true if at least one pair of coefficients of \c *this and \a other are not exactly equal to each other. | ||||
|       * \warning When using floating point scalar values you probably should rather use a | ||||
|       *          fuzzy comparison such as isApprox() | ||||
|       * \sa isApprox(), operator== */ | ||||
|     template<typename OtherDerived> | ||||
|     inline bool operator!=(const MatrixBase<OtherDerived>& other) const | ||||
|     { return cwiseNotEqual(other).any(); } | ||||
|  | ||||
|     NoAlias<Derived,Eigen::MatrixBase > noalias(); | ||||
|  | ||||
|     inline const ForceAlignedAccess<Derived> forceAlignedAccess() const; | ||||
|     inline ForceAlignedAccess<Derived> forceAlignedAccess(); | ||||
|     template<bool Enable> inline typename internal::add_const_on_value_type<typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type>::type forceAlignedAccessIf() const; | ||||
|     template<bool Enable> inline typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf(); | ||||
|  | ||||
|     Scalar trace() const; | ||||
|  | ||||
| /////////// Array module /////////// | ||||
|  | ||||
|     template<int p> RealScalar lpNorm() const; | ||||
|  | ||||
|     MatrixBase<Derived>& matrix() { return *this; } | ||||
|     const MatrixBase<Derived>& matrix() const { return *this; } | ||||
|  | ||||
|     /** \returns an \link ArrayBase Array \endlink expression of this matrix | ||||
|       * \sa ArrayBase::matrix() */ | ||||
|     ArrayWrapper<Derived> array() { return derived(); } | ||||
|     const ArrayWrapper<const Derived> array() const { return derived(); } | ||||
|  | ||||
| /////////// LU module /////////// | ||||
|  | ||||
|     const FullPivLU<PlainObject> fullPivLu() const; | ||||
|     const PartialPivLU<PlainObject> partialPivLu() const; | ||||
|  | ||||
|     #if EIGEN2_SUPPORT_STAGE < STAGE20_RESOLVE_API_CONFLICTS | ||||
|     const LU<PlainObject> lu() const; | ||||
|     #endif | ||||
|  | ||||
|     #ifdef EIGEN2_SUPPORT | ||||
|     const LU<PlainObject> eigen2_lu() const; | ||||
|     #endif | ||||
|  | ||||
|     #if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS | ||||
|     const PartialPivLU<PlainObject> lu() const; | ||||
|     #endif | ||||
|      | ||||
|     #ifdef EIGEN2_SUPPORT | ||||
|     template<typename ResultType> | ||||
|     void computeInverse(MatrixBase<ResultType> *result) const { | ||||
|       *result = this->inverse(); | ||||
|     } | ||||
|     #endif | ||||
|  | ||||
|     const internal::inverse_impl<Derived> inverse() const; | ||||
|     template<typename ResultType> | ||||
|     void computeInverseAndDetWithCheck( | ||||
|       ResultType& inverse, | ||||
|       typename ResultType::Scalar& determinant, | ||||
|       bool& invertible, | ||||
|       const RealScalar& absDeterminantThreshold = NumTraits<Scalar>::dummy_precision() | ||||
|     ) const; | ||||
|     template<typename ResultType> | ||||
|     void computeInverseWithCheck( | ||||
|       ResultType& inverse, | ||||
|       bool& invertible, | ||||
|       const RealScalar& absDeterminantThreshold = NumTraits<Scalar>::dummy_precision() | ||||
|     ) const; | ||||
|     Scalar determinant() const; | ||||
|  | ||||
| /////////// Cholesky module /////////// | ||||
|  | ||||
|     const LLT<PlainObject>  llt() const; | ||||
|     const LDLT<PlainObject> ldlt() const; | ||||
|  | ||||
| /////////// QR module /////////// | ||||
|  | ||||
|     const HouseholderQR<PlainObject> householderQr() const; | ||||
|     const ColPivHouseholderQR<PlainObject> colPivHouseholderQr() const; | ||||
|     const FullPivHouseholderQR<PlainObject> fullPivHouseholderQr() const; | ||||
|      | ||||
|     #ifdef EIGEN2_SUPPORT | ||||
|     const QR<PlainObject> qr() const; | ||||
|     #endif | ||||
|  | ||||
|     EigenvaluesReturnType eigenvalues() const; | ||||
|     RealScalar operatorNorm() const; | ||||
|  | ||||
| /////////// SVD module /////////// | ||||
|  | ||||
|     JacobiSVD<PlainObject> jacobiSvd(unsigned int computationOptions = 0) const; | ||||
|  | ||||
|     #ifdef EIGEN2_SUPPORT | ||||
|     SVD<PlainObject> svd() const; | ||||
|     #endif | ||||
|  | ||||
| /////////// Geometry module /////////// | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /// \internal helper struct to form the return type of the cross product | ||||
|     template<typename OtherDerived> struct cross_product_return_type { | ||||
|       typedef typename internal::scalar_product_traits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType Scalar; | ||||
|       typedef Matrix<Scalar,MatrixBase::RowsAtCompileTime,MatrixBase::ColsAtCompileTime> type; | ||||
|     }; | ||||
|     #endif // EIGEN_PARSED_BY_DOXYGEN | ||||
|     template<typename OtherDerived> | ||||
|     typename cross_product_return_type<OtherDerived>::type | ||||
|     cross(const MatrixBase<OtherDerived>& other) const; | ||||
|     template<typename OtherDerived> | ||||
|     PlainObject cross3(const MatrixBase<OtherDerived>& other) const; | ||||
|     PlainObject unitOrthogonal(void) const; | ||||
|     Matrix<Scalar,3,1> eulerAngles(Index a0, Index a1, Index a2) const; | ||||
|      | ||||
|     #if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS | ||||
|     ScalarMultipleReturnType operator*(const UniformScaling<Scalar>& s) const; | ||||
|     // put this as separate enum value to work around possible GCC 4.3 bug (?) | ||||
|     enum { HomogeneousReturnTypeDirection = ColsAtCompileTime==1?Vertical:Horizontal }; | ||||
|     typedef Homogeneous<Derived, HomogeneousReturnTypeDirection> HomogeneousReturnType; | ||||
|     HomogeneousReturnType homogeneous() const; | ||||
|     #endif | ||||
|      | ||||
|     enum { | ||||
|       SizeMinusOne = SizeAtCompileTime==Dynamic ? Dynamic : SizeAtCompileTime-1 | ||||
|     }; | ||||
|     typedef Block<const Derived, | ||||
|                   internal::traits<Derived>::ColsAtCompileTime==1 ? SizeMinusOne : 1, | ||||
|                   internal::traits<Derived>::ColsAtCompileTime==1 ? 1 : SizeMinusOne> ConstStartMinusOne; | ||||
|     typedef CwiseUnaryOp<internal::scalar_quotient1_op<typename internal::traits<Derived>::Scalar>, | ||||
|                 const ConstStartMinusOne > HNormalizedReturnType; | ||||
|  | ||||
|     const HNormalizedReturnType hnormalized() const; | ||||
|  | ||||
| ////////// Householder module /////////// | ||||
|  | ||||
|     void makeHouseholderInPlace(Scalar& tau, RealScalar& beta); | ||||
|     template<typename EssentialPart> | ||||
|     void makeHouseholder(EssentialPart& essential, | ||||
|                          Scalar& tau, RealScalar& beta) const; | ||||
|     template<typename EssentialPart> | ||||
|     void applyHouseholderOnTheLeft(const EssentialPart& essential, | ||||
|                                    const Scalar& tau, | ||||
|                                    Scalar* workspace); | ||||
|     template<typename EssentialPart> | ||||
|     void applyHouseholderOnTheRight(const EssentialPart& essential, | ||||
|                                     const Scalar& tau, | ||||
|                                     Scalar* workspace); | ||||
|  | ||||
| ///////// Jacobi module ///////// | ||||
|  | ||||
|     template<typename OtherScalar> | ||||
|     void applyOnTheLeft(Index p, Index q, const JacobiRotation<OtherScalar>& j); | ||||
|     template<typename OtherScalar> | ||||
|     void applyOnTheRight(Index p, Index q, const JacobiRotation<OtherScalar>& j); | ||||
|  | ||||
| ///////// MatrixFunctions module ///////// | ||||
|  | ||||
|     typedef typename internal::stem_function<Scalar>::type StemFunction; | ||||
|     const MatrixExponentialReturnValue<Derived> exp() const; | ||||
|     const MatrixFunctionReturnValue<Derived> matrixFunction(StemFunction f) const; | ||||
|     const MatrixFunctionReturnValue<Derived> cosh() const; | ||||
|     const MatrixFunctionReturnValue<Derived> sinh() const; | ||||
|     const MatrixFunctionReturnValue<Derived> cos() const; | ||||
|     const MatrixFunctionReturnValue<Derived> sin() const; | ||||
|     const MatrixSquareRootReturnValue<Derived> sqrt() const; | ||||
|     const MatrixLogarithmReturnValue<Derived> log() const; | ||||
|  | ||||
| #ifdef EIGEN2_SUPPORT | ||||
|     template<typename ProductDerived, typename Lhs, typename Rhs> | ||||
|     Derived& operator+=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0, | ||||
|                                       EvalBeforeAssigningBit>& other); | ||||
|  | ||||
|     template<typename ProductDerived, typename Lhs, typename Rhs> | ||||
|     Derived& operator-=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0, | ||||
|                                       EvalBeforeAssigningBit>& other); | ||||
|  | ||||
|     /** \deprecated because .lazy() is deprecated | ||||
|       * Overloaded for cache friendly product evaluation */ | ||||
|     template<typename OtherDerived> | ||||
|     Derived& lazyAssign(const Flagged<OtherDerived, 0, EvalBeforeAssigningBit>& other) | ||||
|     { return lazyAssign(other._expression()); } | ||||
|  | ||||
|     template<unsigned int Added> | ||||
|     const Flagged<Derived, Added, 0> marked() const; | ||||
|     const Flagged<Derived, 0, EvalBeforeAssigningBit> lazy() const; | ||||
|  | ||||
|     inline const Cwise<Derived> cwise() const; | ||||
|     inline Cwise<Derived> cwise(); | ||||
|  | ||||
|     VectorBlock<Derived> start(Index size); | ||||
|     const VectorBlock<const Derived> start(Index size) const; | ||||
|     VectorBlock<Derived> end(Index size); | ||||
|     const VectorBlock<const Derived> end(Index size) const; | ||||
|     template<int Size> VectorBlock<Derived,Size> start(); | ||||
|     template<int Size> const VectorBlock<const Derived,Size> start() const; | ||||
|     template<int Size> VectorBlock<Derived,Size> end(); | ||||
|     template<int Size> const VectorBlock<const Derived,Size> end() const; | ||||
|  | ||||
|     Minor<Derived> minor(Index row, Index col); | ||||
|     const Minor<Derived> minor(Index row, Index col) const; | ||||
| #endif | ||||
|  | ||||
|   protected: | ||||
|     MatrixBase() : Base() {} | ||||
|  | ||||
|   private: | ||||
|     explicit MatrixBase(int); | ||||
|     MatrixBase(int,int); | ||||
|     template<typename OtherDerived> explicit MatrixBase(const MatrixBase<OtherDerived>&); | ||||
|   protected: | ||||
|     // mixing arrays and matrices is not legal | ||||
|     template<typename OtherDerived> Derived& operator+=(const ArrayBase<OtherDerived>& ) | ||||
|     {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} | ||||
|     // mixing arrays and matrices is not legal | ||||
|     template<typename OtherDerived> Derived& operator-=(const ArrayBase<OtherDerived>& ) | ||||
|     {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} | ||||
| }; | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_MATRIXBASE_H | ||||
							
								
								
									
										111
									
								
								latan/Eigen/src/Core/NestByValue.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								latan/Eigen/src/Core/NestByValue.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,111 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_NESTBYVALUE_H | ||||
| #define EIGEN_NESTBYVALUE_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| /** \class NestByValue | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Expression which must be nested by value | ||||
|   * | ||||
|   * \param ExpressionType the type of the object of which we are requiring nesting-by-value | ||||
|   * | ||||
|   * This class is the return type of MatrixBase::nestByValue() | ||||
|   * and most of the time this is the only way it is used. | ||||
|   * | ||||
|   * \sa MatrixBase::nestByValue() | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename ExpressionType> | ||||
| struct traits<NestByValue<ExpressionType> > : public traits<ExpressionType> | ||||
| {}; | ||||
| } | ||||
|  | ||||
| template<typename ExpressionType> class NestByValue | ||||
|   : public internal::dense_xpr_base< NestByValue<ExpressionType> >::type | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef typename internal::dense_xpr_base<NestByValue>::type Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(NestByValue) | ||||
|  | ||||
|     inline NestByValue(const ExpressionType& matrix) : m_expression(matrix) {} | ||||
|  | ||||
|     inline Index rows() const { return m_expression.rows(); } | ||||
|     inline Index cols() const { return m_expression.cols(); } | ||||
|     inline Index outerStride() const { return m_expression.outerStride(); } | ||||
|     inline Index innerStride() const { return m_expression.innerStride(); } | ||||
|  | ||||
|     inline const CoeffReturnType coeff(Index row, Index col) const | ||||
|     { | ||||
|       return m_expression.coeff(row, col); | ||||
|     } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index row, Index col) | ||||
|     { | ||||
|       return m_expression.const_cast_derived().coeffRef(row, col); | ||||
|     } | ||||
|  | ||||
|     inline const CoeffReturnType coeff(Index index) const | ||||
|     { | ||||
|       return m_expression.coeff(index); | ||||
|     } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index index) | ||||
|     { | ||||
|       return m_expression.const_cast_derived().coeffRef(index); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline const PacketScalar packet(Index row, Index col) const | ||||
|     { | ||||
|       return m_expression.template packet<LoadMode>(row, col); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline void writePacket(Index row, Index col, const PacketScalar& x) | ||||
|     { | ||||
|       m_expression.const_cast_derived().template writePacket<LoadMode>(row, col, x); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline const PacketScalar packet(Index index) const | ||||
|     { | ||||
|       return m_expression.template packet<LoadMode>(index); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline void writePacket(Index index, const PacketScalar& x) | ||||
|     { | ||||
|       m_expression.const_cast_derived().template writePacket<LoadMode>(index, x); | ||||
|     } | ||||
|  | ||||
|     operator const ExpressionType&() const { return m_expression; } | ||||
|  | ||||
|   protected: | ||||
|     const ExpressionType m_expression; | ||||
| }; | ||||
|  | ||||
| /** \returns an expression of the temporary version of *this. | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline const NestByValue<Derived> | ||||
| DenseBase<Derived>::nestByValue() const | ||||
| { | ||||
|   return NestByValue<Derived>(derived()); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_NESTBYVALUE_H | ||||
							
								
								
									
										125
									
								
								latan/Eigen/src/Core/NoAlias.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								latan/Eigen/src/Core/NoAlias.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,125 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_NOALIAS_H | ||||
| #define EIGEN_NOALIAS_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| /** \class NoAlias | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Pseudo expression providing an operator = assuming no aliasing | ||||
|   * | ||||
|   * \param ExpressionType the type of the object on which to do the lazy assignment | ||||
|   * | ||||
|   * This class represents an expression with special assignment operators | ||||
|   * assuming no aliasing between the target expression and the source expression. | ||||
|   * More precisely it alloas to bypass the EvalBeforeAssignBit flag of the source expression. | ||||
|   * It is the return type of MatrixBase::noalias() | ||||
|   * and most of the time this is the only way it is used. | ||||
|   * | ||||
|   * \sa MatrixBase::noalias() | ||||
|   */ | ||||
| template<typename ExpressionType, template <typename> class StorageBase> | ||||
| class NoAlias | ||||
| { | ||||
|     typedef typename ExpressionType::Scalar Scalar; | ||||
|   public: | ||||
|     NoAlias(ExpressionType& expression) : m_expression(expression) {} | ||||
|  | ||||
|     /** Behaves like MatrixBase::lazyAssign(other) | ||||
|       * \sa MatrixBase::lazyAssign() */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other) | ||||
|     { return internal::assign_selector<ExpressionType,OtherDerived,false>::run(m_expression,other.derived()); } | ||||
|  | ||||
|     /** \sa MatrixBase::operator+= */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase<OtherDerived>& other) | ||||
|     { | ||||
|       typedef SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, ExpressionType, OtherDerived> SelfAdder; | ||||
|       SelfAdder tmp(m_expression); | ||||
|       typedef typename internal::nested<OtherDerived>::type OtherDerivedNested; | ||||
|       typedef typename internal::remove_all<OtherDerivedNested>::type _OtherDerivedNested; | ||||
|       internal::assign_selector<SelfAdder,_OtherDerivedNested,false>::run(tmp,OtherDerivedNested(other.derived())); | ||||
|       return m_expression; | ||||
|     } | ||||
|  | ||||
|     /** \sa MatrixBase::operator-= */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE ExpressionType& operator-=(const StorageBase<OtherDerived>& other) | ||||
|     { | ||||
|       typedef SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, ExpressionType, OtherDerived> SelfAdder; | ||||
|       SelfAdder tmp(m_expression); | ||||
|       typedef typename internal::nested<OtherDerived>::type OtherDerivedNested; | ||||
|       typedef typename internal::remove_all<OtherDerivedNested>::type _OtherDerivedNested; | ||||
|       internal::assign_selector<SelfAdder,_OtherDerivedNested,false>::run(tmp,OtherDerivedNested(other.derived())); | ||||
|       return m_expression; | ||||
|     } | ||||
|  | ||||
| #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     template<typename ProductDerived, typename Lhs, typename Rhs> | ||||
|     EIGEN_STRONG_INLINE ExpressionType& operator+=(const ProductBase<ProductDerived, Lhs,Rhs>& other) | ||||
|     { other.derived().addTo(m_expression); return m_expression; } | ||||
|  | ||||
|     template<typename ProductDerived, typename Lhs, typename Rhs> | ||||
|     EIGEN_STRONG_INLINE ExpressionType& operator-=(const ProductBase<ProductDerived, Lhs,Rhs>& other) | ||||
|     { other.derived().subTo(m_expression); return m_expression; } | ||||
|  | ||||
|     template<typename Lhs, typename Rhs, int NestingFlags> | ||||
|     EIGEN_STRONG_INLINE ExpressionType& operator+=(const CoeffBasedProduct<Lhs,Rhs,NestingFlags>& other) | ||||
|     { return m_expression.derived() += CoeffBasedProduct<Lhs,Rhs,NestByRefBit>(other.lhs(), other.rhs()); } | ||||
|  | ||||
|     template<typename Lhs, typename Rhs, int NestingFlags> | ||||
|     EIGEN_STRONG_INLINE ExpressionType& operator-=(const CoeffBasedProduct<Lhs,Rhs,NestingFlags>& other) | ||||
|     { return m_expression.derived() -= CoeffBasedProduct<Lhs,Rhs,NestByRefBit>(other.lhs(), other.rhs()); } | ||||
| #endif | ||||
|  | ||||
|   protected: | ||||
|     ExpressionType& m_expression; | ||||
| }; | ||||
|  | ||||
| /** \returns a pseudo expression of \c *this with an operator= assuming | ||||
|   * no aliasing between \c *this and the source expression. | ||||
|   * | ||||
|   * More precisely, noalias() allows to bypass the EvalBeforeAssignBit flag. | ||||
|   * Currently, even though several expressions may alias, only product | ||||
|   * expressions have this flag. Therefore, noalias() is only usefull when | ||||
|   * the source expression contains a matrix product. | ||||
|   * | ||||
|   * Here are some examples where noalias is usefull: | ||||
|   * \code | ||||
|   * D.noalias()  = A * B; | ||||
|   * D.noalias() += A.transpose() * B; | ||||
|   * D.noalias() -= 2 * A * B.adjoint(); | ||||
|   * \endcode | ||||
|   * | ||||
|   * On the other hand the following example will lead to a \b wrong result: | ||||
|   * \code | ||||
|   * A.noalias() = A * B; | ||||
|   * \endcode | ||||
|   * because the result matrix A is also an operand of the matrix product. Therefore, | ||||
|   * there is no alternative than evaluating A * B in a temporary, that is the default | ||||
|   * behavior when you write: | ||||
|   * \code | ||||
|   * A = A * B; | ||||
|   * \endcode | ||||
|   * | ||||
|   * \sa class NoAlias | ||||
|   */ | ||||
| template<typename Derived> | ||||
| NoAlias<Derived,MatrixBase> MatrixBase<Derived>::noalias() | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_NOALIAS_H | ||||
							
								
								
									
										147
									
								
								latan/Eigen/src/Core/NumTraits.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								latan/Eigen/src/Core/NumTraits.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,147 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_NUMTRAITS_H | ||||
| #define EIGEN_NUMTRAITS_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| /** \class NumTraits | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Holds information about the various numeric (i.e. scalar) types allowed by Eigen. | ||||
|   * | ||||
|   * \param T the numeric type at hand | ||||
|   * | ||||
|   * This class stores enums, typedefs and static methods giving information about a numeric type. | ||||
|   * | ||||
|   * The provided data consists of: | ||||
|   * \li A typedef \a Real, giving the "real part" type of \a T. If \a T is already real, | ||||
|   *     then \a Real is just a typedef to \a T. If \a T is \c std::complex<U> then \a Real | ||||
|   *     is a typedef to \a U. | ||||
|   * \li A typedef \a NonInteger, giving the type that should be used for operations producing non-integral values, | ||||
|   *     such as quotients, square roots, etc. If \a T is a floating-point type, then this typedef just gives | ||||
|   *     \a T again. Note however that many Eigen functions such as internal::sqrt simply refuse to | ||||
|   *     take integers. Outside of a few cases, Eigen doesn't do automatic type promotion. Thus, this typedef is | ||||
|   *     only intended as a helper for code that needs to explicitly promote types. | ||||
|   * \li A typedef \a Nested giving the type to use to nest a value inside of the expression tree. If you don't know what | ||||
|   *     this means, just use \a T here. | ||||
|   * \li An enum value \a IsComplex. It is equal to 1 if \a T is a \c std::complex | ||||
|   *     type, and to 0 otherwise. | ||||
|   * \li An enum value \a IsInteger. It is equal to \c 1 if \a T is an integer type such as \c int, | ||||
|   *     and to \c 0 otherwise. | ||||
|   * \li Enum values ReadCost, AddCost and MulCost representing a rough estimate of the number of CPU cycles needed | ||||
|   *     to by move / add / mul instructions respectively, assuming the data is already stored in CPU registers. | ||||
|   *     Stay vague here. No need to do architecture-specific stuff. | ||||
|   * \li An enum value \a IsSigned. It is equal to \c 1 if \a T is a signed type and to 0 if \a T is unsigned. | ||||
|   * \li An enum value \a RequireInitialization. It is equal to \c 1 if the constructor of the numeric type \a T must | ||||
|   *     be called, and to 0 if it is safe not to call it. Default is 0 if \a T is an arithmetic type, and 1 otherwise. | ||||
|   * \li An epsilon() function which, unlike std::numeric_limits::epsilon(), returns a \a Real instead of a \a T. | ||||
|   * \li A dummy_precision() function returning a weak epsilon value. It is mainly used as a default | ||||
|   *     value by the fuzzy comparison operators. | ||||
|   * \li highest() and lowest() functions returning the highest and lowest possible values respectively. | ||||
|   */ | ||||
|  | ||||
| template<typename T> struct GenericNumTraits | ||||
| { | ||||
|   enum { | ||||
|     IsInteger = std::numeric_limits<T>::is_integer, | ||||
|     IsSigned = std::numeric_limits<T>::is_signed, | ||||
|     IsComplex = 0, | ||||
|     RequireInitialization = internal::is_arithmetic<T>::value ? 0 : 1, | ||||
|     ReadCost = 1, | ||||
|     AddCost = 1, | ||||
|     MulCost = 1 | ||||
|   }; | ||||
|  | ||||
|   typedef T Real; | ||||
|   typedef typename internal::conditional< | ||||
|                      IsInteger, | ||||
|                      typename internal::conditional<sizeof(T)<=2, float, double>::type, | ||||
|                      T | ||||
|                    >::type NonInteger; | ||||
|   typedef T Nested; | ||||
|  | ||||
|   static inline Real epsilon() { return std::numeric_limits<T>::epsilon(); } | ||||
|   static inline Real dummy_precision() | ||||
|   { | ||||
|     // make sure to override this for floating-point types | ||||
|     return Real(0); | ||||
|   } | ||||
|   static inline T highest() { return (std::numeric_limits<T>::max)(); } | ||||
|   static inline T lowest()  { return IsInteger ? (std::numeric_limits<T>::min)() : (-(std::numeric_limits<T>::max)()); } | ||||
|    | ||||
| #ifdef EIGEN2_SUPPORT | ||||
|   enum { | ||||
|     HasFloatingPoint = !IsInteger | ||||
|   }; | ||||
|   typedef NonInteger FloatingPoint; | ||||
| #endif | ||||
| }; | ||||
|  | ||||
| template<typename T> struct NumTraits : GenericNumTraits<T> | ||||
| {}; | ||||
|  | ||||
| template<> struct NumTraits<float> | ||||
|   : GenericNumTraits<float> | ||||
| { | ||||
|   static inline float dummy_precision() { return 1e-5f; } | ||||
| }; | ||||
|  | ||||
| template<> struct NumTraits<double> : GenericNumTraits<double> | ||||
| { | ||||
|   static inline double dummy_precision() { return 1e-12; } | ||||
| }; | ||||
|  | ||||
| template<> struct NumTraits<long double> | ||||
|   : GenericNumTraits<long double> | ||||
| { | ||||
|   static inline long double dummy_precision() { return 1e-15l; } | ||||
| }; | ||||
|  | ||||
| template<typename _Real> struct NumTraits<std::complex<_Real> > | ||||
|   : GenericNumTraits<std::complex<_Real> > | ||||
| { | ||||
|   typedef _Real Real; | ||||
|   enum { | ||||
|     IsComplex = 1, | ||||
|     RequireInitialization = NumTraits<_Real>::RequireInitialization, | ||||
|     ReadCost = 2 * NumTraits<_Real>::ReadCost, | ||||
|     AddCost = 2 * NumTraits<Real>::AddCost, | ||||
|     MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost | ||||
|   }; | ||||
|  | ||||
|   static inline Real epsilon() { return NumTraits<Real>::epsilon(); } | ||||
|   static inline Real dummy_precision() { return NumTraits<Real>::dummy_precision(); } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols> | ||||
| struct NumTraits<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > | ||||
| { | ||||
|   typedef Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> ArrayType; | ||||
|   typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|   typedef Array<RealScalar, Rows, Cols, Options, MaxRows, MaxCols> Real; | ||||
|   typedef typename NumTraits<Scalar>::NonInteger NonIntegerScalar; | ||||
|   typedef Array<NonIntegerScalar, Rows, Cols, Options, MaxRows, MaxCols> NonInteger; | ||||
|   typedef ArrayType & Nested; | ||||
|    | ||||
|   enum { | ||||
|     IsComplex = NumTraits<Scalar>::IsComplex, | ||||
|     IsInteger = NumTraits<Scalar>::IsInteger, | ||||
|     IsSigned  = NumTraits<Scalar>::IsSigned, | ||||
|     RequireInitialization = 1, | ||||
|     ReadCost = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::ReadCost, | ||||
|     AddCost  = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::AddCost, | ||||
|     MulCost  = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::MulCost | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_NUMTRAITS_H | ||||
							
								
								
									
										687
									
								
								latan/Eigen/src/Core/PermutationMatrix.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										687
									
								
								latan/Eigen/src/Core/PermutationMatrix.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,687 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // Copyright (C) 2009-2011 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_PERMUTATIONMATRIX_H | ||||
| #define EIGEN_PERMUTATIONMATRIX_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| template<int RowCol,typename IndicesType,typename MatrixType, typename StorageKind> class PermutedImpl; | ||||
|  | ||||
| /** \class PermutationBase | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Base class for permutations | ||||
|   * | ||||
|   * \param Derived the derived class | ||||
|   * | ||||
|   * This class is the base class for all expressions representing a permutation matrix, | ||||
|   * internally stored as a vector of integers. | ||||
|   * The convention followed here is that if \f$ \sigma \f$ is a permutation, the corresponding permutation matrix | ||||
|   * \f$ P_\sigma \f$ is such that if \f$ (e_1,\ldots,e_p) \f$ is the canonical basis, we have: | ||||
|   *  \f[ P_\sigma(e_i) = e_{\sigma(i)}. \f] | ||||
|   * This convention ensures that for any two permutations \f$ \sigma, \tau \f$, we have: | ||||
|   *  \f[ P_{\sigma\circ\tau} = P_\sigma P_\tau. \f] | ||||
|   * | ||||
|   * Permutation matrices are square and invertible. | ||||
|   * | ||||
|   * Notice that in addition to the member functions and operators listed here, there also are non-member | ||||
|   * operator* to multiply any kind of permutation object with any kind of matrix expression (MatrixBase) | ||||
|   * on either side. | ||||
|   * | ||||
|   * \sa class PermutationMatrix, class PermutationWrapper | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename PermutationType, typename MatrixType, int Side, bool Transposed=false> | ||||
| struct permut_matrix_product_retval; | ||||
| template<typename PermutationType, typename MatrixType, int Side, bool Transposed=false> | ||||
| struct permut_sparsematrix_product_retval; | ||||
| enum PermPermProduct_t {PermPermProduct}; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| template<typename Derived> | ||||
| class PermutationBase : public EigenBase<Derived> | ||||
| { | ||||
|     typedef internal::traits<Derived> Traits; | ||||
|     typedef EigenBase<Derived> Base; | ||||
|   public: | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     typedef typename Traits::IndicesType IndicesType; | ||||
|     enum { | ||||
|       Flags = Traits::Flags, | ||||
|       CoeffReadCost = Traits::CoeffReadCost, | ||||
|       RowsAtCompileTime = Traits::RowsAtCompileTime, | ||||
|       ColsAtCompileTime = Traits::ColsAtCompileTime, | ||||
|       MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime, | ||||
|       MaxColsAtCompileTime = Traits::MaxColsAtCompileTime | ||||
|     }; | ||||
|     typedef typename Traits::Scalar Scalar; | ||||
|     typedef typename Traits::Index Index; | ||||
|     typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime,0,MaxRowsAtCompileTime,MaxColsAtCompileTime> | ||||
|             DenseMatrixType; | ||||
|     typedef PermutationMatrix<IndicesType::SizeAtCompileTime,IndicesType::MaxSizeAtCompileTime,Index> | ||||
|             PlainPermutationType; | ||||
|     using Base::derived; | ||||
|     #endif | ||||
|  | ||||
|     /** Copies the other permutation into *this */ | ||||
|     template<typename OtherDerived> | ||||
|     Derived& operator=(const PermutationBase<OtherDerived>& other) | ||||
|     { | ||||
|       indices() = other.indices(); | ||||
|       return derived(); | ||||
|     } | ||||
|  | ||||
|     /** Assignment from the Transpositions \a tr */ | ||||
|     template<typename OtherDerived> | ||||
|     Derived& operator=(const TranspositionsBase<OtherDerived>& tr) | ||||
|     { | ||||
|       setIdentity(tr.size()); | ||||
|       for(Index k=size()-1; k>=0; --k) | ||||
|         applyTranspositionOnTheRight(k,tr.coeff(k)); | ||||
|       return derived(); | ||||
|     } | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /** This is a special case of the templated operator=. Its purpose is to | ||||
|       * prevent a default operator= from hiding the templated operator=. | ||||
|       */ | ||||
|     Derived& operator=(const PermutationBase& other) | ||||
|     { | ||||
|       indices() = other.indices(); | ||||
|       return derived(); | ||||
|     } | ||||
|     #endif | ||||
|  | ||||
|     /** \returns the number of rows */ | ||||
|     inline Index rows() const { return Index(indices().size()); } | ||||
|  | ||||
|     /** \returns the number of columns */ | ||||
|     inline Index cols() const { return Index(indices().size()); } | ||||
|  | ||||
|     /** \returns the size of a side of the respective square matrix, i.e., the number of indices */ | ||||
|     inline Index size() const { return Index(indices().size()); } | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     template<typename DenseDerived> | ||||
|     void evalTo(MatrixBase<DenseDerived>& other) const | ||||
|     { | ||||
|       other.setZero(); | ||||
|       for (int i=0; i<rows();++i) | ||||
|         other.coeffRef(indices().coeff(i),i) = typename DenseDerived::Scalar(1); | ||||
|     } | ||||
|     #endif | ||||
|  | ||||
|     /** \returns a Matrix object initialized from this permutation matrix. Notice that it | ||||
|       * is inefficient to return this Matrix object by value. For efficiency, favor using | ||||
|       * the Matrix constructor taking EigenBase objects. | ||||
|       */ | ||||
|     DenseMatrixType toDenseMatrix() const | ||||
|     { | ||||
|       return derived(); | ||||
|     } | ||||
|  | ||||
|     /** const version of indices(). */ | ||||
|     const IndicesType& indices() const { return derived().indices(); } | ||||
|     /** \returns a reference to the stored array representing the permutation. */ | ||||
|     IndicesType& indices() { return derived().indices(); } | ||||
|  | ||||
|     /** Resizes to given size. | ||||
|       */ | ||||
|     inline void resize(Index size) | ||||
|     { | ||||
|       indices().resize(size); | ||||
|     } | ||||
|  | ||||
|     /** Sets *this to be the identity permutation matrix */ | ||||
|     void setIdentity() | ||||
|     { | ||||
|       for(Index i = 0; i < size(); ++i) | ||||
|         indices().coeffRef(i) = i; | ||||
|     } | ||||
|  | ||||
|     /** Sets *this to be the identity permutation matrix of given size. | ||||
|       */ | ||||
|     void setIdentity(Index size) | ||||
|     { | ||||
|       resize(size); | ||||
|       setIdentity(); | ||||
|     } | ||||
|  | ||||
|     /** Multiplies *this by the transposition \f$(ij)\f$ on the left. | ||||
|       * | ||||
|       * \returns a reference to *this. | ||||
|       * | ||||
|       * \warning This is much slower than applyTranspositionOnTheRight(int,int): | ||||
|       * this has linear complexity and requires a lot of branching. | ||||
|       * | ||||
|       * \sa applyTranspositionOnTheRight(int,int) | ||||
|       */ | ||||
|     Derived& applyTranspositionOnTheLeft(Index i, Index j) | ||||
|     { | ||||
|       eigen_assert(i>=0 && j>=0 && i<size() && j<size()); | ||||
|       for(Index k = 0; k < size(); ++k) | ||||
|       { | ||||
|         if(indices().coeff(k) == i) indices().coeffRef(k) = j; | ||||
|         else if(indices().coeff(k) == j) indices().coeffRef(k) = i; | ||||
|       } | ||||
|       return derived(); | ||||
|     } | ||||
|  | ||||
|     /** Multiplies *this by the transposition \f$(ij)\f$ on the right. | ||||
|       * | ||||
|       * \returns a reference to *this. | ||||
|       * | ||||
|       * This is a fast operation, it only consists in swapping two indices. | ||||
|       * | ||||
|       * \sa applyTranspositionOnTheLeft(int,int) | ||||
|       */ | ||||
|     Derived& applyTranspositionOnTheRight(Index i, Index j) | ||||
|     { | ||||
|       eigen_assert(i>=0 && j>=0 && i<size() && j<size()); | ||||
|       std::swap(indices().coeffRef(i), indices().coeffRef(j)); | ||||
|       return derived(); | ||||
|     } | ||||
|  | ||||
|     /** \returns the inverse permutation matrix. | ||||
|       * | ||||
|       * \note \note_try_to_help_rvo | ||||
|       */ | ||||
|     inline Transpose<PermutationBase> inverse() const | ||||
|     { return derived(); } | ||||
|     /** \returns the tranpose permutation matrix. | ||||
|       * | ||||
|       * \note \note_try_to_help_rvo | ||||
|       */ | ||||
|     inline Transpose<PermutationBase> transpose() const | ||||
|     { return derived(); } | ||||
|  | ||||
|     /**** multiplication helpers to hopefully get RVO ****/ | ||||
|  | ||||
|    | ||||
| #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|   protected: | ||||
|     template<typename OtherDerived> | ||||
|     void assignTranspose(const PermutationBase<OtherDerived>& other) | ||||
|     { | ||||
|       for (int i=0; i<rows();++i) indices().coeffRef(other.indices().coeff(i)) = i; | ||||
|     } | ||||
|     template<typename Lhs,typename Rhs> | ||||
|     void assignProduct(const Lhs& lhs, const Rhs& rhs) | ||||
|     { | ||||
|       eigen_assert(lhs.cols() == rhs.rows()); | ||||
|       for (int i=0; i<rows();++i) indices().coeffRef(i) = lhs.indices().coeff(rhs.indices().coeff(i)); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|   public: | ||||
|  | ||||
|     /** \returns the product permutation matrix. | ||||
|       * | ||||
|       * \note \note_try_to_help_rvo | ||||
|       */ | ||||
|     template<typename Other> | ||||
|     inline PlainPermutationType operator*(const PermutationBase<Other>& other) const | ||||
|     { return PlainPermutationType(internal::PermPermProduct, derived(), other.derived()); } | ||||
|  | ||||
|     /** \returns the product of a permutation with another inverse permutation. | ||||
|       * | ||||
|       * \note \note_try_to_help_rvo | ||||
|       */ | ||||
|     template<typename Other> | ||||
|     inline PlainPermutationType operator*(const Transpose<PermutationBase<Other> >& other) const | ||||
|     { return PlainPermutationType(internal::PermPermProduct, *this, other.eval()); } | ||||
|  | ||||
|     /** \returns the product of an inverse permutation with another permutation. | ||||
|       * | ||||
|       * \note \note_try_to_help_rvo | ||||
|       */ | ||||
|     template<typename Other> friend | ||||
|     inline PlainPermutationType operator*(const Transpose<PermutationBase<Other> >& other, const PermutationBase& perm) | ||||
|     { return PlainPermutationType(internal::PermPermProduct, other.eval(), perm); } | ||||
|  | ||||
|   protected: | ||||
|  | ||||
| }; | ||||
|  | ||||
| /** \class PermutationMatrix | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Permutation matrix | ||||
|   * | ||||
|   * \param SizeAtCompileTime the number of rows/cols, or Dynamic | ||||
|   * \param MaxSizeAtCompileTime the maximum number of rows/cols, or Dynamic. This optional parameter defaults to SizeAtCompileTime. Most of the time, you should not have to specify it. | ||||
|   * \param IndexType the interger type of the indices | ||||
|   * | ||||
|   * This class represents a permutation matrix, internally stored as a vector of integers. | ||||
|   * | ||||
|   * \sa class PermutationBase, class PermutationWrapper, class DiagonalMatrix | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType> | ||||
| struct traits<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType> > | ||||
|  : traits<Matrix<IndexType,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> > | ||||
| { | ||||
|   typedef IndexType Index; | ||||
|   typedef Matrix<IndexType, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType> | ||||
| class PermutationMatrix : public PermutationBase<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType> > | ||||
| { | ||||
|     typedef PermutationBase<PermutationMatrix> Base; | ||||
|     typedef internal::traits<PermutationMatrix> Traits; | ||||
|   public: | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     typedef typename Traits::IndicesType IndicesType; | ||||
|     #endif | ||||
|  | ||||
|     inline PermutationMatrix() | ||||
|     {} | ||||
|  | ||||
|     /** Constructs an uninitialized permutation matrix of given size. | ||||
|       */ | ||||
|     inline PermutationMatrix(int size) : m_indices(size) | ||||
|     {} | ||||
|  | ||||
|     /** Copy constructor. */ | ||||
|     template<typename OtherDerived> | ||||
|     inline PermutationMatrix(const PermutationBase<OtherDerived>& other) | ||||
|       : m_indices(other.indices()) {} | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /** Standard copy constructor. Defined only to prevent a default copy constructor | ||||
|       * from hiding the other templated constructor */ | ||||
|     inline PermutationMatrix(const PermutationMatrix& other) : m_indices(other.indices()) {} | ||||
|     #endif | ||||
|  | ||||
|     /** Generic constructor from expression of the indices. The indices | ||||
|       * array has the meaning that the permutations sends each integer i to indices[i]. | ||||
|       * | ||||
|       * \warning It is your responsibility to check that the indices array that you passes actually | ||||
|       * describes a permutation, i.e., each value between 0 and n-1 occurs exactly once, where n is the | ||||
|       * array's size. | ||||
|       */ | ||||
|     template<typename Other> | ||||
|     explicit inline PermutationMatrix(const MatrixBase<Other>& indices) : m_indices(indices) | ||||
|     {} | ||||
|  | ||||
|     /** Convert the Transpositions \a tr to a permutation matrix */ | ||||
|     template<typename Other> | ||||
|     explicit PermutationMatrix(const TranspositionsBase<Other>& tr) | ||||
|       : m_indices(tr.size()) | ||||
|     { | ||||
|       *this = tr; | ||||
|     } | ||||
|  | ||||
|     /** Copies the other permutation into *this */ | ||||
|     template<typename Other> | ||||
|     PermutationMatrix& operator=(const PermutationBase<Other>& other) | ||||
|     { | ||||
|       m_indices = other.indices(); | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     /** Assignment from the Transpositions \a tr */ | ||||
|     template<typename Other> | ||||
|     PermutationMatrix& operator=(const TranspositionsBase<Other>& tr) | ||||
|     { | ||||
|       return Base::operator=(tr.derived()); | ||||
|     } | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /** This is a special case of the templated operator=. Its purpose is to | ||||
|       * prevent a default operator= from hiding the templated operator=. | ||||
|       */ | ||||
|     PermutationMatrix& operator=(const PermutationMatrix& other) | ||||
|     { | ||||
|       m_indices = other.m_indices; | ||||
|       return *this; | ||||
|     } | ||||
|     #endif | ||||
|  | ||||
|     /** const version of indices(). */ | ||||
|     const IndicesType& indices() const { return m_indices; } | ||||
|     /** \returns a reference to the stored array representing the permutation. */ | ||||
|     IndicesType& indices() { return m_indices; } | ||||
|  | ||||
|  | ||||
|     /**** multiplication helpers to hopefully get RVO ****/ | ||||
|  | ||||
| #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     template<typename Other> | ||||
|     PermutationMatrix(const Transpose<PermutationBase<Other> >& other) | ||||
|       : m_indices(other.nestedPermutation().size()) | ||||
|     { | ||||
|       for (int i=0; i<m_indices.size();++i) m_indices.coeffRef(other.nestedPermutation().indices().coeff(i)) = i; | ||||
|     } | ||||
|     template<typename Lhs,typename Rhs> | ||||
|     PermutationMatrix(internal::PermPermProduct_t, const Lhs& lhs, const Rhs& rhs) | ||||
|       : m_indices(lhs.indices().size()) | ||||
|     { | ||||
|       Base::assignProduct(lhs,rhs); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|   protected: | ||||
|  | ||||
|     IndicesType m_indices; | ||||
| }; | ||||
|  | ||||
|  | ||||
| namespace internal { | ||||
| template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int _PacketAccess> | ||||
| struct traits<Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType>,_PacketAccess> > | ||||
|  : traits<Matrix<IndexType,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> > | ||||
| { | ||||
|   typedef IndexType Index; | ||||
|   typedef Map<const Matrix<IndexType, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1>, _PacketAccess> IndicesType; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int _PacketAccess> | ||||
| class Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType>,_PacketAccess> | ||||
|   : public PermutationBase<Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType>,_PacketAccess> > | ||||
| { | ||||
|     typedef PermutationBase<Map> Base; | ||||
|     typedef internal::traits<Map> Traits; | ||||
|   public: | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     typedef typename Traits::IndicesType IndicesType; | ||||
|     typedef typename IndicesType::Scalar Index; | ||||
|     #endif | ||||
|  | ||||
|     inline Map(const Index* indices) | ||||
|       : m_indices(indices) | ||||
|     {} | ||||
|  | ||||
|     inline Map(const Index* indices, Index size) | ||||
|       : m_indices(indices,size) | ||||
|     {} | ||||
|  | ||||
|     /** Copies the other permutation into *this */ | ||||
|     template<typename Other> | ||||
|     Map& operator=(const PermutationBase<Other>& other) | ||||
|     { return Base::operator=(other.derived()); } | ||||
|  | ||||
|     /** Assignment from the Transpositions \a tr */ | ||||
|     template<typename Other> | ||||
|     Map& operator=(const TranspositionsBase<Other>& tr) | ||||
|     { return Base::operator=(tr.derived()); } | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /** This is a special case of the templated operator=. Its purpose is to | ||||
|       * prevent a default operator= from hiding the templated operator=. | ||||
|       */ | ||||
|     Map& operator=(const Map& other) | ||||
|     { | ||||
|       m_indices = other.m_indices; | ||||
|       return *this; | ||||
|     } | ||||
|     #endif | ||||
|  | ||||
|     /** const version of indices(). */ | ||||
|     const IndicesType& indices() const { return m_indices; } | ||||
|     /** \returns a reference to the stored array representing the permutation. */ | ||||
|     IndicesType& indices() { return m_indices; } | ||||
|  | ||||
|   protected: | ||||
|  | ||||
|     IndicesType m_indices; | ||||
| }; | ||||
|  | ||||
| /** \class PermutationWrapper | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Class to view a vector of integers as a permutation matrix | ||||
|   * | ||||
|   * \param _IndicesType the type of the vector of integer (can be any compatible expression) | ||||
|   * | ||||
|   * This class allows to view any vector expression of integers as a permutation matrix. | ||||
|   * | ||||
|   * \sa class PermutationBase, class PermutationMatrix | ||||
|   */ | ||||
|  | ||||
| struct PermutationStorage {}; | ||||
|  | ||||
| template<typename _IndicesType> class TranspositionsWrapper; | ||||
| namespace internal { | ||||
| template<typename _IndicesType> | ||||
| struct traits<PermutationWrapper<_IndicesType> > | ||||
| { | ||||
|   typedef PermutationStorage StorageKind; | ||||
|   typedef typename _IndicesType::Scalar Scalar; | ||||
|   typedef typename _IndicesType::Scalar Index; | ||||
|   typedef _IndicesType IndicesType; | ||||
|   enum { | ||||
|     RowsAtCompileTime = _IndicesType::SizeAtCompileTime, | ||||
|     ColsAtCompileTime = _IndicesType::SizeAtCompileTime, | ||||
|     MaxRowsAtCompileTime = IndicesType::MaxRowsAtCompileTime, | ||||
|     MaxColsAtCompileTime = IndicesType::MaxColsAtCompileTime, | ||||
|     Flags = 0, | ||||
|     CoeffReadCost = _IndicesType::CoeffReadCost | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename _IndicesType> | ||||
| class PermutationWrapper : public PermutationBase<PermutationWrapper<_IndicesType> > | ||||
| { | ||||
|     typedef PermutationBase<PermutationWrapper> Base; | ||||
|     typedef internal::traits<PermutationWrapper> Traits; | ||||
|   public: | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     typedef typename Traits::IndicesType IndicesType; | ||||
|     #endif | ||||
|  | ||||
|     inline PermutationWrapper(const IndicesType& indices) | ||||
|       : m_indices(indices) | ||||
|     {} | ||||
|  | ||||
|     /** const version of indices(). */ | ||||
|     const typename internal::remove_all<typename IndicesType::Nested>::type& | ||||
|     indices() const { return m_indices; } | ||||
|  | ||||
|   protected: | ||||
|  | ||||
|     typename IndicesType::Nested m_indices; | ||||
| }; | ||||
|  | ||||
| /** \returns the matrix with the permutation applied to the columns. | ||||
|   */ | ||||
| template<typename Derived, typename PermutationDerived> | ||||
| inline const internal::permut_matrix_product_retval<PermutationDerived, Derived, OnTheRight> | ||||
| operator*(const MatrixBase<Derived>& matrix, | ||||
|           const PermutationBase<PermutationDerived> &permutation) | ||||
| { | ||||
|   return internal::permut_matrix_product_retval | ||||
|            <PermutationDerived, Derived, OnTheRight> | ||||
|            (permutation.derived(), matrix.derived()); | ||||
| } | ||||
|  | ||||
| /** \returns the matrix with the permutation applied to the rows. | ||||
|   */ | ||||
| template<typename Derived, typename PermutationDerived> | ||||
| inline const internal::permut_matrix_product_retval | ||||
|                <PermutationDerived, Derived, OnTheLeft> | ||||
| operator*(const PermutationBase<PermutationDerived> &permutation, | ||||
|           const MatrixBase<Derived>& matrix) | ||||
| { | ||||
|   return internal::permut_matrix_product_retval | ||||
|            <PermutationDerived, Derived, OnTheLeft> | ||||
|            (permutation.derived(), matrix.derived()); | ||||
| } | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename PermutationType, typename MatrixType, int Side, bool Transposed> | ||||
| struct traits<permut_matrix_product_retval<PermutationType, MatrixType, Side, Transposed> > | ||||
| { | ||||
|   typedef typename MatrixType::PlainObject ReturnType; | ||||
| }; | ||||
|  | ||||
| template<typename PermutationType, typename MatrixType, int Side, bool Transposed> | ||||
| struct permut_matrix_product_retval | ||||
|  : public ReturnByValue<permut_matrix_product_retval<PermutationType, MatrixType, Side, Transposed> > | ||||
| { | ||||
|     typedef typename remove_all<typename MatrixType::Nested>::type MatrixTypeNestedCleaned; | ||||
|  | ||||
|     permut_matrix_product_retval(const PermutationType& perm, const MatrixType& matrix) | ||||
|       : m_permutation(perm), m_matrix(matrix) | ||||
|     {} | ||||
|  | ||||
|     inline int rows() const { return m_matrix.rows(); } | ||||
|     inline int cols() const { return m_matrix.cols(); } | ||||
|  | ||||
|     template<typename Dest> inline void evalTo(Dest& dst) const | ||||
|     { | ||||
|       const int n = Side==OnTheLeft ? rows() : cols(); | ||||
|  | ||||
|       if(is_same<MatrixTypeNestedCleaned,Dest>::value && extract_data(dst) == extract_data(m_matrix)) | ||||
|       { | ||||
|         // apply the permutation inplace | ||||
|         Matrix<bool,PermutationType::RowsAtCompileTime,1,0,PermutationType::MaxRowsAtCompileTime> mask(m_permutation.size()); | ||||
|         mask.fill(false); | ||||
|         int r = 0; | ||||
|         while(r < m_permutation.size()) | ||||
|         { | ||||
|           // search for the next seed | ||||
|           while(r<m_permutation.size() && mask[r]) r++; | ||||
|           if(r>=m_permutation.size()) | ||||
|             break; | ||||
|           // we got one, let's follow it until we are back to the seed | ||||
|           int k0 = r++; | ||||
|           int kPrev = k0; | ||||
|           mask.coeffRef(k0) = true; | ||||
|           for(int k=m_permutation.indices().coeff(k0); k!=k0; k=m_permutation.indices().coeff(k)) | ||||
|           { | ||||
|                   Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>(dst, k) | ||||
|             .swap(Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime> | ||||
|                        (dst,((Side==OnTheLeft) ^ Transposed) ? k0 : kPrev)); | ||||
|  | ||||
|             mask.coeffRef(k) = true; | ||||
|             kPrev = k; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|         for(int i = 0; i < n; ++i) | ||||
|         { | ||||
|           Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime> | ||||
|                (dst, ((Side==OnTheLeft) ^ Transposed) ? m_permutation.indices().coeff(i) : i) | ||||
|  | ||||
|           = | ||||
|  | ||||
|           Block<const MatrixTypeNestedCleaned,Side==OnTheLeft ? 1 : MatrixType::RowsAtCompileTime,Side==OnTheRight ? 1 : MatrixType::ColsAtCompileTime> | ||||
|                (m_matrix, ((Side==OnTheRight) ^ Transposed) ? m_permutation.indices().coeff(i) : i); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|   protected: | ||||
|     const PermutationType& m_permutation; | ||||
|     typename MatrixType::Nested m_matrix; | ||||
| }; | ||||
|  | ||||
| /* Template partial specialization for transposed/inverse permutations */ | ||||
|  | ||||
| template<typename Derived> | ||||
| struct traits<Transpose<PermutationBase<Derived> > > | ||||
|  : traits<Derived> | ||||
| {}; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| template<typename Derived> | ||||
| class Transpose<PermutationBase<Derived> > | ||||
|   : public EigenBase<Transpose<PermutationBase<Derived> > > | ||||
| { | ||||
|     typedef Derived PermutationType; | ||||
|     typedef typename PermutationType::IndicesType IndicesType; | ||||
|     typedef typename PermutationType::PlainPermutationType PlainPermutationType; | ||||
|   public: | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     typedef internal::traits<PermutationType> Traits; | ||||
|     typedef typename Derived::DenseMatrixType DenseMatrixType; | ||||
|     enum { | ||||
|       Flags = Traits::Flags, | ||||
|       CoeffReadCost = Traits::CoeffReadCost, | ||||
|       RowsAtCompileTime = Traits::RowsAtCompileTime, | ||||
|       ColsAtCompileTime = Traits::ColsAtCompileTime, | ||||
|       MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime, | ||||
|       MaxColsAtCompileTime = Traits::MaxColsAtCompileTime | ||||
|     }; | ||||
|     typedef typename Traits::Scalar Scalar; | ||||
|     #endif | ||||
|  | ||||
|     Transpose(const PermutationType& p) : m_permutation(p) {} | ||||
|  | ||||
|     inline int rows() const { return m_permutation.rows(); } | ||||
|     inline int cols() const { return m_permutation.cols(); } | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     template<typename DenseDerived> | ||||
|     void evalTo(MatrixBase<DenseDerived>& other) const | ||||
|     { | ||||
|       other.setZero(); | ||||
|       for (int i=0; i<rows();++i) | ||||
|         other.coeffRef(i, m_permutation.indices().coeff(i)) = typename DenseDerived::Scalar(1); | ||||
|     } | ||||
|     #endif | ||||
|  | ||||
|     /** \return the equivalent permutation matrix */ | ||||
|     PlainPermutationType eval() const { return *this; } | ||||
|  | ||||
|     DenseMatrixType toDenseMatrix() const { return *this; } | ||||
|  | ||||
|     /** \returns the matrix with the inverse permutation applied to the columns. | ||||
|       */ | ||||
|     template<typename OtherDerived> friend | ||||
|     inline const internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheRight, true> | ||||
|     operator*(const MatrixBase<OtherDerived>& matrix, const Transpose& trPerm) | ||||
|     { | ||||
|       return internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheRight, true>(trPerm.m_permutation, matrix.derived()); | ||||
|     } | ||||
|  | ||||
|     /** \returns the matrix with the inverse permutation applied to the rows. | ||||
|       */ | ||||
|     template<typename OtherDerived> | ||||
|     inline const internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheLeft, true> | ||||
|     operator*(const MatrixBase<OtherDerived>& matrix) const | ||||
|     { | ||||
|       return internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheLeft, true>(m_permutation, matrix.derived()); | ||||
|     } | ||||
|  | ||||
|     const PermutationType& nestedPermutation() const { return m_permutation; } | ||||
|  | ||||
|   protected: | ||||
|     const PermutationType& m_permutation; | ||||
| }; | ||||
|  | ||||
| template<typename Derived> | ||||
| const PermutationWrapper<const Derived> MatrixBase<Derived>::asPermutation() const | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_PERMUTATIONMATRIX_H | ||||
							
								
								
									
										768
									
								
								latan/Eigen/src/Core/PlainObjectBase.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										768
									
								
								latan/Eigen/src/Core/PlainObjectBase.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,768 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_DENSESTORAGEBASE_H | ||||
| #define EIGEN_DENSESTORAGEBASE_H | ||||
|  | ||||
| #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO | ||||
| # define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=Scalar(0); | ||||
| #else | ||||
| # define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED | ||||
| #endif | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| 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; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /** \class PlainObjectBase | ||||
|   * \brief %Dense storage base class for matrices and arrays. | ||||
|   * | ||||
|   * This class can be extended with the help of the plugin mechanism described on the page | ||||
|   * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_PLAINOBJECTBASE_PLUGIN. | ||||
|   * | ||||
|   * \sa \ref TopicClassHierarchy | ||||
|   */ | ||||
| #ifdef EIGEN_PARSED_BY_DOXYGEN | ||||
| namespace internal { | ||||
|  | ||||
| // this is a warkaround to doxygen not being able to understand the inheritence logic | ||||
| // when it is hidden by the dense_xpr_base helper struct. | ||||
| template<typename Derived> struct dense_xpr_base_dispatcher_for_doxygen;// : public MatrixBase<Derived> {}; | ||||
| /** This class is just a workaround for Doxygen and it does not not actually exist. */ | ||||
| template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> | ||||
| struct dense_xpr_base_dispatcher_for_doxygen<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > | ||||
|     : public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {}; | ||||
| /** This class is just a workaround for Doxygen and it does not not actually exist. */ | ||||
| template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> | ||||
| struct dense_xpr_base_dispatcher_for_doxygen<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > | ||||
|     : public ArrayBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {}; | ||||
|  | ||||
| } // namespace internal | ||||
|  | ||||
| template<typename Derived> | ||||
| class PlainObjectBase : public internal::dense_xpr_base_dispatcher_for_doxygen<Derived> | ||||
| #else | ||||
| template<typename Derived> | ||||
| class PlainObjectBase : public internal::dense_xpr_base<Derived>::type | ||||
| #endif | ||||
| { | ||||
|   public: | ||||
|     enum { Options = internal::traits<Derived>::Options }; | ||||
|     typedef typename internal::dense_xpr_base<Derived>::type Base; | ||||
|  | ||||
|     typedef typename internal::traits<Derived>::StorageKind StorageKind; | ||||
|     typedef typename internal::traits<Derived>::Index Index; | ||||
|     typedef typename internal::traits<Derived>::Scalar Scalar; | ||||
|     typedef typename internal::packet_traits<Scalar>::type PacketScalar; | ||||
|     typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|     typedef Derived DenseType; | ||||
|  | ||||
|     using Base::RowsAtCompileTime; | ||||
|     using Base::ColsAtCompileTime; | ||||
|     using Base::SizeAtCompileTime; | ||||
|     using Base::MaxRowsAtCompileTime; | ||||
|     using Base::MaxColsAtCompileTime; | ||||
|     using Base::MaxSizeAtCompileTime; | ||||
|     using Base::IsVectorAtCompileTime; | ||||
|     using Base::Flags; | ||||
|  | ||||
|     template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map; | ||||
|     friend  class Eigen::Map<Derived, Unaligned>; | ||||
|     typedef Eigen::Map<Derived, Unaligned>  MapType; | ||||
|     friend  class Eigen::Map<const Derived, Unaligned>; | ||||
|     typedef const Eigen::Map<const Derived, Unaligned> ConstMapType; | ||||
|     friend  class Eigen::Map<Derived, Aligned>; | ||||
|     typedef Eigen::Map<Derived, Aligned> AlignedMapType; | ||||
|     friend  class Eigen::Map<const Derived, Aligned>; | ||||
|     typedef const Eigen::Map<const Derived, Aligned> ConstAlignedMapType; | ||||
|     template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> 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 = SizeAtCompileTime != Dynamic && (internal::traits<Derived>::Flags & AlignedBit) != 0 }; | ||||
|     EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) | ||||
|  | ||||
|     Base& base() { return *static_cast<Base*>(this); } | ||||
|     const Base& base() const { return *static_cast<const Base*>(this); } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); } | ||||
|     EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE const Scalar& coeff(Index row, Index col) const | ||||
|     { | ||||
|       if(Flags & RowMajorBit) | ||||
|         return m_storage.data()[col + row * m_storage.cols()]; | ||||
|       else // column-major | ||||
|         return m_storage.data()[row + col * m_storage.rows()]; | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const | ||||
|     { | ||||
|       return m_storage.data()[index]; | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col) | ||||
|     { | ||||
|       if(Flags & RowMajorBit) | ||||
|         return m_storage.data()[col + row * m_storage.cols()]; | ||||
|       else // column-major | ||||
|         return m_storage.data()[row + col * m_storage.rows()]; | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) | ||||
|     { | ||||
|       return m_storage.data()[index]; | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE const Scalar& coeffRef(Index row, Index col) const | ||||
|     { | ||||
|       if(Flags & RowMajorBit) | ||||
|         return m_storage.data()[col + row * m_storage.cols()]; | ||||
|       else // column-major | ||||
|         return m_storage.data()[row + col * m_storage.rows()]; | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const | ||||
|     { | ||||
|       return m_storage.data()[index]; | ||||
|     } | ||||
|  | ||||
|     /** \internal */ | ||||
|     template<int LoadMode> | ||||
|     EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const | ||||
|     { | ||||
|       return internal::ploadt<PacketScalar, LoadMode> | ||||
|                (m_storage.data() + (Flags & RowMajorBit | ||||
|                                    ? col + row * m_storage.cols() | ||||
|                                    : row + col * m_storage.rows())); | ||||
|     } | ||||
|  | ||||
|     /** \internal */ | ||||
|     template<int LoadMode> | ||||
|     EIGEN_STRONG_INLINE PacketScalar packet(Index index) const | ||||
|     { | ||||
|       return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index); | ||||
|     } | ||||
|  | ||||
|     /** \internal */ | ||||
|     template<int StoreMode> | ||||
|     EIGEN_STRONG_INLINE void writePacket(Index row, Index col, const PacketScalar& x) | ||||
|     { | ||||
|       internal::pstoret<Scalar, PacketScalar, StoreMode> | ||||
|               (m_storage.data() + (Flags & RowMajorBit | ||||
|                                    ? col + row * m_storage.cols() | ||||
|                                    : row + col * m_storage.rows()), x); | ||||
|     } | ||||
|  | ||||
|     /** \internal */ | ||||
|     template<int StoreMode> | ||||
|     EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& x) | ||||
|     { | ||||
|       internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, x); | ||||
|     } | ||||
|  | ||||
|     /** \returns a const pointer to the data array of this matrix */ | ||||
|     EIGEN_STRONG_INLINE const Scalar *data() const | ||||
|     { return m_storage.data(); } | ||||
|  | ||||
|     /** \returns a pointer to the data array of this matrix */ | ||||
|     EIGEN_STRONG_INLINE Scalar *data() | ||||
|     { return m_storage.data(); } | ||||
|  | ||||
|     /** Resizes \c *this to a \a rows x \a cols matrix. | ||||
|       * | ||||
|       * This method is intended for dynamic-size matrices, although it is legal to call it on any | ||||
|       * matrix as long as fixed dimensions are left unchanged. If you only want to change the number | ||||
|       * of rows and/or of columns, you can use resize(NoChange_t, Index), resize(Index, NoChange_t). | ||||
|       * | ||||
|       * If the current number of coefficients of \c *this exactly matches the | ||||
|       * product \a rows * \a cols, then no memory allocation is performed and | ||||
|       * the current values are left unchanged. In all other cases, including | ||||
|       * shrinking, the data is reallocated and all previous values are lost. | ||||
|       * | ||||
|       * Example: \include Matrix_resize_int_int.cpp | ||||
|       * Output: \verbinclude Matrix_resize_int_int.out | ||||
|       * | ||||
|       * \sa resize(Index) for vectors, resize(NoChange_t, Index), resize(Index, NoChange_t) | ||||
|       */ | ||||
|     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 | ||||
|     } | ||||
|  | ||||
|     /** Resizes \c *this to a vector of length \a size | ||||
|       * | ||||
|       * \only_for_vectors. This method does not work for | ||||
|       * partially dynamic matrices when the static dimension is anything other | ||||
|       * than 1. For example it will not work with Matrix<double, 2, Dynamic>. | ||||
|       * | ||||
|       * Example: \include Matrix_resize_int.cpp | ||||
|       * Output: \verbinclude Matrix_resize_int.out | ||||
|       * | ||||
|       * \sa resize(Index,Index), resize(NoChange_t, Index), resize(Index, NoChange_t) | ||||
|       */ | ||||
|     inline void resize(Index size) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase) | ||||
|       eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size); | ||||
|       #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO | ||||
|         bool size_changed = size != this->size(); | ||||
|       #endif | ||||
|       if(RowsAtCompileTime == 1) | ||||
|         m_storage.resize(size, 1, size); | ||||
|       else | ||||
|         m_storage.resize(size, size, 1); | ||||
|       #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO | ||||
|         if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED | ||||
|       #endif | ||||
|     } | ||||
|  | ||||
|     /** Resizes the matrix, changing only the number of columns. For the parameter of type NoChange_t, just pass the special value \c NoChange | ||||
|       * as in the example below. | ||||
|       * | ||||
|       * Example: \include Matrix_resize_NoChange_int.cpp | ||||
|       * Output: \verbinclude Matrix_resize_NoChange_int.out | ||||
|       * | ||||
|       * \sa resize(Index,Index) | ||||
|       */ | ||||
|     inline void resize(NoChange_t, Index cols) | ||||
|     { | ||||
|       resize(rows(), cols); | ||||
|     } | ||||
|  | ||||
|     /** Resizes the matrix, changing only the number of rows. For the parameter of type NoChange_t, just pass the special value \c NoChange | ||||
|       * as in the example below. | ||||
|       * | ||||
|       * Example: \include Matrix_resize_int_NoChange.cpp | ||||
|       * Output: \verbinclude Matrix_resize_int_NoChange.out | ||||
|       * | ||||
|       * \sa resize(Index,Index) | ||||
|       */ | ||||
|     inline void resize(Index rows, NoChange_t) | ||||
|     { | ||||
|       resize(rows, cols()); | ||||
|     } | ||||
|  | ||||
|     /** Resizes \c *this to have the same dimensions as \a other. | ||||
|       * Takes care of doing all the checking that's needed. | ||||
|       * | ||||
|       * Note that copying a row-vector into a vector (and conversely) is allowed. | ||||
|       * The resizing, if any, is then done in the appropriate way so that row-vectors | ||||
|       * remain row-vectors and vectors remain vectors. | ||||
|       */ | ||||
|     template<typename OtherDerived> | ||||
|     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) | ||||
|       { | ||||
|         eigen_assert(other.rows() == 1 || other.cols() == 1); | ||||
|         resize(1, othersize); | ||||
|       } | ||||
|       else if(ColsAtCompileTime == 1) | ||||
|       { | ||||
|         eigen_assert(other.rows() == 1 || other.cols() == 1); | ||||
|         resize(othersize, 1); | ||||
|       } | ||||
|       else resize(other.rows(), other.cols()); | ||||
|     } | ||||
|  | ||||
|     /** Resizes the matrix to \a rows x \a cols while leaving old values untouched. | ||||
|       * | ||||
|       * The method is intended for matrices of dynamic size. If you only want to change the number | ||||
|       * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or | ||||
|       * conservativeResize(Index, NoChange_t). | ||||
|       * | ||||
|       * Matrices are resized relative to the top-left element. In case values need to be  | ||||
|       * appended to the matrix they will be uninitialized. | ||||
|       */ | ||||
|     EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols) | ||||
|     { | ||||
|       internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols); | ||||
|     } | ||||
|  | ||||
|     /** Resizes the matrix to \a rows x \a cols while leaving old values untouched. | ||||
|       * | ||||
|       * As opposed to conservativeResize(Index rows, Index cols), this version leaves | ||||
|       * the number of columns unchanged. | ||||
|       * | ||||
|       * In case the matrix is growing, new rows will be uninitialized. | ||||
|       */ | ||||
|     EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t) | ||||
|     { | ||||
|       // Note: see the comment in conservativeResize(Index,Index) | ||||
|       conservativeResize(rows, cols()); | ||||
|     } | ||||
|  | ||||
|     /** Resizes the matrix to \a rows x \a cols while leaving old values untouched. | ||||
|       * | ||||
|       * As opposed to conservativeResize(Index rows, Index cols), this version leaves | ||||
|       * the number of rows unchanged. | ||||
|       * | ||||
|       * In case the matrix is growing, new columns will be uninitialized. | ||||
|       */ | ||||
|     EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols) | ||||
|     { | ||||
|       // Note: see the comment in conservativeResize(Index,Index) | ||||
|       conservativeResize(rows(), cols); | ||||
|     } | ||||
|  | ||||
|     /** Resizes the vector to \a size while retaining old values. | ||||
|       * | ||||
|       * \only_for_vectors. This method does not work for | ||||
|       * partially dynamic matrices when the static dimension is anything other | ||||
|       * than 1. For example it will not work with Matrix<double, 2, Dynamic>. | ||||
|       * | ||||
|       * When values are appended, they will be uninitialized. | ||||
|       */ | ||||
|     EIGEN_STRONG_INLINE void conservativeResize(Index size) | ||||
|     { | ||||
|       internal::conservative_resize_like_impl<Derived>::run(*this, size); | ||||
|     } | ||||
|  | ||||
|     /** Resizes the matrix to \a rows x \a cols of \c other, while leaving old values untouched. | ||||
|       * | ||||
|       * The method is intended for matrices of dynamic size. If you only want to change the number | ||||
|       * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or | ||||
|       * conservativeResize(Index, NoChange_t). | ||||
|       * | ||||
|       * Matrices are resized relative to the top-left element. In case values need to be  | ||||
|       * appended to the matrix they will copied from \c other. | ||||
|       */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other); | ||||
|     } | ||||
|  | ||||
|     /** This is a special case of the templated operator=. Its purpose is to | ||||
|       * prevent a default operator= from hiding the templated operator=. | ||||
|       */ | ||||
|     EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other) | ||||
|     { | ||||
|       return _set(other); | ||||
|     } | ||||
|  | ||||
|     /** \sa MatrixBase::lazyAssign() */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       _resize_to_match(other); | ||||
|       return Base::lazyAssign(other.derived()); | ||||
|     } | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func) | ||||
|     { | ||||
|       resize(func.rows(), func.cols()); | ||||
|       return Base::operator=(func); | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE explicit PlainObjectBase() : m_storage() | ||||
|     { | ||||
| //       _check_template_params(); | ||||
| //       EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED | ||||
|     } | ||||
|  | ||||
| #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     // FIXME is it still needed ? | ||||
|     /** \internal */ | ||||
|     PlainObjectBase(internal::constructor_without_unaligned_array_assert) | ||||
|       : m_storage(internal::constructor_without_unaligned_array_assert()) | ||||
|     { | ||||
| //       _check_template_params(); EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|     EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols) | ||||
|       : m_storage(size, rows, cols) | ||||
|     { | ||||
| //       _check_template_params(); | ||||
| //       EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED | ||||
|     } | ||||
|  | ||||
|     /** \copydoc MatrixBase::operator=(const EigenBase<OtherDerived>&) | ||||
|       */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other) | ||||
|     { | ||||
|       _resize_to_match(other); | ||||
|       Base::operator=(other.derived()); | ||||
|       return this->derived(); | ||||
|     } | ||||
|  | ||||
|     /** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other) | ||||
|       : 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()); | ||||
|     } | ||||
|  | ||||
|     /** \name Map | ||||
|       * These are convenience functions returning Map objects. The Map() static functions return unaligned Map objects, | ||||
|       * while the AlignedMap() functions return aligned Map objects and thus should be called only with 16-byte-aligned | ||||
|       * \a data pointers. | ||||
|       * | ||||
|       * \see class Map | ||||
|       */ | ||||
|     //@{ | ||||
|     static inline ConstMapType Map(const Scalar* data) | ||||
|     { return ConstMapType(data); } | ||||
|     static inline MapType Map(Scalar* data) | ||||
|     { return MapType(data); } | ||||
|     static inline ConstMapType Map(const Scalar* data, Index size) | ||||
|     { return ConstMapType(data, size); } | ||||
|     static inline MapType Map(Scalar* data, Index size) | ||||
|     { return MapType(data, size); } | ||||
|     static inline ConstMapType Map(const Scalar* data, Index rows, Index cols) | ||||
|     { return ConstMapType(data, rows, cols); } | ||||
|     static inline MapType Map(Scalar* data, Index rows, Index cols) | ||||
|     { return MapType(data, rows, cols); } | ||||
|  | ||||
|     static inline ConstAlignedMapType MapAligned(const Scalar* data) | ||||
|     { return ConstAlignedMapType(data); } | ||||
|     static inline AlignedMapType MapAligned(Scalar* data) | ||||
|     { return AlignedMapType(data); } | ||||
|     static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size) | ||||
|     { return ConstAlignedMapType(data, size); } | ||||
|     static inline AlignedMapType MapAligned(Scalar* data, Index size) | ||||
|     { return AlignedMapType(data, size); } | ||||
|     static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols) | ||||
|     { return ConstAlignedMapType(data, rows, cols); } | ||||
|     static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols) | ||||
|     { return AlignedMapType(data, rows, cols); } | ||||
|  | ||||
|     template<int Outer, int Inner> | ||||
|     static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, const Stride<Outer, Inner>& stride) | ||||
|     { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, stride); } | ||||
|     template<int Outer, int Inner> | ||||
|     static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, const Stride<Outer, Inner>& stride) | ||||
|     { return typename StridedMapType<Stride<Outer, Inner> >::type(data, stride); } | ||||
|     template<int Outer, int Inner> | ||||
|     static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index size, const Stride<Outer, Inner>& stride) | ||||
|     { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, size, stride); } | ||||
|     template<int Outer, int Inner> | ||||
|     static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index size, const Stride<Outer, Inner>& stride) | ||||
|     { return typename StridedMapType<Stride<Outer, Inner> >::type(data, size, stride); } | ||||
|     template<int Outer, int Inner> | ||||
|     static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) | ||||
|     { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); } | ||||
|     template<int Outer, int Inner> | ||||
|     static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) | ||||
|     { return typename StridedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); } | ||||
|  | ||||
|     template<int Outer, int Inner> | ||||
|     static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, const Stride<Outer, Inner>& stride) | ||||
|     { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, stride); } | ||||
|     template<int Outer, int Inner> | ||||
|     static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, const Stride<Outer, Inner>& stride) | ||||
|     { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, stride); } | ||||
|     template<int Outer, int Inner> | ||||
|     static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index size, const Stride<Outer, Inner>& stride) | ||||
|     { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); } | ||||
|     template<int Outer, int Inner> | ||||
|     static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index size, const Stride<Outer, Inner>& stride) | ||||
|     { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); } | ||||
|     template<int Outer, int Inner> | ||||
|     static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) | ||||
|     { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); } | ||||
|     template<int Outer, int Inner> | ||||
|     static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) | ||||
|     { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); } | ||||
|     //@} | ||||
|  | ||||
|     using Base::setConstant; | ||||
|     Derived& setConstant(Index size, const Scalar& value); | ||||
|     Derived& setConstant(Index rows, Index cols, const Scalar& value); | ||||
|  | ||||
|     using Base::setZero; | ||||
|     Derived& setZero(Index size); | ||||
|     Derived& setZero(Index rows, Index cols); | ||||
|  | ||||
|     using Base::setOnes; | ||||
|     Derived& setOnes(Index size); | ||||
|     Derived& setOnes(Index rows, Index cols); | ||||
|  | ||||
|     using Base::setRandom; | ||||
|     Derived& setRandom(Index size); | ||||
|     Derived& setRandom(Index rows, Index cols); | ||||
|  | ||||
|     #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN | ||||
|     #include EIGEN_PLAINOBJECTBASE_PLUGIN | ||||
|     #endif | ||||
|  | ||||
|   protected: | ||||
|     /** \internal Resizes *this in preparation for assigning \a other to it. | ||||
|       * Takes care of doing all the checking that's needed. | ||||
|       * | ||||
|       * Note that copying a row-vector into a vector (and conversely) is allowed. | ||||
|       * The resizing, if any, is then done in the appropriate way so that row-vectors | ||||
|       * remain row-vectors and vectors remain vectors. | ||||
|       */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other) | ||||
|     { | ||||
|       #ifdef EIGEN_NO_AUTOMATIC_RESIZING | ||||
|       eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size()) | ||||
|                  : (rows() == other.rows() && cols() == other.cols()))) | ||||
|         && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined"); | ||||
|       EIGEN_ONLY_USED_FOR_DEBUG(other); | ||||
|       #else | ||||
|       resizeLike(other); | ||||
|       #endif | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|       * \brief Copies the value of the expression \a other into \c *this with automatic resizing. | ||||
|       * | ||||
|       * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), | ||||
|       * it will be initialized. | ||||
|       * | ||||
|       * Note that copying a row-vector into a vector (and conversely) is allowed. | ||||
|       * The resizing, if any, is then done in the appropriate way so that row-vectors | ||||
|       * remain row-vectors and vectors remain vectors. | ||||
|       * | ||||
|       * \sa operator=(const MatrixBase<OtherDerived>&), _set_noalias() | ||||
|       * | ||||
|       * \internal | ||||
|       */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       _set_selector(other.derived(), typename internal::conditional<static_cast<bool>(int(OtherDerived::Flags) & EvalBeforeAssigningBit), internal::true_type, internal::false_type>::type()); | ||||
|       return this->derived(); | ||||
|     } | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::true_type&) { _set_noalias(other.eval()); } | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::false_type&) { _set_noalias(other); } | ||||
|  | ||||
|     /** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which | ||||
|       * is the case when creating a new matrix) so one can enforce lazy evaluation. | ||||
|       * | ||||
|       * \sa operator=(const MatrixBase<OtherDerived>&), _set() | ||||
|       */ | ||||
|     template<typename OtherDerived> | ||||
|     EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       // I don't think we need this resize call since the lazyAssign will anyways resize | ||||
|       // and lazyAssign will be called by the assign selector. | ||||
|       //_resize_to_match(other); | ||||
|       // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because | ||||
|       // it wouldn't allow to copy a row-vector into a column-vector. | ||||
|       return internal::assign_selector<Derived,OtherDerived,false>::run(this->derived(), other.derived()); | ||||
|     } | ||||
|  | ||||
|     template<typename T0, typename T1> | ||||
|     EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) && | ||||
|                           bool(NumTraits<T1>::IsInteger), | ||||
|                           FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED) | ||||
|       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 | ||||
|     } | ||||
|     template<typename T0, typename T1> | ||||
|     EIGEN_STRONG_INLINE void _init2(const Scalar& x, const Scalar& y, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2) | ||||
|       m_storage.data()[0] = x; | ||||
|       m_storage.data()[1] = y; | ||||
|     } | ||||
|  | ||||
|     template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> | ||||
|     friend struct internal::matrix_swap_impl; | ||||
|  | ||||
|     /** \internal generic implementation of swap for dense storage since for dynamic-sized matrices of same type it is enough to swap the | ||||
|       * data pointers. | ||||
|       */ | ||||
|     template<typename OtherDerived> | ||||
|     void _swap(DenseBase<OtherDerived> const & other) | ||||
|     { | ||||
|       enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic }; | ||||
|       internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.const_cast_derived()); | ||||
|     } | ||||
|  | ||||
|   public: | ||||
| #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     static EIGEN_STRONG_INLINE void _check_template_params() | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor) | ||||
|                         && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0) | ||||
|                         && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0)) | ||||
|                         && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0)) | ||||
|                         && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0)) | ||||
|                         && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0)) | ||||
|                         && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic) | ||||
|                         && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic) | ||||
|                         && (Options & (DontAlign|RowMajor)) == Options), | ||||
|         INVALID_MATRIX_TEMPLATE_PARAMETERS) | ||||
|     } | ||||
| #endif | ||||
|  | ||||
| private: | ||||
|     enum { ThisConstantIsPrivateInPlainObjectBase }; | ||||
| }; | ||||
|  | ||||
| template <typename Derived, typename OtherDerived, bool IsVector> | ||||
| struct internal::conservative_resize_like_impl | ||||
| { | ||||
|   typedef typename Derived::Index Index; | ||||
|   static void run(DenseBase<Derived>& _this, Index rows, Index cols) | ||||
|   { | ||||
|     if (_this.rows() == rows && _this.cols() == cols) return; | ||||
|     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived) | ||||
|  | ||||
|     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 | ||||
|     { | ||||
|       // The storage order does not allow us to use reallocation. | ||||
|       typename Derived::PlainObject tmp(rows,cols); | ||||
|       const Index common_rows = (std::min)(rows, _this.rows()); | ||||
|       const Index common_cols = (std::min)(cols, _this.cols()); | ||||
|       tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols); | ||||
|       _this.derived().swap(tmp); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other) | ||||
|   { | ||||
|     if (_this.rows() == other.rows() && _this.cols() == other.cols()) return; | ||||
|  | ||||
|     // Note: Here is space for improvement. Basically, for conservativeResize(Index,Index), | ||||
|     // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the | ||||
|     // dimensions is dynamic, one could use either conservativeResize(Index rows, NoChange_t) or | ||||
|     // conservativeResize(NoChange_t, Index cols). For these methods new static asserts like | ||||
|     // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good. | ||||
|     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived) | ||||
|     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived) | ||||
|  | ||||
|     if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows | ||||
|          (!Derived::IsRowMajor && _this.rows() == other.rows()) )  // column-major and we change only the number of columns | ||||
|     { | ||||
|       const Index new_rows = other.rows() - _this.rows(); | ||||
|       const Index new_cols = other.cols() - _this.cols(); | ||||
|       _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols()); | ||||
|       if (new_rows>0) | ||||
|         _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows); | ||||
|       else if (new_cols>0) | ||||
|         _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|       // The storage order does not allow us to use reallocation. | ||||
|       typename Derived::PlainObject tmp(other); | ||||
|       const Index common_rows = (std::min)(tmp.rows(), _this.rows()); | ||||
|       const Index common_cols = (std::min)(tmp.cols(), _this.cols()); | ||||
|       tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols); | ||||
|       _this.derived().swap(tmp); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template <typename Derived, typename OtherDerived> | ||||
| struct conservative_resize_like_impl<Derived,OtherDerived,true> | ||||
| { | ||||
|   typedef typename Derived::Index Index; | ||||
|   static void run(DenseBase<Derived>& _this, Index size) | ||||
|   { | ||||
|     const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size; | ||||
|     const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1; | ||||
|     _this.derived().m_storage.conservativeResize(size,new_rows,new_cols); | ||||
|   } | ||||
|  | ||||
|   static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other) | ||||
|   { | ||||
|     if (_this.rows() == other.rows() && _this.cols() == other.cols()) return; | ||||
|  | ||||
|     const Index num_new_elements = other.size() - _this.size(); | ||||
|  | ||||
|     const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows(); | ||||
|     const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1; | ||||
|     _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols); | ||||
|  | ||||
|     if (num_new_elements > 0) | ||||
|       _this.tail(num_new_elements) = other.tail(num_new_elements); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> | ||||
| struct matrix_swap_impl | ||||
| { | ||||
|   static inline void run(MatrixTypeA& a, MatrixTypeB& b) | ||||
|   { | ||||
|     a.base().swap(b); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename MatrixTypeA, typename MatrixTypeB> | ||||
| struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true> | ||||
| { | ||||
|   static inline void run(MatrixTypeA& a, MatrixTypeB& b) | ||||
|   { | ||||
|     static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_DENSESTORAGEBASE_H | ||||
							
								
								
									
										98
									
								
								latan/Eigen/src/Core/Product.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								latan/Eigen/src/Core/Product.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla Public | ||||
| // License, v. 2.0. If a copy of the MPL was not distributed with this | ||||
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_PRODUCT_H | ||||
| #define EIGEN_PRODUCT_H | ||||
|  | ||||
| template<typename Lhs, typename Rhs> class Product; | ||||
| template<typename Lhs, typename Rhs, typename StorageKind> class ProductImpl; | ||||
|  | ||||
| /** \class Product | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Expression of the product of two arbitrary matrices or vectors | ||||
|   * | ||||
|   * \param Lhs the type of the left-hand side expression | ||||
|   * \param Rhs the type of the right-hand side expression | ||||
|   * | ||||
|   * This class represents an expression of the product of two arbitrary matrices. | ||||
|   * | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename Lhs, typename Rhs> | ||||
| struct traits<Product<Lhs, Rhs> > | ||||
| { | ||||
|   typedef MatrixXpr XprKind; | ||||
|   typedef typename remove_all<Lhs>::type LhsCleaned; | ||||
|   typedef typename remove_all<Rhs>::type RhsCleaned; | ||||
|   typedef typename scalar_product_traits<typename traits<LhsCleaned>::Scalar, typename traits<RhsCleaned>::Scalar>::ReturnType Scalar; | ||||
|   typedef typename promote_storage_type<typename traits<LhsCleaned>::StorageKind, | ||||
|                                         typename traits<RhsCleaned>::StorageKind>::ret StorageKind; | ||||
|   typedef typename promote_index_type<typename traits<LhsCleaned>::Index, | ||||
|                                       typename traits<RhsCleaned>::Index>::type Index; | ||||
|   enum { | ||||
|     RowsAtCompileTime = LhsCleaned::RowsAtCompileTime, | ||||
|     ColsAtCompileTime = RhsCleaned::ColsAtCompileTime, | ||||
|     MaxRowsAtCompileTime = LhsCleaned::MaxRowsAtCompileTime, | ||||
|     MaxColsAtCompileTime = RhsCleaned::MaxColsAtCompileTime, | ||||
|     Flags = (MaxRowsAtCompileTime==1 ? RowMajorBit : 0), // TODO should be no storage order | ||||
|     CoeffReadCost = 0 // TODO CoeffReadCost should not be part of the expression traits | ||||
|   }; | ||||
| }; | ||||
| } // end namespace internal | ||||
|  | ||||
|  | ||||
| template<typename Lhs, typename Rhs> | ||||
| class Product : public ProductImpl<Lhs,Rhs,typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind, | ||||
|                                                                             typename internal::traits<Rhs>::StorageKind>::ret> | ||||
| { | ||||
|   public: | ||||
|      | ||||
|     typedef typename ProductImpl< | ||||
|         Lhs, Rhs, | ||||
|         typename internal::promote_storage_type<typename Lhs::StorageKind, | ||||
|                                                 typename Rhs::StorageKind>::ret>::Base Base; | ||||
|     EIGEN_GENERIC_PUBLIC_INTERFACE(Product) | ||||
|  | ||||
|     typedef typename Lhs::Nested LhsNested; | ||||
|     typedef typename Rhs::Nested RhsNested; | ||||
|     typedef typename internal::remove_all<LhsNested>::type LhsNestedCleaned; | ||||
|     typedef typename internal::remove_all<RhsNested>::type RhsNestedCleaned; | ||||
|  | ||||
|     Product(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs) | ||||
|     { | ||||
|       eigen_assert(lhs.cols() == rhs.rows() | ||||
|         && "invalid matrix product" | ||||
|         && "if you wanted a coeff-wise or a dot product use the respective explicit functions"); | ||||
|     } | ||||
|  | ||||
|     inline Index rows() const { return m_lhs.rows(); } | ||||
|     inline Index cols() const { return m_rhs.cols(); } | ||||
|  | ||||
|     const LhsNestedCleaned& lhs() const { return m_lhs; } | ||||
|     const RhsNestedCleaned& rhs() const { return m_rhs; } | ||||
|  | ||||
|   protected: | ||||
|  | ||||
|     const LhsNested m_lhs; | ||||
|     const RhsNested m_rhs; | ||||
| }; | ||||
|  | ||||
| template<typename Lhs, typename Rhs> | ||||
| class ProductImpl<Lhs,Rhs,Dense> : public internal::dense_xpr_base<Product<Lhs,Rhs> >::type | ||||
| { | ||||
|     typedef Product<Lhs, Rhs> Derived; | ||||
|   public: | ||||
|  | ||||
|     typedef typename internal::dense_xpr_base<Product<Lhs, Rhs> >::type Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(Derived) | ||||
| }; | ||||
|  | ||||
| #endif // EIGEN_PRODUCT_H | ||||
							
								
								
									
										278
									
								
								latan/Eigen/src/Core/ProductBase.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										278
									
								
								latan/Eigen/src/Core/ProductBase.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,278 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_PRODUCTBASE_H | ||||
| #define EIGEN_PRODUCTBASE_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class ProductBase | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename Derived, typename _Lhs, typename _Rhs> | ||||
| struct traits<ProductBase<Derived,_Lhs,_Rhs> > | ||||
| { | ||||
|   typedef MatrixXpr XprKind; | ||||
|   typedef typename remove_all<_Lhs>::type Lhs; | ||||
|   typedef typename remove_all<_Rhs>::type Rhs; | ||||
|   typedef typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType Scalar; | ||||
|   typedef typename promote_storage_type<typename traits<Lhs>::StorageKind, | ||||
|                                            typename traits<Rhs>::StorageKind>::ret StorageKind; | ||||
|   typedef typename promote_index_type<typename traits<Lhs>::Index, | ||||
|                                          typename traits<Rhs>::Index>::type Index; | ||||
|   enum { | ||||
|     RowsAtCompileTime = traits<Lhs>::RowsAtCompileTime, | ||||
|     ColsAtCompileTime = traits<Rhs>::ColsAtCompileTime, | ||||
|     MaxRowsAtCompileTime = traits<Lhs>::MaxRowsAtCompileTime, | ||||
|     MaxColsAtCompileTime = traits<Rhs>::MaxColsAtCompileTime, | ||||
|     Flags = (MaxRowsAtCompileTime==1 ? RowMajorBit : 0) | ||||
|           | EvalBeforeNestingBit | EvalBeforeAssigningBit | NestByRefBit, | ||||
|                   // Note that EvalBeforeNestingBit and NestByRefBit | ||||
|                   // are not used in practice because nested is overloaded for products | ||||
|     CoeffReadCost = 0 // FIXME why is it needed ? | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| #define EIGEN_PRODUCT_PUBLIC_INTERFACE(Derived) \ | ||||
|   typedef ProductBase<Derived, Lhs, Rhs > Base; \ | ||||
|   EIGEN_DENSE_PUBLIC_INTERFACE(Derived) \ | ||||
|   typedef typename Base::LhsNested LhsNested; \ | ||||
|   typedef typename Base::_LhsNested _LhsNested; \ | ||||
|   typedef typename Base::LhsBlasTraits LhsBlasTraits; \ | ||||
|   typedef typename Base::ActualLhsType ActualLhsType; \ | ||||
|   typedef typename Base::_ActualLhsType _ActualLhsType; \ | ||||
|   typedef typename Base::RhsNested RhsNested; \ | ||||
|   typedef typename Base::_RhsNested _RhsNested; \ | ||||
|   typedef typename Base::RhsBlasTraits RhsBlasTraits; \ | ||||
|   typedef typename Base::ActualRhsType ActualRhsType; \ | ||||
|   typedef typename Base::_ActualRhsType _ActualRhsType; \ | ||||
|   using Base::m_lhs; \ | ||||
|   using Base::m_rhs; | ||||
|  | ||||
| template<typename Derived, typename Lhs, typename Rhs> | ||||
| class ProductBase : public MatrixBase<Derived> | ||||
| { | ||||
|   public: | ||||
|     typedef MatrixBase<Derived> Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(ProductBase) | ||||
|      | ||||
|     typedef typename Lhs::Nested LhsNested; | ||||
|     typedef typename internal::remove_all<LhsNested>::type _LhsNested; | ||||
|     typedef internal::blas_traits<_LhsNested> LhsBlasTraits; | ||||
|     typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType; | ||||
|     typedef typename internal::remove_all<ActualLhsType>::type _ActualLhsType; | ||||
|     typedef typename internal::traits<Lhs>::Scalar LhsScalar; | ||||
|  | ||||
|     typedef typename Rhs::Nested RhsNested; | ||||
|     typedef typename internal::remove_all<RhsNested>::type _RhsNested; | ||||
|     typedef internal::blas_traits<_RhsNested> RhsBlasTraits; | ||||
|     typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType; | ||||
|     typedef typename internal::remove_all<ActualRhsType>::type _ActualRhsType; | ||||
|     typedef typename internal::traits<Rhs>::Scalar RhsScalar; | ||||
|  | ||||
|     // Diagonal of a product: no need to evaluate the arguments because they are going to be evaluated only once | ||||
|     typedef CoeffBasedProduct<LhsNested, RhsNested, 0> FullyLazyCoeffBaseProductType; | ||||
|  | ||||
|   public: | ||||
|  | ||||
|     typedef typename Base::PlainObject PlainObject; | ||||
|  | ||||
|     ProductBase(const Lhs& lhs, const Rhs& rhs) | ||||
|       : m_lhs(lhs), m_rhs(rhs) | ||||
|     { | ||||
|       eigen_assert(lhs.cols() == rhs.rows() | ||||
|         && "invalid matrix product" | ||||
|         && "if you wanted a coeff-wise or a dot product use the respective explicit functions"); | ||||
|     } | ||||
|  | ||||
|     inline Index rows() const { return m_lhs.rows(); } | ||||
|     inline Index cols() const { return m_rhs.cols(); } | ||||
|  | ||||
|     template<typename Dest> | ||||
|     inline void evalTo(Dest& dst) const { dst.setZero(); scaleAndAddTo(dst,Scalar(1)); } | ||||
|  | ||||
|     template<typename Dest> | ||||
|     inline void addTo(Dest& dst) const { scaleAndAddTo(dst,Scalar(1)); } | ||||
|  | ||||
|     template<typename Dest> | ||||
|     inline void subTo(Dest& dst) const { scaleAndAddTo(dst,Scalar(-1)); } | ||||
|  | ||||
|     template<typename Dest> | ||||
|     inline void scaleAndAddTo(Dest& dst,Scalar alpha) const { derived().scaleAndAddTo(dst,alpha); } | ||||
|  | ||||
|     const _LhsNested& lhs() const { return m_lhs; } | ||||
|     const _RhsNested& rhs() const { return m_rhs; } | ||||
|  | ||||
|     // Implicit conversion to the nested type (trigger the evaluation of the product) | ||||
|     operator const PlainObject& () const | ||||
|     { | ||||
|       m_result.resize(m_lhs.rows(), m_rhs.cols()); | ||||
|       derived().evalTo(m_result); | ||||
|       return m_result; | ||||
|     } | ||||
|  | ||||
|     const Diagonal<const FullyLazyCoeffBaseProductType,0> diagonal() const | ||||
|     { return FullyLazyCoeffBaseProductType(m_lhs, m_rhs); } | ||||
|  | ||||
|     template<int Index> | ||||
|     const Diagonal<FullyLazyCoeffBaseProductType,Index> diagonal() const | ||||
|     { return FullyLazyCoeffBaseProductType(m_lhs, m_rhs); } | ||||
|  | ||||
|     const Diagonal<FullyLazyCoeffBaseProductType,Dynamic> diagonal(Index index) const | ||||
|     { return FullyLazyCoeffBaseProductType(m_lhs, m_rhs).diagonal(index); } | ||||
|  | ||||
|     // restrict coeff accessors to 1x1 expressions. No need to care about mutators here since this isnt a Lvalue expression | ||||
|     typename Base::CoeffReturnType coeff(Index row, Index col) const | ||||
|     { | ||||
| #ifdef EIGEN2_SUPPORT | ||||
|       return lhs().row(row).cwiseProduct(rhs().col(col).transpose()).sum(); | ||||
| #else | ||||
|       EIGEN_STATIC_ASSERT_SIZE_1x1(Derived) | ||||
|       eigen_assert(this->rows() == 1 && this->cols() == 1); | ||||
|       Matrix<Scalar,1,1> result = *this; | ||||
|       return result.coeff(row,col); | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     typename Base::CoeffReturnType coeff(Index i) const | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_SIZE_1x1(Derived) | ||||
|       eigen_assert(this->rows() == 1 && this->cols() == 1); | ||||
|       Matrix<Scalar,1,1> result = *this; | ||||
|       return result.coeff(i); | ||||
|     } | ||||
|  | ||||
|     const Scalar& coeffRef(Index row, Index col) const | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_SIZE_1x1(Derived) | ||||
|       eigen_assert(this->rows() == 1 && this->cols() == 1); | ||||
|       return derived().coeffRef(row,col); | ||||
|     } | ||||
|  | ||||
|     const Scalar& coeffRef(Index i) const | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_SIZE_1x1(Derived) | ||||
|       eigen_assert(this->rows() == 1 && this->cols() == 1); | ||||
|       return derived().coeffRef(i); | ||||
|     } | ||||
|  | ||||
|   protected: | ||||
|  | ||||
|     LhsNested m_lhs; | ||||
|     RhsNested m_rhs; | ||||
|  | ||||
|     mutable PlainObject m_result; | ||||
| }; | ||||
|  | ||||
| // here we need to overload the nested rule for products | ||||
| // such that the nested type is a const reference to a plain matrix | ||||
| namespace internal { | ||||
| template<typename Lhs, typename Rhs, int Mode, int N, typename PlainObject> | ||||
| struct nested<GeneralProduct<Lhs,Rhs,Mode>, N, PlainObject> | ||||
| { | ||||
|   typedef PlainObject const& type; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename NestedProduct> | ||||
| class ScaledProduct; | ||||
|  | ||||
| // Note that these two operator* functions are not defined as member | ||||
| // functions of ProductBase, because, otherwise we would have to | ||||
| // define all overloads defined in MatrixBase. Furthermore, Using | ||||
| // "using Base::operator*" would not work with MSVC. | ||||
| // | ||||
| // Also note that here we accept any compatible scalar types | ||||
| template<typename Derived,typename Lhs,typename Rhs> | ||||
| const ScaledProduct<Derived> | ||||
| operator*(const ProductBase<Derived,Lhs,Rhs>& prod, typename Derived::Scalar x) | ||||
| { return ScaledProduct<Derived>(prod.derived(), x); } | ||||
|  | ||||
| template<typename Derived,typename Lhs,typename Rhs> | ||||
| typename internal::enable_if<!internal::is_same<typename Derived::Scalar,typename Derived::RealScalar>::value, | ||||
|                       const ScaledProduct<Derived> >::type | ||||
| operator*(const ProductBase<Derived,Lhs,Rhs>& prod, typename Derived::RealScalar x) | ||||
| { return ScaledProduct<Derived>(prod.derived(), x); } | ||||
|  | ||||
|  | ||||
| template<typename Derived,typename Lhs,typename Rhs> | ||||
| const ScaledProduct<Derived> | ||||
| operator*(typename Derived::Scalar x,const ProductBase<Derived,Lhs,Rhs>& prod) | ||||
| { return ScaledProduct<Derived>(prod.derived(), x); } | ||||
|  | ||||
| template<typename Derived,typename Lhs,typename Rhs> | ||||
| typename internal::enable_if<!internal::is_same<typename Derived::Scalar,typename Derived::RealScalar>::value, | ||||
|                       const ScaledProduct<Derived> >::type | ||||
| operator*(typename Derived::RealScalar x,const ProductBase<Derived,Lhs,Rhs>& prod) | ||||
| { return ScaledProduct<Derived>(prod.derived(), x); } | ||||
|  | ||||
| namespace internal { | ||||
| template<typename NestedProduct> | ||||
| struct traits<ScaledProduct<NestedProduct> > | ||||
|  : traits<ProductBase<ScaledProduct<NestedProduct>, | ||||
|                          typename NestedProduct::_LhsNested, | ||||
|                          typename NestedProduct::_RhsNested> > | ||||
| { | ||||
|   typedef typename traits<NestedProduct>::StorageKind StorageKind; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename NestedProduct> | ||||
| class ScaledProduct | ||||
|   : public ProductBase<ScaledProduct<NestedProduct>, | ||||
|                        typename NestedProduct::_LhsNested, | ||||
|                        typename NestedProduct::_RhsNested> | ||||
| { | ||||
|   public: | ||||
|     typedef ProductBase<ScaledProduct<NestedProduct>, | ||||
|                        typename NestedProduct::_LhsNested, | ||||
|                        typename NestedProduct::_RhsNested> Base; | ||||
|     typedef typename Base::Scalar Scalar; | ||||
|     typedef typename Base::PlainObject PlainObject; | ||||
| //     EIGEN_PRODUCT_PUBLIC_INTERFACE(ScaledProduct) | ||||
|  | ||||
|     ScaledProduct(const NestedProduct& prod, Scalar x) | ||||
|     : Base(prod.lhs(),prod.rhs()), m_prod(prod), m_alpha(x) {} | ||||
|  | ||||
|     template<typename Dest> | ||||
|     inline void evalTo(Dest& dst) const { dst.setZero(); scaleAndAddTo(dst, Scalar(1)); } | ||||
|  | ||||
|     template<typename Dest> | ||||
|     inline void addTo(Dest& dst) const { scaleAndAddTo(dst, Scalar(1)); } | ||||
|  | ||||
|     template<typename Dest> | ||||
|     inline void subTo(Dest& dst) const { scaleAndAddTo(dst, Scalar(-1)); } | ||||
|  | ||||
|     template<typename Dest> | ||||
|     inline void scaleAndAddTo(Dest& dst,Scalar alpha) const { m_prod.derived().scaleAndAddTo(dst,alpha * m_alpha); } | ||||
|  | ||||
|     const Scalar& alpha() const { return m_alpha; } | ||||
|      | ||||
|   protected: | ||||
|     const NestedProduct& m_prod; | ||||
|     Scalar m_alpha; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * Overloaded to perform an efficient C = (A*B).lazy() */ | ||||
| template<typename Derived> | ||||
| template<typename ProductDerived, typename Lhs, typename Rhs> | ||||
| Derived& MatrixBase<Derived>::lazyAssign(const ProductBase<ProductDerived, Lhs,Rhs>& other) | ||||
| { | ||||
|   other.derived().evalTo(derived()); | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_PRODUCTBASE_H | ||||
							
								
								
									
										152
									
								
								latan/Eigen/src/Core/Random.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								latan/Eigen/src/Core/Random.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,152 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_RANDOM_H | ||||
| #define EIGEN_RANDOM_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename Scalar> struct scalar_random_op { | ||||
|   EIGEN_EMPTY_STRUCT_CTOR(scalar_random_op) | ||||
|   template<typename Index> | ||||
|   inline const Scalar operator() (Index, Index = 0) const { return random<Scalar>(); } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct functor_traits<scalar_random_op<Scalar> > | ||||
| { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false, IsRepeatable = false }; }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /** \returns a random matrix expression | ||||
|   * | ||||
|   * The parameters \a rows and \a cols are the number of rows and of columns of | ||||
|   * the returned matrix. Must be compatible with this MatrixBase type. | ||||
|   * | ||||
|   * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, | ||||
|   * it is redundant to pass \a rows and \a cols as arguments, so Random() should be used | ||||
|   * instead. | ||||
|   * | ||||
|   * Example: \include MatrixBase_random_int_int.cpp | ||||
|   * Output: \verbinclude MatrixBase_random_int_int.out | ||||
|   * | ||||
|   * This expression has the "evaluate before nesting" flag so that it will be evaluated into | ||||
|   * a temporary matrix whenever it is nested in a larger expression. This prevents unexpected | ||||
|   * behavior with expressions involving random matrices. | ||||
|   * | ||||
|   * \sa MatrixBase::setRandom(), MatrixBase::Random(Index), MatrixBase::Random() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline const CwiseNullaryOp<internal::scalar_random_op<typename internal::traits<Derived>::Scalar>, Derived> | ||||
| DenseBase<Derived>::Random(Index rows, Index cols) | ||||
| { | ||||
|   return NullaryExpr(rows, cols, internal::scalar_random_op<Scalar>()); | ||||
| } | ||||
|  | ||||
| /** \returns a random vector expression | ||||
|   * | ||||
|   * The parameter \a size is the size of the returned vector. | ||||
|   * Must be compatible with this MatrixBase type. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * This variant is meant to be used for dynamic-size vector types. For fixed-size types, | ||||
|   * it is redundant to pass \a size as argument, so Random() should be used | ||||
|   * instead. | ||||
|   * | ||||
|   * Example: \include MatrixBase_random_int.cpp | ||||
|   * Output: \verbinclude MatrixBase_random_int.out | ||||
|   * | ||||
|   * This expression has the "evaluate before nesting" flag so that it will be evaluated into | ||||
|   * a temporary vector whenever it is nested in a larger expression. This prevents unexpected | ||||
|   * behavior with expressions involving random matrices. | ||||
|   * | ||||
|   * \sa MatrixBase::setRandom(), MatrixBase::Random(Index,Index), MatrixBase::Random() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline const CwiseNullaryOp<internal::scalar_random_op<typename internal::traits<Derived>::Scalar>, Derived> | ||||
| DenseBase<Derived>::Random(Index size) | ||||
| { | ||||
|   return NullaryExpr(size, internal::scalar_random_op<Scalar>()); | ||||
| } | ||||
|  | ||||
| /** \returns a fixed-size random matrix or vector expression | ||||
|   * | ||||
|   * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you | ||||
|   * need to use the variants taking size arguments. | ||||
|   * | ||||
|   * Example: \include MatrixBase_random.cpp | ||||
|   * Output: \verbinclude MatrixBase_random.out | ||||
|   * | ||||
|   * This expression has the "evaluate before nesting" flag so that it will be evaluated into | ||||
|   * a temporary matrix whenever it is nested in a larger expression. This prevents unexpected | ||||
|   * behavior with expressions involving random matrices. | ||||
|   * | ||||
|   * \sa MatrixBase::setRandom(), MatrixBase::Random(Index,Index), MatrixBase::Random(Index) | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline const CwiseNullaryOp<internal::scalar_random_op<typename internal::traits<Derived>::Scalar>, Derived> | ||||
| DenseBase<Derived>::Random() | ||||
| { | ||||
|   return NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_random_op<Scalar>()); | ||||
| } | ||||
|  | ||||
| /** Sets all coefficients in this expression to random values. | ||||
|   * | ||||
|   * Example: \include MatrixBase_setRandom.cpp | ||||
|   * Output: \verbinclude MatrixBase_setRandom.out | ||||
|   * | ||||
|   * \sa class CwiseNullaryOp, setRandom(Index), setRandom(Index,Index) | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline Derived& DenseBase<Derived>::setRandom() | ||||
| { | ||||
|   return *this = Random(rows(), cols()); | ||||
| } | ||||
|  | ||||
| /** Resizes to the given \a size, and sets all coefficients in this expression to random values. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * Example: \include Matrix_setRandom_int.cpp | ||||
|   * Output: \verbinclude Matrix_setRandom_int.out | ||||
|   * | ||||
|   * \sa MatrixBase::setRandom(), setRandom(Index,Index), class CwiseNullaryOp, MatrixBase::Random() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE Derived& | ||||
| PlainObjectBase<Derived>::setRandom(Index size) | ||||
| { | ||||
|   resize(size); | ||||
|   return setRandom(); | ||||
| } | ||||
|  | ||||
| /** Resizes to the given size, and sets all coefficients in this expression to random values. | ||||
|   * | ||||
|   * \param rows the new number of rows | ||||
|   * \param cols the new number of columns | ||||
|   * | ||||
|   * Example: \include Matrix_setRandom_int_int.cpp | ||||
|   * Output: \verbinclude Matrix_setRandom_int_int.out | ||||
|   * | ||||
|   * \sa MatrixBase::setRandom(), setRandom(Index), class CwiseNullaryOp, MatrixBase::Random() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE Derived& | ||||
| PlainObjectBase<Derived>::setRandom(Index rows, Index cols) | ||||
| { | ||||
|   resize(rows, cols); | ||||
|   return setRandom(); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_RANDOM_H | ||||
							
								
								
									
										406
									
								
								latan/Eigen/src/Core/Redux.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										406
									
								
								latan/Eigen/src/Core/Redux.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,406 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_REDUX_H | ||||
| #define EIGEN_REDUX_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| // TODO | ||||
| //  * implement other kind of vectorization | ||||
| //  * factorize code | ||||
|  | ||||
| /*************************************************************************** | ||||
| * Part 1 : the logic deciding a strategy for vectorization and unrolling | ||||
| ***************************************************************************/ | ||||
|  | ||||
| template<typename Func, typename Derived> | ||||
| struct redux_traits | ||||
| { | ||||
| public: | ||||
|   enum { | ||||
|     PacketSize = packet_traits<typename Derived::Scalar>::size, | ||||
|     InnerMaxSize = int(Derived::IsRowMajor) | ||||
|                  ? Derived::MaxColsAtCompileTime | ||||
|                  : Derived::MaxRowsAtCompileTime | ||||
|   }; | ||||
|  | ||||
|   enum { | ||||
|     MightVectorize = (int(Derived::Flags)&ActualPacketAccessBit) | ||||
|                   && (functor_traits<Func>::PacketAccess), | ||||
|     MayLinearVectorize = MightVectorize && (int(Derived::Flags)&LinearAccessBit), | ||||
|     MaySliceVectorize  = MightVectorize && int(InnerMaxSize)>=3*PacketSize | ||||
|   }; | ||||
|  | ||||
| public: | ||||
|   enum { | ||||
|     Traversal = int(MayLinearVectorize) ? int(LinearVectorizedTraversal) | ||||
|               : int(MaySliceVectorize)  ? int(SliceVectorizedTraversal) | ||||
|                                         : int(DefaultTraversal) | ||||
|   }; | ||||
|  | ||||
| public: | ||||
|   enum { | ||||
|     Cost = (  Derived::SizeAtCompileTime == Dynamic | ||||
|            || Derived::CoeffReadCost == Dynamic | ||||
|            || (Derived::SizeAtCompileTime!=1 && functor_traits<Func>::Cost == Dynamic) | ||||
|            ) ? Dynamic | ||||
|            : Derived::SizeAtCompileTime * Derived::CoeffReadCost | ||||
|                + (Derived::SizeAtCompileTime-1) * functor_traits<Func>::Cost, | ||||
|     UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Traversal) == int(DefaultTraversal) ? 1 : int(PacketSize)) | ||||
|   }; | ||||
|  | ||||
| public: | ||||
|   enum { | ||||
|     Unrolling = Cost != Dynamic && Cost <= UnrollingLimit | ||||
|               ? CompleteUnrolling | ||||
|               : NoUnrolling | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /*************************************************************************** | ||||
| * Part 2 : unrollers | ||||
| ***************************************************************************/ | ||||
|  | ||||
| /*** no vectorization ***/ | ||||
|  | ||||
| template<typename Func, typename Derived, int Start, int Length> | ||||
| struct redux_novec_unroller | ||||
| { | ||||
|   enum { | ||||
|     HalfLength = Length/2 | ||||
|   }; | ||||
|  | ||||
|   typedef typename Derived::Scalar Scalar; | ||||
|  | ||||
|   static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func& func) | ||||
|   { | ||||
|     return func(redux_novec_unroller<Func, Derived, Start, HalfLength>::run(mat,func), | ||||
|                 redux_novec_unroller<Func, Derived, Start+HalfLength, Length-HalfLength>::run(mat,func)); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Func, typename Derived, int Start> | ||||
| struct redux_novec_unroller<Func, Derived, Start, 1> | ||||
| { | ||||
|   enum { | ||||
|     outer = Start / Derived::InnerSizeAtCompileTime, | ||||
|     inner = Start % Derived::InnerSizeAtCompileTime | ||||
|   }; | ||||
|  | ||||
|   typedef typename Derived::Scalar Scalar; | ||||
|  | ||||
|   static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func&) | ||||
|   { | ||||
|     return mat.coeffByOuterInner(outer, inner); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // This is actually dead code and will never be called. It is required | ||||
| // to prevent false warnings regarding failed inlining though | ||||
| // for 0 length run() will never be called at all. | ||||
| template<typename Func, typename Derived, int Start> | ||||
| struct redux_novec_unroller<Func, Derived, Start, 0> | ||||
| { | ||||
|   typedef typename Derived::Scalar Scalar; | ||||
|   static EIGEN_STRONG_INLINE Scalar run(const Derived&, const Func&) { return Scalar(); } | ||||
| }; | ||||
|  | ||||
| /*** vectorization ***/ | ||||
|  | ||||
| template<typename Func, typename Derived, int Start, int Length> | ||||
| struct redux_vec_unroller | ||||
| { | ||||
|   enum { | ||||
|     PacketSize = packet_traits<typename Derived::Scalar>::size, | ||||
|     HalfLength = Length/2 | ||||
|   }; | ||||
|  | ||||
|   typedef typename Derived::Scalar Scalar; | ||||
|   typedef typename packet_traits<Scalar>::type PacketScalar; | ||||
|  | ||||
|   static EIGEN_STRONG_INLINE PacketScalar run(const Derived &mat, const Func& func) | ||||
|   { | ||||
|     return func.packetOp( | ||||
|             redux_vec_unroller<Func, Derived, Start, HalfLength>::run(mat,func), | ||||
|             redux_vec_unroller<Func, Derived, Start+HalfLength, Length-HalfLength>::run(mat,func) ); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Func, typename Derived, int Start> | ||||
| struct redux_vec_unroller<Func, Derived, Start, 1> | ||||
| { | ||||
|   enum { | ||||
|     index = Start * packet_traits<typename Derived::Scalar>::size, | ||||
|     outer = index / int(Derived::InnerSizeAtCompileTime), | ||||
|     inner = index % int(Derived::InnerSizeAtCompileTime), | ||||
|     alignment = (Derived::Flags & AlignedBit) ? Aligned : Unaligned | ||||
|   }; | ||||
|  | ||||
|   typedef typename Derived::Scalar Scalar; | ||||
|   typedef typename packet_traits<Scalar>::type PacketScalar; | ||||
|  | ||||
|   static EIGEN_STRONG_INLINE PacketScalar run(const Derived &mat, const Func&) | ||||
|   { | ||||
|     return mat.template packetByOuterInner<alignment>(outer, inner); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /*************************************************************************** | ||||
| * Part 3 : implementation of all cases | ||||
| ***************************************************************************/ | ||||
|  | ||||
| template<typename Func, typename Derived, | ||||
|          int Traversal = redux_traits<Func, Derived>::Traversal, | ||||
|          int Unrolling = redux_traits<Func, Derived>::Unrolling | ||||
| > | ||||
| struct redux_impl; | ||||
|  | ||||
| template<typename Func, typename Derived> | ||||
| struct redux_impl<Func, Derived, DefaultTraversal, NoUnrolling> | ||||
| { | ||||
|   typedef typename Derived::Scalar Scalar; | ||||
|   typedef typename Derived::Index Index; | ||||
|   static EIGEN_STRONG_INLINE Scalar run(const Derived& mat, const Func& func) | ||||
|   { | ||||
|     eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix"); | ||||
|     Scalar res; | ||||
|     res = mat.coeffByOuterInner(0, 0); | ||||
|     for(Index i = 1; i < mat.innerSize(); ++i) | ||||
|       res = func(res, mat.coeffByOuterInner(0, i)); | ||||
|     for(Index i = 1; i < mat.outerSize(); ++i) | ||||
|       for(Index j = 0; j < mat.innerSize(); ++j) | ||||
|         res = func(res, mat.coeffByOuterInner(i, j)); | ||||
|     return res; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Func, typename Derived> | ||||
| struct redux_impl<Func,Derived, DefaultTraversal, CompleteUnrolling> | ||||
|   : public redux_novec_unroller<Func,Derived, 0, Derived::SizeAtCompileTime> | ||||
| {}; | ||||
|  | ||||
| template<typename Func, typename Derived> | ||||
| struct redux_impl<Func, Derived, LinearVectorizedTraversal, NoUnrolling> | ||||
| { | ||||
|   typedef typename Derived::Scalar Scalar; | ||||
|   typedef typename packet_traits<Scalar>::type PacketScalar; | ||||
|   typedef typename Derived::Index Index; | ||||
|  | ||||
|   static Scalar run(const Derived& mat, const Func& func) | ||||
|   { | ||||
|     const Index size = mat.size(); | ||||
|     eigen_assert(size && "you are using an empty matrix"); | ||||
|     const Index packetSize = packet_traits<Scalar>::size; | ||||
|     const Index alignedStart = internal::first_aligned(mat); | ||||
|     enum { | ||||
|       alignment = bool(Derived::Flags & DirectAccessBit) || bool(Derived::Flags & AlignedBit) | ||||
|                 ? Aligned : Unaligned | ||||
|     }; | ||||
|     const Index alignedSize2 = ((size-alignedStart)/(2*packetSize))*(2*packetSize); | ||||
|     const Index alignedSize = ((size-alignedStart)/(packetSize))*(packetSize); | ||||
|     const Index alignedEnd2 = alignedStart + alignedSize2; | ||||
|     const Index alignedEnd  = alignedStart + alignedSize; | ||||
|     Scalar res; | ||||
|     if(alignedSize) | ||||
|     { | ||||
|       PacketScalar packet_res0 = mat.template packet<alignment>(alignedStart); | ||||
|       if(alignedSize>packetSize) // we have at least two packets to partly unroll the loop | ||||
|       { | ||||
|         PacketScalar packet_res1 = mat.template packet<alignment>(alignedStart+packetSize); | ||||
|         for(Index index = alignedStart + 2*packetSize; index < alignedEnd2; index += 2*packetSize) | ||||
|         { | ||||
|           packet_res0 = func.packetOp(packet_res0, mat.template packet<alignment>(index)); | ||||
|           packet_res1 = func.packetOp(packet_res1, mat.template packet<alignment>(index+packetSize)); | ||||
|         } | ||||
|  | ||||
|         packet_res0 = func.packetOp(packet_res0,packet_res1); | ||||
|         if(alignedEnd>alignedEnd2) | ||||
|           packet_res0 = func.packetOp(packet_res0, mat.template packet<alignment>(alignedEnd2)); | ||||
|       } | ||||
|       res = func.predux(packet_res0); | ||||
|  | ||||
|       for(Index index = 0; index < alignedStart; ++index) | ||||
|         res = func(res,mat.coeff(index)); | ||||
|  | ||||
|       for(Index index = alignedEnd; index < size; ++index) | ||||
|         res = func(res,mat.coeff(index)); | ||||
|     } | ||||
|     else // too small to vectorize anything. | ||||
|          // since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize. | ||||
|     { | ||||
|       res = mat.coeff(0); | ||||
|       for(Index index = 1; index < size; ++index) | ||||
|         res = func(res,mat.coeff(index)); | ||||
|     } | ||||
|  | ||||
|     return res; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Func, typename Derived> | ||||
| struct redux_impl<Func, Derived, SliceVectorizedTraversal, NoUnrolling> | ||||
| { | ||||
|   typedef typename Derived::Scalar Scalar; | ||||
|   typedef typename packet_traits<Scalar>::type PacketScalar; | ||||
|   typedef typename Derived::Index Index; | ||||
|  | ||||
|   static Scalar run(const Derived& mat, const Func& func) | ||||
|   { | ||||
|     eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix"); | ||||
|     const Index innerSize = mat.innerSize(); | ||||
|     const Index outerSize = mat.outerSize(); | ||||
|     enum { | ||||
|       packetSize = packet_traits<Scalar>::size | ||||
|     }; | ||||
|     const Index packetedInnerSize = ((innerSize)/packetSize)*packetSize; | ||||
|     Scalar res; | ||||
|     if(packetedInnerSize) | ||||
|     { | ||||
|       PacketScalar packet_res = mat.template packet<Unaligned>(0,0); | ||||
|       for(Index j=0; j<outerSize; ++j) | ||||
|         for(Index i=(j==0?packetSize:0); i<packetedInnerSize; i+=Index(packetSize)) | ||||
|           packet_res = func.packetOp(packet_res, mat.template packetByOuterInner<Unaligned>(j,i)); | ||||
|  | ||||
|       res = func.predux(packet_res); | ||||
|       for(Index j=0; j<outerSize; ++j) | ||||
|         for(Index i=packetedInnerSize; i<innerSize; ++i) | ||||
|           res = func(res, mat.coeffByOuterInner(j,i)); | ||||
|     } | ||||
|     else // too small to vectorize anything. | ||||
|          // since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize. | ||||
|     { | ||||
|       res = redux_impl<Func, Derived, DefaultTraversal, NoUnrolling>::run(mat, func); | ||||
|     } | ||||
|  | ||||
|     return res; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Func, typename Derived> | ||||
| struct redux_impl<Func, Derived, LinearVectorizedTraversal, CompleteUnrolling> | ||||
| { | ||||
|   typedef typename Derived::Scalar Scalar; | ||||
|   typedef typename packet_traits<Scalar>::type PacketScalar; | ||||
|   enum { | ||||
|     PacketSize = packet_traits<Scalar>::size, | ||||
|     Size = Derived::SizeAtCompileTime, | ||||
|     VectorizedSize = (Size / PacketSize) * PacketSize | ||||
|   }; | ||||
|   static EIGEN_STRONG_INLINE Scalar run(const Derived& mat, const Func& func) | ||||
|   { | ||||
|     eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix"); | ||||
|     Scalar res = func.predux(redux_vec_unroller<Func, Derived, 0, Size / PacketSize>::run(mat,func)); | ||||
|     if (VectorizedSize != Size) | ||||
|       res = func(res,redux_novec_unroller<Func, Derived, VectorizedSize, Size-VectorizedSize>::run(mat,func)); | ||||
|     return res; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /*************************************************************************** | ||||
| * Part 4 : public API | ||||
| ***************************************************************************/ | ||||
|  | ||||
|  | ||||
| /** \returns the result of a full redux operation on the whole matrix or vector using \a func | ||||
|   * | ||||
|   * The template parameter \a BinaryOp is the type of the functor \a func which must be | ||||
|   * an associative operator. Both current STL and TR1 functor styles are handled. | ||||
|   * | ||||
|   * \sa DenseBase::sum(), DenseBase::minCoeff(), DenseBase::maxCoeff(), MatrixBase::colwise(), MatrixBase::rowwise() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename Func> | ||||
| EIGEN_STRONG_INLINE typename internal::result_of<Func(typename internal::traits<Derived>::Scalar)>::type | ||||
| DenseBase<Derived>::redux(const Func& func) const | ||||
| { | ||||
|   typedef typename internal::remove_all<typename Derived::Nested>::type ThisNested; | ||||
|   return internal::redux_impl<Func, ThisNested> | ||||
|             ::run(derived(), func); | ||||
| } | ||||
|  | ||||
| /** \returns the minimum of all coefficients of *this | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar | ||||
| DenseBase<Derived>::minCoeff() const | ||||
| { | ||||
|   return this->redux(Eigen::internal::scalar_min_op<Scalar>()); | ||||
| } | ||||
|  | ||||
| /** \returns the maximum of all coefficients of *this | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar | ||||
| DenseBase<Derived>::maxCoeff() const | ||||
| { | ||||
|   return this->redux(Eigen::internal::scalar_max_op<Scalar>()); | ||||
| } | ||||
|  | ||||
| /** \returns the sum of all coefficients of *this | ||||
|   * | ||||
|   * \sa trace(), prod(), mean() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar | ||||
| DenseBase<Derived>::sum() const | ||||
| { | ||||
|   if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0)) | ||||
|     return Scalar(0); | ||||
|   return this->redux(Eigen::internal::scalar_sum_op<Scalar>()); | ||||
| } | ||||
|  | ||||
| /** \returns the mean of all coefficients of *this | ||||
| * | ||||
| * \sa trace(), prod(), sum() | ||||
| */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar | ||||
| DenseBase<Derived>::mean() const | ||||
| { | ||||
|   return Scalar(this->redux(Eigen::internal::scalar_sum_op<Scalar>())) / Scalar(this->size()); | ||||
| } | ||||
|  | ||||
| /** \returns the product of all coefficients of *this | ||||
|   * | ||||
|   * Example: \include MatrixBase_prod.cpp | ||||
|   * Output: \verbinclude MatrixBase_prod.out | ||||
|   * | ||||
|   * \sa sum(), mean(), trace() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar | ||||
| DenseBase<Derived>::prod() const | ||||
| { | ||||
|   if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0)) | ||||
|     return Scalar(1); | ||||
|   return this->redux(Eigen::internal::scalar_product_op<Scalar>()); | ||||
| } | ||||
|  | ||||
| /** \returns the trace of \c *this, i.e. the sum of the coefficients on the main diagonal. | ||||
|   * | ||||
|   * \c *this can be any matrix, not necessarily square. | ||||
|   * | ||||
|   * \sa diagonal(), sum() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar | ||||
| MatrixBase<Derived>::trace() const | ||||
| { | ||||
|   return derived().diagonal().sum(); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_REDUX_H | ||||
							
								
								
									
										177
									
								
								latan/Eigen/src/Core/Replicate.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								latan/Eigen/src/Core/Replicate.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,177 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_REPLICATE_H | ||||
| #define EIGEN_REPLICATE_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** | ||||
|   * \class Replicate | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Expression of the multiple replication of a matrix or vector | ||||
|   * | ||||
|   * \param MatrixType the type of the object we are replicating | ||||
|   * | ||||
|   * This class represents an expression of the multiple replication of a matrix or vector. | ||||
|   * It is the return type of DenseBase::replicate() and most of the time | ||||
|   * this is the only way it is used. | ||||
|   * | ||||
|   * \sa DenseBase::replicate() | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename MatrixType,int RowFactor,int ColFactor> | ||||
| struct traits<Replicate<MatrixType,RowFactor,ColFactor> > | ||||
|  : traits<MatrixType> | ||||
| { | ||||
|   typedef typename MatrixType::Scalar Scalar; | ||||
|   typedef typename traits<MatrixType>::StorageKind StorageKind; | ||||
|   typedef typename traits<MatrixType>::XprKind XprKind; | ||||
|   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 | ||||
|                       ? Dynamic | ||||
|                       : RowFactor * MatrixType::RowsAtCompileTime, | ||||
|     ColsAtCompileTime = ColFactor==Dynamic || int(MatrixType::ColsAtCompileTime)==Dynamic | ||||
|                       ? Dynamic | ||||
|                       : ColFactor * MatrixType::ColsAtCompileTime, | ||||
|    //FIXME we don't propagate the max sizes !!! | ||||
|     MaxRowsAtCompileTime = RowsAtCompileTime, | ||||
|     MaxColsAtCompileTime = ColsAtCompileTime, | ||||
|     IsRowMajor = MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1 ? 1 | ||||
|                : MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1 ? 0 | ||||
|                : (MatrixType::Flags & RowMajorBit) ? 1 : 0, | ||||
|     Flags = (_MatrixTypeNested::Flags & HereditaryBits & ~RowMajorBit) | (IsRowMajor ? RowMajorBit : 0), | ||||
|     CoeffReadCost = _MatrixTypeNested::CoeffReadCost | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| 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; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(Replicate) | ||||
|  | ||||
|     template<typename OriginalMatrixType> | ||||
|     inline explicit Replicate(const OriginalMatrixType& matrix) | ||||
|       : m_matrix(matrix), m_rowFactor(RowFactor), m_colFactor(ColFactor) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT((internal::is_same<typename internal::remove_const<MatrixType>::type,OriginalMatrixType>::value), | ||||
|                           THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE) | ||||
|       eigen_assert(RowFactor!=Dynamic && ColFactor!=Dynamic); | ||||
|     } | ||||
|  | ||||
|     template<typename OriginalMatrixType> | ||||
|     inline Replicate(const OriginalMatrixType& matrix, Index rowFactor, Index colFactor) | ||||
|       : m_matrix(matrix), m_rowFactor(rowFactor), m_colFactor(colFactor) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT((internal::is_same<typename internal::remove_const<MatrixType>::type,OriginalMatrixType>::value), | ||||
|                           THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE) | ||||
|     } | ||||
|  | ||||
|     inline Index rows() const { return m_matrix.rows() * m_rowFactor.value(); } | ||||
|     inline Index cols() const { return m_matrix.cols() * m_colFactor.value(); } | ||||
|  | ||||
|     inline Scalar coeff(Index row, Index col) const | ||||
|     { | ||||
|       // try to avoid using modulo; this is a pure optimization strategy | ||||
|       const Index actual_row  = internal::traits<MatrixType>::RowsAtCompileTime==1 ? 0 | ||||
|                             : RowFactor==1 ? row | ||||
|                             : row%m_matrix.rows(); | ||||
|       const Index actual_col  = internal::traits<MatrixType>::ColsAtCompileTime==1 ? 0 | ||||
|                             : ColFactor==1 ? col | ||||
|                             : col%m_matrix.cols(); | ||||
|  | ||||
|       return m_matrix.coeff(actual_row, actual_col); | ||||
|     } | ||||
|     template<int LoadMode> | ||||
|     inline PacketScalar packet(Index row, Index col) const | ||||
|     { | ||||
|       const Index actual_row  = internal::traits<MatrixType>::RowsAtCompileTime==1 ? 0 | ||||
|                             : RowFactor==1 ? row | ||||
|                             : row%m_matrix.rows(); | ||||
|       const Index actual_col  = internal::traits<MatrixType>::ColsAtCompileTime==1 ? 0 | ||||
|                             : ColFactor==1 ? col | ||||
|                             : col%m_matrix.cols(); | ||||
|  | ||||
|       return m_matrix.template packet<LoadMode>(actual_row, actual_col); | ||||
|     } | ||||
|  | ||||
|     const _MatrixTypeNested& nestedExpression() const | ||||
|     {  | ||||
|       return m_matrix;  | ||||
|     } | ||||
|  | ||||
|   protected: | ||||
|     MatrixTypeNested m_matrix; | ||||
|     const internal::variable_if_dynamic<Index, RowFactor> m_rowFactor; | ||||
|     const internal::variable_if_dynamic<Index, ColFactor> m_colFactor; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|   * \return an expression of the replication of \c *this | ||||
|   * | ||||
|   * Example: \include MatrixBase_replicate.cpp | ||||
|   * Output: \verbinclude MatrixBase_replicate.out | ||||
|   * | ||||
|   * \sa VectorwiseOp::replicate(), DenseBase::replicate(Index,Index), class Replicate | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<int RowFactor, int ColFactor> | ||||
| inline const Replicate<Derived,RowFactor,ColFactor> | ||||
| DenseBase<Derived>::replicate() const | ||||
| { | ||||
|   return Replicate<Derived,RowFactor,ColFactor>(derived()); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   * \return an expression of the replication of \c *this | ||||
|   * | ||||
|   * Example: \include MatrixBase_replicate_int_int.cpp | ||||
|   * Output: \verbinclude MatrixBase_replicate_int_int.out | ||||
|   * | ||||
|   * \sa VectorwiseOp::replicate(), DenseBase::replicate<int,int>(), class Replicate | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline const Replicate<Derived,Dynamic,Dynamic> | ||||
| DenseBase<Derived>::replicate(Index rowFactor,Index colFactor) const | ||||
| { | ||||
|   return Replicate<Derived,Dynamic,Dynamic>(derived(),rowFactor,colFactor); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   * \return an expression of the replication of each column (or row) of \c *this | ||||
|   * | ||||
|   * Example: \include DirectionWise_replicate_int.cpp | ||||
|   * Output: \verbinclude DirectionWise_replicate_int.out | ||||
|   * | ||||
|   * \sa VectorwiseOp::replicate(), DenseBase::replicate(), class Replicate | ||||
|   */ | ||||
| template<typename ExpressionType, int Direction> | ||||
| const typename VectorwiseOp<ExpressionType,Direction>::ReplicateReturnType | ||||
| VectorwiseOp<ExpressionType,Direction>::replicate(Index factor) const | ||||
| { | ||||
|   return typename VectorwiseOp<ExpressionType,Direction>::ReplicateReturnType | ||||
|           (_expression(),Direction==Vertical?factor:1,Direction==Horizontal?factor:1); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_REPLICATE_H | ||||
							
								
								
									
										88
									
								
								latan/Eigen/src/Core/ReturnByValue.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								latan/Eigen/src/Core/ReturnByValue.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2009-2010 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_RETURNBYVALUE_H | ||||
| #define EIGEN_RETURNBYVALUE_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| /** \class ReturnByValue | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename Derived> | ||||
| struct traits<ReturnByValue<Derived> > | ||||
|   : public traits<typename traits<Derived>::ReturnType> | ||||
| { | ||||
|   enum { | ||||
|     // We're disabling the DirectAccess because e.g. the constructor of | ||||
|     // the Block-with-DirectAccess expression requires to have a coeffRef method. | ||||
|     // Also, we don't want to have to implement the stride stuff. | ||||
|     Flags = (traits<typename traits<Derived>::ReturnType>::Flags | ||||
|              | EvalBeforeNestingBit) & ~DirectAccessBit | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /* The ReturnByValue object doesn't even have a coeff() method. | ||||
|  * So the only way that nesting it in an expression can work, is by evaluating it into a plain matrix. | ||||
|  * So internal::nested always gives the plain return matrix type. | ||||
|  * | ||||
|  * FIXME: I don't understand why we need this specialization: isn't this taken care of by the EvalBeforeNestingBit ?? | ||||
|  */ | ||||
| template<typename Derived,int n,typename PlainObject> | ||||
| struct nested<ReturnByValue<Derived>, n, PlainObject> | ||||
| { | ||||
|   typedef typename traits<Derived>::ReturnType type; | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| template<typename Derived> class ReturnByValue | ||||
|   : public internal::dense_xpr_base< ReturnByValue<Derived> >::type | ||||
| { | ||||
|   public: | ||||
|     typedef typename internal::traits<Derived>::ReturnType ReturnType; | ||||
|  | ||||
|     typedef typename internal::dense_xpr_base<ReturnByValue>::type Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(ReturnByValue) | ||||
|  | ||||
|     template<typename Dest> | ||||
|     inline void evalTo(Dest& dst) const | ||||
|     { static_cast<const Derived*>(this)->evalTo(dst); } | ||||
|     inline Index rows() const { return static_cast<const Derived*>(this)->rows(); } | ||||
|     inline Index cols() const { return static_cast<const Derived*>(this)->cols(); } | ||||
|  | ||||
| #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
| #define Unusable YOU_ARE_TRYING_TO_ACCESS_A_SINGLE_COEFFICIENT_IN_A_SPECIAL_EXPRESSION_WHERE_THAT_IS_NOT_ALLOWED_BECAUSE_THAT_WOULD_BE_INEFFICIENT | ||||
|     class Unusable{ | ||||
|       Unusable(const Unusable&) {} | ||||
|       Unusable& operator=(const Unusable&) {return *this;} | ||||
|     }; | ||||
|     const Unusable& coeff(Index) const { return *reinterpret_cast<const Unusable*>(this); } | ||||
|     const Unusable& coeff(Index,Index) const { return *reinterpret_cast<const Unusable*>(this); } | ||||
|     Unusable& coeffRef(Index) { return *reinterpret_cast<Unusable*>(this); } | ||||
|     Unusable& coeffRef(Index,Index) { return *reinterpret_cast<Unusable*>(this); } | ||||
| #endif | ||||
| }; | ||||
|  | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| Derived& DenseBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other) | ||||
| { | ||||
|   other.evalTo(derived()); | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_RETURNBYVALUE_H | ||||
							
								
								
									
										224
									
								
								latan/Eigen/src/Core/Reverse.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								latan/Eigen/src/Core/Reverse.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,224 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // Copyright (C) 2009 Ricard Marxer <email@ricardmarxer.com> | ||||
| // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_REVERSE_H | ||||
| #define EIGEN_REVERSE_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class Reverse | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Expression of the reverse of a vector or matrix | ||||
|   * | ||||
|   * \param MatrixType the type of the object of which we are taking the reverse | ||||
|   * | ||||
|   * This class represents an expression of the reverse of a vector. | ||||
|   * It is the return type of MatrixBase::reverse() and VectorwiseOp::reverse() | ||||
|   * and most of the time this is the only way it is used. | ||||
|   * | ||||
|   * \sa MatrixBase::reverse(), VectorwiseOp::reverse() | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename MatrixType, int Direction> | ||||
| struct traits<Reverse<MatrixType, Direction> > | ||||
|  : traits<MatrixType> | ||||
| { | ||||
|   typedef typename MatrixType::Scalar Scalar; | ||||
|   typedef typename traits<MatrixType>::StorageKind StorageKind; | ||||
|   typedef typename traits<MatrixType>::XprKind XprKind; | ||||
|   typedef typename nested<MatrixType>::type MatrixTypeNested; | ||||
|   typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested; | ||||
|   enum { | ||||
|     RowsAtCompileTime = MatrixType::RowsAtCompileTime, | ||||
|     ColsAtCompileTime = MatrixType::ColsAtCompileTime, | ||||
|     MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, | ||||
|     MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, | ||||
|  | ||||
|     // let's enable LinearAccess only with vectorization because of the product overhead | ||||
|     LinearAccess = ( (Direction==BothDirections) && (int(_MatrixTypeNested::Flags)&PacketAccessBit) ) | ||||
|                  ? LinearAccessBit : 0, | ||||
|  | ||||
|     Flags = int(_MatrixTypeNested::Flags) & (HereditaryBits | LvalueBit | PacketAccessBit | LinearAccess), | ||||
|  | ||||
|     CoeffReadCost = _MatrixTypeNested::CoeffReadCost | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| template<typename PacketScalar, bool ReversePacket> struct reverse_packet_cond | ||||
| { | ||||
|   static inline PacketScalar run(const PacketScalar& x) { return preverse(x); } | ||||
| }; | ||||
|  | ||||
| template<typename PacketScalar> struct reverse_packet_cond<PacketScalar,false> | ||||
| { | ||||
|   static inline PacketScalar run(const PacketScalar& x) { return x; } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal  | ||||
|  | ||||
| template<typename MatrixType, int Direction> class Reverse | ||||
|   : public internal::dense_xpr_base< Reverse<MatrixType, Direction> >::type | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef typename internal::dense_xpr_base<Reverse>::type Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(Reverse) | ||||
|     using Base::IsRowMajor; | ||||
|  | ||||
|     // next line is necessary because otherwise const version of operator() | ||||
|     // is hidden by non-const version defined in this file | ||||
|     using Base::operator();  | ||||
|  | ||||
|   protected: | ||||
|     enum { | ||||
|       PacketSize = internal::packet_traits<Scalar>::size, | ||||
|       IsColMajor = !IsRowMajor, | ||||
|       ReverseRow = (Direction == Vertical)   || (Direction == BothDirections), | ||||
|       ReverseCol = (Direction == Horizontal) || (Direction == BothDirections), | ||||
|       OffsetRow  = ReverseRow && IsColMajor ? PacketSize : 1, | ||||
|       OffsetCol  = ReverseCol && IsRowMajor ? PacketSize : 1, | ||||
|       ReversePacket = (Direction == BothDirections) | ||||
|                     || ((Direction == Vertical)   && IsColMajor) | ||||
|                     || ((Direction == Horizontal) && IsRowMajor) | ||||
|     }; | ||||
|     typedef internal::reverse_packet_cond<PacketScalar,ReversePacket> reverse_packet; | ||||
|   public: | ||||
|  | ||||
|     inline Reverse(const MatrixType& matrix) : m_matrix(matrix) { } | ||||
|  | ||||
|     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse) | ||||
|  | ||||
|     inline Index rows() const { return m_matrix.rows(); } | ||||
|     inline Index cols() const { return m_matrix.cols(); } | ||||
|  | ||||
|     inline Index innerStride() const | ||||
|     { | ||||
|       return -m_matrix.innerStride(); | ||||
|     } | ||||
|  | ||||
|     inline Scalar& operator()(Index row, Index col) | ||||
|     { | ||||
|       eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols()); | ||||
|       return coeffRef(row, col); | ||||
|     } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index row, Index col) | ||||
|     { | ||||
|       return m_matrix.const_cast_derived().coeffRef(ReverseRow ? m_matrix.rows() - row - 1 : row, | ||||
|                                                     ReverseCol ? m_matrix.cols() - col - 1 : col); | ||||
|     } | ||||
|  | ||||
|     inline CoeffReturnType coeff(Index row, Index col) const | ||||
|     { | ||||
|       return m_matrix.coeff(ReverseRow ? m_matrix.rows() - row - 1 : row, | ||||
|                             ReverseCol ? m_matrix.cols() - col - 1 : col); | ||||
|     } | ||||
|  | ||||
|     inline CoeffReturnType coeff(Index index) const | ||||
|     { | ||||
|       return m_matrix.coeff(m_matrix.size() - index - 1); | ||||
|     } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index index) | ||||
|     { | ||||
|       return m_matrix.const_cast_derived().coeffRef(m_matrix.size() - index - 1); | ||||
|     } | ||||
|  | ||||
|     inline Scalar& operator()(Index index) | ||||
|     { | ||||
|       eigen_assert(index >= 0 && index < m_matrix.size()); | ||||
|       return coeffRef(index); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline const PacketScalar packet(Index row, Index col) const | ||||
|     { | ||||
|       return reverse_packet::run(m_matrix.template packet<LoadMode>( | ||||
|                                     ReverseRow ? m_matrix.rows() - row - OffsetRow : row, | ||||
|                                     ReverseCol ? m_matrix.cols() - col - OffsetCol : col)); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline void writePacket(Index row, Index col, const PacketScalar& x) | ||||
|     { | ||||
|       m_matrix.const_cast_derived().template writePacket<LoadMode>( | ||||
|                                       ReverseRow ? m_matrix.rows() - row - OffsetRow : row, | ||||
|                                       ReverseCol ? m_matrix.cols() - col - OffsetCol : col, | ||||
|                                       reverse_packet::run(x)); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline const PacketScalar packet(Index index) const | ||||
|     { | ||||
|       return internal::preverse(m_matrix.template packet<LoadMode>( m_matrix.size() - index - PacketSize )); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline void writePacket(Index index, const PacketScalar& x) | ||||
|     { | ||||
|       m_matrix.const_cast_derived().template writePacket<LoadMode>(m_matrix.size() - index - PacketSize, internal::preverse(x)); | ||||
|     } | ||||
|  | ||||
|     const typename internal::remove_all<typename MatrixType::Nested>::type&  | ||||
|     nestedExpression() const  | ||||
|     { | ||||
|       return m_matrix; | ||||
|     } | ||||
|  | ||||
|   protected: | ||||
|     typename MatrixType::Nested m_matrix; | ||||
| }; | ||||
|  | ||||
| /** \returns an expression of the reverse of *this. | ||||
|   * | ||||
|   * Example: \include MatrixBase_reverse.cpp | ||||
|   * Output: \verbinclude MatrixBase_reverse.out | ||||
|   * | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline typename DenseBase<Derived>::ReverseReturnType | ||||
| DenseBase<Derived>::reverse() | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| /** This is the const version of reverse(). */ | ||||
| template<typename Derived> | ||||
| inline const typename DenseBase<Derived>::ConstReverseReturnType | ||||
| DenseBase<Derived>::reverse() const | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| /** This is the "in place" version of reverse: it reverses \c *this. | ||||
|   * | ||||
|   * In most cases it is probably better to simply use the reversed expression | ||||
|   * of a matrix. However, when reversing the matrix data itself is really needed, | ||||
|   * then this "in-place" version is probably the right choice because it provides | ||||
|   * the following additional features: | ||||
|   *  - less error prone: doing the same operation with .reverse() requires special care: | ||||
|   *    \code m = m.reverse().eval(); \endcode | ||||
|   *  - this API allows to avoid creating a temporary (the current implementation creates a temporary, but that could be avoided using swap) | ||||
|   *  - it allows future optimizations (cache friendliness, etc.) | ||||
|   * | ||||
|   * \sa reverse() */ | ||||
| template<typename Derived> | ||||
| inline void DenseBase<Derived>::reverseInPlace() | ||||
| { | ||||
|   derived() = derived().reverse().eval(); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_REVERSE_H | ||||
							
								
								
									
										162
									
								
								latan/Eigen/src/Core/Select.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								latan/Eigen/src/Core/Select.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,162 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_SELECT_H | ||||
| #define EIGEN_SELECT_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class Select | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Expression of a coefficient wise version of the C++ ternary operator ?: | ||||
|   * | ||||
|   * \param ConditionMatrixType the type of the \em condition expression which must be a boolean matrix | ||||
|   * \param ThenMatrixType the type of the \em then expression | ||||
|   * \param ElseMatrixType the type of the \em else expression | ||||
|   * | ||||
|   * This class represents an expression of a coefficient wise version of the C++ ternary operator ?:. | ||||
|   * It is the return type of DenseBase::select() and most of the time this is the only way it is used. | ||||
|   * | ||||
|   * \sa DenseBase::select(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&) const | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType> | ||||
| struct traits<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> > | ||||
|  : traits<ThenMatrixType> | ||||
| { | ||||
|   typedef typename traits<ThenMatrixType>::Scalar Scalar; | ||||
|   typedef Dense StorageKind; | ||||
|   typedef typename traits<ThenMatrixType>::XprKind XprKind; | ||||
|   typedef typename ConditionMatrixType::Nested ConditionMatrixNested; | ||||
|   typedef typename ThenMatrixType::Nested ThenMatrixNested; | ||||
|   typedef typename ElseMatrixType::Nested ElseMatrixNested; | ||||
|   enum { | ||||
|     RowsAtCompileTime = ConditionMatrixType::RowsAtCompileTime, | ||||
|     ColsAtCompileTime = ConditionMatrixType::ColsAtCompileTime, | ||||
|     MaxRowsAtCompileTime = ConditionMatrixType::MaxRowsAtCompileTime, | ||||
|     MaxColsAtCompileTime = ConditionMatrixType::MaxColsAtCompileTime, | ||||
|     Flags = (unsigned int)ThenMatrixType::Flags & ElseMatrixType::Flags & HereditaryBits, | ||||
|     CoeffReadCost = traits<typename remove_all<ConditionMatrixNested>::type>::CoeffReadCost | ||||
|                   + EIGEN_SIZE_MAX(traits<typename remove_all<ThenMatrixNested>::type>::CoeffReadCost, | ||||
|                                    traits<typename remove_all<ElseMatrixNested>::type>::CoeffReadCost) | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType> | ||||
| class Select : internal::no_assignment_operator, | ||||
|   public internal::dense_xpr_base< Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >::type | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef typename internal::dense_xpr_base<Select>::type Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(Select) | ||||
|  | ||||
|     Select(const ConditionMatrixType& conditionMatrix, | ||||
|            const ThenMatrixType& thenMatrix, | ||||
|            const ElseMatrixType& elseMatrix) | ||||
|       : m_condition(conditionMatrix), m_then(thenMatrix), m_else(elseMatrix) | ||||
|     { | ||||
|       eigen_assert(m_condition.rows() == m_then.rows() && m_condition.rows() == m_else.rows()); | ||||
|       eigen_assert(m_condition.cols() == m_then.cols() && m_condition.cols() == m_else.cols()); | ||||
|     } | ||||
|  | ||||
|     Index rows() const { return m_condition.rows(); } | ||||
|     Index cols() const { return m_condition.cols(); } | ||||
|  | ||||
|     const Scalar coeff(Index i, Index j) const | ||||
|     { | ||||
|       if (m_condition.coeff(i,j)) | ||||
|         return m_then.coeff(i,j); | ||||
|       else | ||||
|         return m_else.coeff(i,j); | ||||
|     } | ||||
|  | ||||
|     const Scalar coeff(Index i) const | ||||
|     { | ||||
|       if (m_condition.coeff(i)) | ||||
|         return m_then.coeff(i); | ||||
|       else | ||||
|         return m_else.coeff(i); | ||||
|     } | ||||
|  | ||||
|     const ConditionMatrixType& conditionMatrix() const | ||||
|     { | ||||
|       return m_condition; | ||||
|     } | ||||
|  | ||||
|     const ThenMatrixType& thenMatrix() const | ||||
|     { | ||||
|       return m_then; | ||||
|     } | ||||
|  | ||||
|     const ElseMatrixType& elseMatrix() const | ||||
|     { | ||||
|       return m_else; | ||||
|     } | ||||
|  | ||||
|   protected: | ||||
|     typename ConditionMatrixType::Nested m_condition; | ||||
|     typename ThenMatrixType::Nested m_then; | ||||
|     typename ElseMatrixType::Nested m_else; | ||||
| }; | ||||
|  | ||||
|  | ||||
| /** \returns a matrix where each coefficient (i,j) is equal to \a thenMatrix(i,j) | ||||
|   * if \c *this(i,j), and \a elseMatrix(i,j) otherwise. | ||||
|   * | ||||
|   * Example: \include MatrixBase_select.cpp | ||||
|   * Output: \verbinclude MatrixBase_select.out | ||||
|   * | ||||
|   * \sa class Select | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename ThenDerived,typename ElseDerived> | ||||
| inline const Select<Derived,ThenDerived,ElseDerived> | ||||
| DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix, | ||||
|                             const DenseBase<ElseDerived>& elseMatrix) const | ||||
| { | ||||
|   return Select<Derived,ThenDerived,ElseDerived>(derived(), thenMatrix.derived(), elseMatrix.derived()); | ||||
| } | ||||
|  | ||||
| /** Version of DenseBase::select(const DenseBase&, const DenseBase&) with | ||||
|   * the \em else expression being a scalar value. | ||||
|   * | ||||
|   * \sa DenseBase::select(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&) const, class Select | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename ThenDerived> | ||||
| inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType> | ||||
| DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix, | ||||
|                             typename ThenDerived::Scalar elseScalar) const | ||||
| { | ||||
|   return Select<Derived,ThenDerived,typename ThenDerived::ConstantReturnType>( | ||||
|     derived(), thenMatrix.derived(), ThenDerived::Constant(rows(),cols(),elseScalar)); | ||||
| } | ||||
|  | ||||
| /** Version of DenseBase::select(const DenseBase&, const DenseBase&) with | ||||
|   * the \em then expression being a scalar value. | ||||
|   * | ||||
|   * \sa DenseBase::select(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&) const, class Select | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename ElseDerived> | ||||
| inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived > | ||||
| DenseBase<Derived>::select(typename ElseDerived::Scalar thenScalar, | ||||
|                             const DenseBase<ElseDerived>& elseMatrix) const | ||||
| { | ||||
|   return Select<Derived,typename ElseDerived::ConstantReturnType,ElseDerived>( | ||||
|     derived(), ElseDerived::Constant(rows(),cols(),thenScalar), elseMatrix.derived()); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_SELECT_H | ||||
							
								
								
									
										314
									
								
								latan/Eigen/src/Core/SelfAdjointView.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										314
									
								
								latan/Eigen/src/Core/SelfAdjointView.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,314 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_SELFADJOINTMATRIX_H | ||||
| #define EIGEN_SELFADJOINTMATRIX_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class SelfAdjointView | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * | ||||
|   * \brief Expression of a selfadjoint matrix from a triangular part of a dense matrix | ||||
|   * | ||||
|   * \param MatrixType the type of the dense matrix storing the coefficients | ||||
|   * \param TriangularPart can be either \c #Lower or \c #Upper | ||||
|   * | ||||
|   * This class is an expression of a sefladjoint matrix from a triangular part of a matrix | ||||
|   * with given dense storage of the coefficients. It is the return type of MatrixBase::selfadjointView() | ||||
|   * and most of the time this is the only way that it is used. | ||||
|   * | ||||
|   * \sa class TriangularBase, MatrixBase::selfadjointView() | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename MatrixType, unsigned int UpLo> | ||||
| struct traits<SelfAdjointView<MatrixType, UpLo> > : traits<MatrixType> | ||||
| { | ||||
|   typedef typename nested<MatrixType>::type MatrixTypeNested; | ||||
|   typedef typename remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned; | ||||
|   typedef MatrixType ExpressionType; | ||||
|   typedef typename MatrixType::PlainObject DenseMatrixType; | ||||
|   enum { | ||||
|     Mode = UpLo | SelfAdjoint, | ||||
|     Flags =  MatrixTypeNestedCleaned::Flags & (HereditaryBits) | ||||
|            & (~(PacketAccessBit | DirectAccessBit | LinearAccessBit)), // FIXME these flags should be preserved | ||||
|     CoeffReadCost = MatrixTypeNestedCleaned::CoeffReadCost | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template <typename Lhs, int LhsMode, bool LhsIsVector, | ||||
|           typename Rhs, int RhsMode, bool RhsIsVector> | ||||
| struct SelfadjointProductMatrix; | ||||
|  | ||||
| // FIXME could also be called SelfAdjointWrapper to be consistent with DiagonalWrapper ?? | ||||
| template<typename MatrixType, unsigned int UpLo> class SelfAdjointView | ||||
|   : public TriangularBase<SelfAdjointView<MatrixType, UpLo> > | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef TriangularBase<SelfAdjointView> Base; | ||||
|     typedef typename internal::traits<SelfAdjointView>::MatrixTypeNested MatrixTypeNested; | ||||
|     typedef typename internal::traits<SelfAdjointView>::MatrixTypeNestedCleaned MatrixTypeNestedCleaned; | ||||
|  | ||||
|     /** \brief The type of coefficients in this matrix */ | ||||
|     typedef typename internal::traits<SelfAdjointView>::Scalar Scalar;  | ||||
|  | ||||
|     typedef typename MatrixType::Index Index; | ||||
|  | ||||
|     enum { | ||||
|       Mode = internal::traits<SelfAdjointView>::Mode | ||||
|     }; | ||||
|     typedef typename MatrixType::PlainObject PlainObject; | ||||
|  | ||||
|     inline SelfAdjointView(MatrixType& matrix) : m_matrix(matrix) | ||||
|     {} | ||||
|  | ||||
|     inline Index rows() const { return m_matrix.rows(); } | ||||
|     inline Index cols() const { return m_matrix.cols(); } | ||||
|     inline Index outerStride() const { return m_matrix.outerStride(); } | ||||
|     inline Index innerStride() const { return m_matrix.innerStride(); } | ||||
|  | ||||
|     /** \sa MatrixBase::coeff() | ||||
|       * \warning the coordinates must fit into the referenced triangular part | ||||
|       */ | ||||
|     inline Scalar coeff(Index row, Index col) const | ||||
|     { | ||||
|       Base::check_coordinates_internal(row, col); | ||||
|       return m_matrix.coeff(row, col); | ||||
|     } | ||||
|  | ||||
|     /** \sa MatrixBase::coeffRef() | ||||
|       * \warning the coordinates must fit into the referenced triangular part | ||||
|       */ | ||||
|     inline Scalar& coeffRef(Index row, Index col) | ||||
|     { | ||||
|       Base::check_coordinates_internal(row, col); | ||||
|       return m_matrix.const_cast_derived().coeffRef(row, col); | ||||
|     } | ||||
|  | ||||
|     /** \internal */ | ||||
|     const MatrixTypeNestedCleaned& _expression() const { return m_matrix; } | ||||
|  | ||||
|     const MatrixTypeNestedCleaned& nestedExpression() const { return m_matrix; } | ||||
|     MatrixTypeNestedCleaned& nestedExpression() { return *const_cast<MatrixTypeNestedCleaned*>(&m_matrix); } | ||||
|  | ||||
|     /** Efficient self-adjoint matrix times vector/matrix product */ | ||||
|     template<typename OtherDerived> | ||||
|     SelfadjointProductMatrix<MatrixType,Mode,false,OtherDerived,0,OtherDerived::IsVectorAtCompileTime> | ||||
|     operator*(const MatrixBase<OtherDerived>& rhs) const | ||||
|     { | ||||
|       return SelfadjointProductMatrix | ||||
|               <MatrixType,Mode,false,OtherDerived,0,OtherDerived::IsVectorAtCompileTime> | ||||
|               (m_matrix, rhs.derived()); | ||||
|     } | ||||
|  | ||||
|     /** Efficient vector/matrix times self-adjoint matrix product */ | ||||
|     template<typename OtherDerived> friend | ||||
|     SelfadjointProductMatrix<OtherDerived,0,OtherDerived::IsVectorAtCompileTime,MatrixType,Mode,false> | ||||
|     operator*(const MatrixBase<OtherDerived>& lhs, const SelfAdjointView& rhs) | ||||
|     { | ||||
|       return SelfadjointProductMatrix | ||||
|               <OtherDerived,0,OtherDerived::IsVectorAtCompileTime,MatrixType,Mode,false> | ||||
|               (lhs.derived(),rhs.m_matrix); | ||||
|     } | ||||
|  | ||||
|     /** Perform a symmetric rank 2 update of the selfadjoint matrix \c *this: | ||||
|       * \f$ this = this + \alpha u v^* + conj(\alpha) v u^* \f$ | ||||
|       * \returns a reference to \c *this | ||||
|       * | ||||
|       * The vectors \a u and \c v \b must be column vectors, however they can be | ||||
|       * a adjoint expression without any overhead. Only the meaningful triangular | ||||
|       * part of the matrix is updated, the rest is left unchanged. | ||||
|       * | ||||
|       * \sa rankUpdate(const MatrixBase<DerivedU>&, Scalar) | ||||
|       */ | ||||
|     template<typename DerivedU, typename DerivedV> | ||||
|     SelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, const MatrixBase<DerivedV>& v, Scalar alpha = Scalar(1)); | ||||
|  | ||||
|     /** Perform a symmetric rank K update of the selfadjoint matrix \c *this: | ||||
|       * \f$ this = this + \alpha ( u u^* ) \f$ where \a u is a vector or matrix. | ||||
|       * | ||||
|       * \returns a reference to \c *this | ||||
|       * | ||||
|       * Note that to perform \f$ this = this + \alpha ( u^* u ) \f$ you can simply | ||||
|       * call this function with u.adjoint(). | ||||
|       * | ||||
|       * \sa rankUpdate(const MatrixBase<DerivedU>&, const MatrixBase<DerivedV>&, Scalar) | ||||
|       */ | ||||
|     template<typename DerivedU> | ||||
|     SelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, Scalar alpha = Scalar(1)); | ||||
|  | ||||
| /////////// Cholesky module /////////// | ||||
|  | ||||
|     const LLT<PlainObject, UpLo> llt() const; | ||||
|     const LDLT<PlainObject, UpLo> ldlt() const; | ||||
|  | ||||
| /////////// Eigenvalue module /////////// | ||||
|  | ||||
|     /** Real part of #Scalar */ | ||||
|     typedef typename NumTraits<Scalar>::Real RealScalar; | ||||
|     /** Return type of eigenvalues() */ | ||||
|     typedef Matrix<RealScalar, internal::traits<MatrixType>::ColsAtCompileTime, 1> EigenvaluesReturnType; | ||||
|  | ||||
|     EigenvaluesReturnType eigenvalues() const; | ||||
|     RealScalar operatorNorm() const; | ||||
|      | ||||
|     #ifdef EIGEN2_SUPPORT | ||||
|     template<typename OtherDerived> | ||||
|     SelfAdjointView& operator=(const MatrixBase<OtherDerived>& other) | ||||
|     { | ||||
|       enum { | ||||
|         OtherPart = UpLo == Upper ? StrictlyLower : StrictlyUpper | ||||
|       }; | ||||
|       m_matrix.const_cast_derived().template triangularView<UpLo>() = other; | ||||
|       m_matrix.const_cast_derived().template triangularView<OtherPart>() = other.adjoint(); | ||||
|       return *this; | ||||
|     } | ||||
|     template<typename OtherMatrixType, unsigned int OtherMode> | ||||
|     SelfAdjointView& operator=(const TriangularView<OtherMatrixType, OtherMode>& other) | ||||
|     { | ||||
|       enum { | ||||
|         OtherPart = UpLo == Upper ? StrictlyLower : StrictlyUpper | ||||
|       }; | ||||
|       m_matrix.const_cast_derived().template triangularView<UpLo>() = other.toDenseMatrix(); | ||||
|       m_matrix.const_cast_derived().template triangularView<OtherPart>() = other.toDenseMatrix().adjoint(); | ||||
|       return *this; | ||||
|     } | ||||
|     #endif | ||||
|  | ||||
|   protected: | ||||
|     MatrixTypeNested m_matrix; | ||||
| }; | ||||
|  | ||||
|  | ||||
| // template<typename OtherDerived, typename MatrixType, unsigned int UpLo> | ||||
| // internal::selfadjoint_matrix_product_returntype<OtherDerived,SelfAdjointView<MatrixType,UpLo> > | ||||
| // operator*(const MatrixBase<OtherDerived>& lhs, const SelfAdjointView<MatrixType,UpLo>& rhs) | ||||
| // { | ||||
| //   return internal::matrix_selfadjoint_product_returntype<OtherDerived,SelfAdjointView<MatrixType,UpLo> >(lhs.derived(),rhs); | ||||
| // } | ||||
|  | ||||
| // selfadjoint to dense matrix | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int UnrollCount, bool ClearOpposite> | ||||
| struct triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Upper), UnrollCount, ClearOpposite> | ||||
| { | ||||
|   enum { | ||||
|     col = (UnrollCount-1) / Derived1::RowsAtCompileTime, | ||||
|     row = (UnrollCount-1) % Derived1::RowsAtCompileTime | ||||
|   }; | ||||
|  | ||||
|   static inline void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Upper), UnrollCount-1, ClearOpposite>::run(dst, src); | ||||
|  | ||||
|     if(row == col) | ||||
|       dst.coeffRef(row, col) = real(src.coeff(row, col)); | ||||
|     else if(row < col) | ||||
|       dst.coeffRef(col, row) = conj(dst.coeffRef(row, col) = src.coeff(row, col)); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, bool ClearOpposite> | ||||
| struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Upper, 0, ClearOpposite> | ||||
| { | ||||
|   static inline void run(Derived1 &, const Derived2 &) {} | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, int UnrollCount, bool ClearOpposite> | ||||
| struct triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Lower), UnrollCount, ClearOpposite> | ||||
| { | ||||
|   enum { | ||||
|     col = (UnrollCount-1) / Derived1::RowsAtCompileTime, | ||||
|     row = (UnrollCount-1) % Derived1::RowsAtCompileTime | ||||
|   }; | ||||
|  | ||||
|   static inline void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Lower), UnrollCount-1, ClearOpposite>::run(dst, src); | ||||
|  | ||||
|     if(row == col) | ||||
|       dst.coeffRef(row, col) = real(src.coeff(row, col)); | ||||
|     else if(row > col) | ||||
|       dst.coeffRef(col, row) = conj(dst.coeffRef(row, col) = src.coeff(row, col)); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, bool ClearOpposite> | ||||
| struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Lower, 0, ClearOpposite> | ||||
| { | ||||
|   static inline void run(Derived1 &, const Derived2 &) {} | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, bool ClearOpposite> | ||||
| struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Upper, Dynamic, ClearOpposite> | ||||
| { | ||||
|   typedef typename Derived1::Index Index; | ||||
|   static inline void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     for(Index j = 0; j < dst.cols(); ++j) | ||||
|     { | ||||
|       for(Index i = 0; i < j; ++i) | ||||
|       { | ||||
|         dst.copyCoeff(i, j, src); | ||||
|         dst.coeffRef(j,i) = conj(dst.coeff(i,j)); | ||||
|       } | ||||
|       dst.copyCoeff(j, j, src); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, bool ClearOpposite> | ||||
| struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Lower, Dynamic, ClearOpposite> | ||||
| { | ||||
|   static inline void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|   typedef typename Derived1::Index Index; | ||||
|     for(Index i = 0; i < dst.rows(); ++i) | ||||
|     { | ||||
|       for(Index j = 0; j < i; ++j) | ||||
|       { | ||||
|         dst.copyCoeff(i, j, src); | ||||
|         dst.coeffRef(j,i) = conj(dst.coeff(i,j)); | ||||
|       } | ||||
|       dst.copyCoeff(i, i, src); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /*************************************************************************** | ||||
| * Implementation of MatrixBase methods | ||||
| ***************************************************************************/ | ||||
|  | ||||
| template<typename Derived> | ||||
| template<unsigned int UpLo> | ||||
| typename MatrixBase<Derived>::template ConstSelfAdjointViewReturnType<UpLo>::Type | ||||
| MatrixBase<Derived>::selfadjointView() const | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| template<typename Derived> | ||||
| template<unsigned int UpLo> | ||||
| typename MatrixBase<Derived>::template SelfAdjointViewReturnType<UpLo>::Type | ||||
| MatrixBase<Derived>::selfadjointView() | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_SELFADJOINTMATRIX_H | ||||
							
								
								
									
										194
									
								
								latan/Eigen/src/Core/SelfCwiseBinaryOp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								latan/Eigen/src/Core/SelfCwiseBinaryOp.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,194 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_SELFCWISEBINARYOP_H | ||||
| #define EIGEN_SELFCWISEBINARYOP_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class SelfCwiseBinaryOp | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \internal | ||||
|   * | ||||
|   * \brief Internal helper class for optimizing operators like +=, -= | ||||
|   * | ||||
|   * This is a pseudo expression class re-implementing the copyCoeff/copyPacket | ||||
|   * method to directly performs a +=/-= operations in an optimal way. In particular, | ||||
|   * this allows to make sure that the input/output data are loaded only once using | ||||
|   * aligned packet loads. | ||||
|   * | ||||
|   * \sa class SwapWrapper for a similar trick. | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename BinaryOp, typename Lhs, typename Rhs> | ||||
| struct traits<SelfCwiseBinaryOp<BinaryOp,Lhs,Rhs> > | ||||
|   : traits<CwiseBinaryOp<BinaryOp,Lhs,Rhs> > | ||||
| { | ||||
|   enum { | ||||
|     // Note that it is still a good idea to preserve the DirectAccessBit | ||||
|     // so that assign can correctly align the data. | ||||
|     Flags = traits<CwiseBinaryOp<BinaryOp,Lhs,Rhs> >::Flags | (Lhs::Flags&DirectAccessBit) | (Lhs::Flags&LvalueBit), | ||||
|     OuterStrideAtCompileTime = Lhs::OuterStrideAtCompileTime, | ||||
|     InnerStrideAtCompileTime = Lhs::InnerStrideAtCompileTime | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename BinaryOp, typename Lhs, typename Rhs> class SelfCwiseBinaryOp | ||||
|   : public internal::dense_xpr_base< SelfCwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef typename internal::dense_xpr_base<SelfCwiseBinaryOp>::type Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(SelfCwiseBinaryOp) | ||||
|  | ||||
|     typedef typename internal::packet_traits<Scalar>::type Packet; | ||||
|  | ||||
|     inline SelfCwiseBinaryOp(Lhs& xpr, const BinaryOp& func = BinaryOp()) : m_matrix(xpr), m_functor(func) {} | ||||
|  | ||||
|     inline Index rows() const { return m_matrix.rows(); } | ||||
|     inline Index cols() const { return m_matrix.cols(); } | ||||
|     inline Index outerStride() const { return m_matrix.outerStride(); } | ||||
|     inline Index innerStride() const { return m_matrix.innerStride(); } | ||||
|     inline const Scalar* data() const { return m_matrix.data(); } | ||||
|  | ||||
|     // note that this function is needed by assign to correctly align loads/stores | ||||
|     // TODO make Assign use .data() | ||||
|     inline Scalar& coeffRef(Index row, Index col) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_LVALUE(Lhs) | ||||
|       return m_matrix.const_cast_derived().coeffRef(row, col); | ||||
|     } | ||||
|     inline const Scalar& coeffRef(Index row, Index col) const | ||||
|     { | ||||
|       return m_matrix.coeffRef(row, col); | ||||
|     } | ||||
|  | ||||
|     // note that this function is needed by assign to correctly align loads/stores | ||||
|     // TODO make Assign use .data() | ||||
|     inline Scalar& coeffRef(Index index) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_LVALUE(Lhs) | ||||
|       return m_matrix.const_cast_derived().coeffRef(index); | ||||
|     } | ||||
|     inline const Scalar& coeffRef(Index index) const | ||||
|     { | ||||
|       return m_matrix.const_cast_derived().coeffRef(index); | ||||
|     } | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     void copyCoeff(Index row, Index col, const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       OtherDerived& _other = other.const_cast_derived(); | ||||
|       eigen_internal_assert(row >= 0 && row < rows() | ||||
|                          && col >= 0 && col < cols()); | ||||
|       Scalar& tmp = m_matrix.coeffRef(row,col); | ||||
|       tmp = m_functor(tmp, _other.coeff(row,col)); | ||||
|     } | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     void copyCoeff(Index index, const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       OtherDerived& _other = other.const_cast_derived(); | ||||
|       eigen_internal_assert(index >= 0 && index < m_matrix.size()); | ||||
|       Scalar& tmp = m_matrix.coeffRef(index); | ||||
|       tmp = m_functor(tmp, _other.coeff(index)); | ||||
|     } | ||||
|  | ||||
|     template<typename OtherDerived, int StoreMode, int LoadMode> | ||||
|     void copyPacket(Index row, Index col, const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       OtherDerived& _other = other.const_cast_derived(); | ||||
|       eigen_internal_assert(row >= 0 && row < rows() | ||||
|                         && col >= 0 && col < cols()); | ||||
|       m_matrix.template writePacket<StoreMode>(row, col, | ||||
|         m_functor.packetOp(m_matrix.template packet<StoreMode>(row, col),_other.template packet<LoadMode>(row, col)) ); | ||||
|     } | ||||
|  | ||||
|     template<typename OtherDerived, int StoreMode, int LoadMode> | ||||
|     void copyPacket(Index index, const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       OtherDerived& _other = other.const_cast_derived(); | ||||
|       eigen_internal_assert(index >= 0 && index < m_matrix.size()); | ||||
|       m_matrix.template writePacket<StoreMode>(index, | ||||
|         m_functor.packetOp(m_matrix.template packet<StoreMode>(index),_other.template packet<LoadMode>(index)) ); | ||||
|     } | ||||
|  | ||||
|     // reimplement lazyAssign to handle complex *= real | ||||
|     // see CwiseBinaryOp ctor for details | ||||
|     template<typename RhsDerived> | ||||
|     EIGEN_STRONG_INLINE SelfCwiseBinaryOp& lazyAssign(const DenseBase<RhsDerived>& rhs) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs,RhsDerived) | ||||
|       EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename RhsDerived::Scalar); | ||||
|        | ||||
|     #ifdef EIGEN_DEBUG_ASSIGN | ||||
|       internal::assign_traits<SelfCwiseBinaryOp, RhsDerived>::debug(); | ||||
|     #endif | ||||
|       eigen_assert(rows() == rhs.rows() && cols() == rhs.cols()); | ||||
|       internal::assign_impl<SelfCwiseBinaryOp, RhsDerived>::run(*this,rhs.derived()); | ||||
|     #ifndef EIGEN_NO_DEBUG | ||||
|       this->checkTransposeAliasing(rhs.derived()); | ||||
|     #endif | ||||
|       return *this; | ||||
|     } | ||||
|      | ||||
|     // overloaded to honor evaluation of special matrices | ||||
|     // maybe another solution would be to not use SelfCwiseBinaryOp | ||||
|     // at first... | ||||
|     SelfCwiseBinaryOp& operator=(const Rhs& _rhs) | ||||
|     { | ||||
|       typename internal::nested<Rhs>::type rhs(_rhs); | ||||
|       return Base::operator=(rhs); | ||||
|     } | ||||
|  | ||||
|     Lhs& expression() const  | ||||
|     {  | ||||
|       return m_matrix; | ||||
|     } | ||||
|  | ||||
|     const BinaryOp& functor() const  | ||||
|     {  | ||||
|       return m_functor; | ||||
|     } | ||||
|  | ||||
|   protected: | ||||
|     Lhs& m_matrix; | ||||
|     const BinaryOp& m_functor; | ||||
|  | ||||
|   private: | ||||
|     SelfCwiseBinaryOp& operator=(const SelfCwiseBinaryOp&); | ||||
| }; | ||||
|  | ||||
| template<typename Derived> | ||||
| inline Derived& DenseBase<Derived>::operator*=(const Scalar& other) | ||||
| { | ||||
|   typedef typename Derived::PlainObject PlainObject; | ||||
|   SelfCwiseBinaryOp<internal::scalar_product_op<Scalar>, Derived, typename PlainObject::ConstantReturnType> tmp(derived()); | ||||
|   tmp = PlainObject::Constant(rows(),cols(),other); | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| template<typename Derived> | ||||
| inline Derived& DenseBase<Derived>::operator/=(const Scalar& other) | ||||
| { | ||||
|   typedef typename internal::conditional<NumTraits<Scalar>::IsInteger, | ||||
|                                         internal::scalar_quotient_op<Scalar>, | ||||
|                                         internal::scalar_product_op<Scalar> >::type BinOp; | ||||
|   typedef typename Derived::PlainObject PlainObject; | ||||
|   SelfCwiseBinaryOp<BinOp, Derived, typename PlainObject::ConstantReturnType> tmp(derived()); | ||||
|   tmp = PlainObject::Constant(rows(),cols(), NumTraits<Scalar>::IsInteger ? other : Scalar(1)/other); | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_SELFCWISEBINARYOP_H | ||||
							
								
								
									
										260
									
								
								latan/Eigen/src/Core/SolveTriangular.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										260
									
								
								latan/Eigen/src/Core/SolveTriangular.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,260 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_SOLVETRIANGULAR_H | ||||
| #define EIGEN_SOLVETRIANGULAR_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| // Forward declarations: | ||||
| // The following two routines are implemented in the products/TriangularSolver*.h files | ||||
| template<typename LhsScalar, typename RhsScalar, typename Index, int Side, int Mode, bool Conjugate, int StorageOrder> | ||||
| struct triangular_solve_vector; | ||||
|  | ||||
| template <typename Scalar, typename Index, int Side, int Mode, bool Conjugate, int TriStorageOrder, int OtherStorageOrder> | ||||
| struct triangular_solve_matrix; | ||||
|  | ||||
| // small helper struct extracting some traits on the underlying solver operation | ||||
| template<typename Lhs, typename Rhs, int Side> | ||||
| class trsolve_traits | ||||
| { | ||||
|   private: | ||||
|     enum { | ||||
|       RhsIsVectorAtCompileTime = (Side==OnTheLeft ? Rhs::ColsAtCompileTime : Rhs::RowsAtCompileTime)==1 | ||||
|     }; | ||||
|   public: | ||||
|     enum { | ||||
|       Unrolling   = (RhsIsVectorAtCompileTime && Rhs::SizeAtCompileTime != Dynamic && Rhs::SizeAtCompileTime <= 8) | ||||
|                   ? CompleteUnrolling : NoUnrolling, | ||||
|       RhsVectors  = RhsIsVectorAtCompileTime ? 1 : Dynamic | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| template<typename Lhs, typename Rhs, | ||||
|   int Side, // can be OnTheLeft/OnTheRight | ||||
|   int Mode, // can be Upper/Lower | UnitDiag | ||||
|   int Unrolling = trsolve_traits<Lhs,Rhs,Side>::Unrolling, | ||||
|   int RhsVectors = trsolve_traits<Lhs,Rhs,Side>::RhsVectors | ||||
|   > | ||||
| struct triangular_solver_selector; | ||||
|  | ||||
| template<typename Lhs, typename Rhs, int Side, int Mode> | ||||
| struct triangular_solver_selector<Lhs,Rhs,Side,Mode,NoUnrolling,1> | ||||
| { | ||||
|   typedef typename Lhs::Scalar LhsScalar; | ||||
|   typedef typename Rhs::Scalar RhsScalar; | ||||
|   typedef blas_traits<Lhs> LhsProductTraits; | ||||
|   typedef typename LhsProductTraits::ExtractType ActualLhsType; | ||||
|   typedef Map<Matrix<RhsScalar,Dynamic,1>, Aligned> MappedRhs; | ||||
|   static void run(const Lhs& lhs, Rhs& rhs) | ||||
|   { | ||||
|     ActualLhsType actualLhs = LhsProductTraits::extract(lhs); | ||||
|  | ||||
|     // FIXME find a way to allow an inner stride if packet_traits<Scalar>::size==1 | ||||
|  | ||||
|     bool useRhsDirectly = Rhs::InnerStrideAtCompileTime==1 || rhs.innerStride()==1; | ||||
|  | ||||
|     ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhs,rhs.size(), | ||||
|                                                   (useRhsDirectly ? rhs.data() : 0)); | ||||
|                                                    | ||||
|     if(!useRhsDirectly) | ||||
|       MappedRhs(actualRhs,rhs.size()) = rhs; | ||||
|  | ||||
|     triangular_solve_vector<LhsScalar, RhsScalar, typename Lhs::Index, Side, Mode, LhsProductTraits::NeedToConjugate, | ||||
|                             (int(Lhs::Flags) & RowMajorBit) ? RowMajor : ColMajor> | ||||
|       ::run(actualLhs.cols(), actualLhs.data(), actualLhs.outerStride(), actualRhs); | ||||
|  | ||||
|     if(!useRhsDirectly) | ||||
|       rhs = MappedRhs(actualRhs, rhs.size()); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // the rhs is a matrix | ||||
| template<typename Lhs, typename Rhs, int Side, int Mode> | ||||
| struct triangular_solver_selector<Lhs,Rhs,Side,Mode,NoUnrolling,Dynamic> | ||||
| { | ||||
|   typedef typename Rhs::Scalar Scalar; | ||||
|   typedef typename Rhs::Index Index; | ||||
|   typedef blas_traits<Lhs> LhsProductTraits; | ||||
|   typedef typename LhsProductTraits::DirectLinearAccessType ActualLhsType; | ||||
|  | ||||
|   static void run(const Lhs& lhs, Rhs& rhs) | ||||
|   { | ||||
|     typename internal::add_const_on_value_type<ActualLhsType>::type actualLhs = LhsProductTraits::extract(lhs); | ||||
|  | ||||
|     const Index size = lhs.rows(); | ||||
|     const Index othersize = Side==OnTheLeft? rhs.cols() : rhs.rows(); | ||||
|  | ||||
|     typedef internal::gemm_blocking_space<(Rhs::Flags&RowMajorBit) ? RowMajor : ColMajor,Scalar,Scalar, | ||||
|               Rhs::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime, Lhs::MaxRowsAtCompileTime,4> BlockingType; | ||||
|  | ||||
|     BlockingType blocking(rhs.rows(), rhs.cols(), size); | ||||
|  | ||||
|     triangular_solve_matrix<Scalar,Index,Side,Mode,LhsProductTraits::NeedToConjugate,(int(Lhs::Flags) & RowMajorBit) ? RowMajor : ColMajor, | ||||
|                                (Rhs::Flags&RowMajorBit) ? RowMajor : ColMajor> | ||||
|       ::run(size, othersize, &actualLhs.coeffRef(0,0), actualLhs.outerStride(), &rhs.coeffRef(0,0), rhs.outerStride(), blocking); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /*************************************************************************** | ||||
| * meta-unrolling implementation | ||||
| ***************************************************************************/ | ||||
|  | ||||
| template<typename Lhs, typename Rhs, int Mode, int Index, int Size, | ||||
|          bool Stop = Index==Size> | ||||
| struct triangular_solver_unroller; | ||||
|  | ||||
| template<typename Lhs, typename Rhs, int Mode, int Index, int Size> | ||||
| struct triangular_solver_unroller<Lhs,Rhs,Mode,Index,Size,false> { | ||||
|   enum { | ||||
|     IsLower = ((Mode&Lower)==Lower), | ||||
|     I = IsLower ? Index : Size - Index - 1, | ||||
|     S = IsLower ? 0     : I+1 | ||||
|   }; | ||||
|   static void run(const Lhs& lhs, Rhs& rhs) | ||||
|   { | ||||
|     if (Index>0) | ||||
|       rhs.coeffRef(I) -= lhs.row(I).template segment<Index>(S).transpose() | ||||
|                          .cwiseProduct(rhs.template segment<Index>(S)).sum(); | ||||
|  | ||||
|     if(!(Mode & UnitDiag)) | ||||
|       rhs.coeffRef(I) /= lhs.coeff(I,I); | ||||
|  | ||||
|     triangular_solver_unroller<Lhs,Rhs,Mode,Index+1,Size>::run(lhs,rhs); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Lhs, typename Rhs, int Mode, int Index, int Size> | ||||
| struct triangular_solver_unroller<Lhs,Rhs,Mode,Index,Size,true> { | ||||
|   static void run(const Lhs&, Rhs&) {} | ||||
| }; | ||||
|  | ||||
| template<typename Lhs, typename Rhs, int Mode> | ||||
| struct triangular_solver_selector<Lhs,Rhs,OnTheLeft,Mode,CompleteUnrolling,1> { | ||||
|   static void run(const Lhs& lhs, Rhs& rhs) | ||||
|   { triangular_solver_unroller<Lhs,Rhs,Mode,0,Rhs::SizeAtCompileTime>::run(lhs,rhs); } | ||||
| }; | ||||
|  | ||||
| template<typename Lhs, typename Rhs, int Mode> | ||||
| struct triangular_solver_selector<Lhs,Rhs,OnTheRight,Mode,CompleteUnrolling,1> { | ||||
|   static void run(const Lhs& lhs, Rhs& rhs) | ||||
|   { | ||||
|     Transpose<const Lhs> trLhs(lhs); | ||||
|     Transpose<Rhs> trRhs(rhs); | ||||
|      | ||||
|     triangular_solver_unroller<Transpose<const Lhs>,Transpose<Rhs>, | ||||
|                               ((Mode&Upper)==Upper ? Lower : Upper) | (Mode&UnitDiag), | ||||
|                               0,Rhs::SizeAtCompileTime>::run(trLhs,trRhs); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /*************************************************************************** | ||||
| * TriangularView methods | ||||
| ***************************************************************************/ | ||||
|  | ||||
| /** "in-place" version of TriangularView::solve() where the result is written in \a other | ||||
|   * | ||||
|   * \warning The parameter is only marked 'const' to make the C++ compiler accept a temporary expression here. | ||||
|   * This function will const_cast it, so constness isn't honored here. | ||||
|   * | ||||
|   * See TriangularView:solve() for the details. | ||||
|   */ | ||||
| template<typename MatrixType, unsigned int Mode> | ||||
| template<int Side, typename OtherDerived> | ||||
| void TriangularView<MatrixType,Mode>::solveInPlace(const MatrixBase<OtherDerived>& _other) const | ||||
| { | ||||
|   OtherDerived& other = _other.const_cast_derived(); | ||||
|   eigen_assert( cols() == rows() && ((Side==OnTheLeft && cols() == other.rows()) || (Side==OnTheRight && cols() == other.cols())) ); | ||||
|   eigen_assert((!(Mode & ZeroDiag)) && bool(Mode & (Upper|Lower))); | ||||
|  | ||||
|   enum { copy = internal::traits<OtherDerived>::Flags & RowMajorBit  && OtherDerived::IsVectorAtCompileTime }; | ||||
|   typedef typename internal::conditional<copy, | ||||
|     typename internal::plain_matrix_type_column_major<OtherDerived>::type, OtherDerived&>::type OtherCopy; | ||||
|   OtherCopy otherCopy(other); | ||||
|  | ||||
|   internal::triangular_solver_selector<MatrixType, typename internal::remove_reference<OtherCopy>::type, | ||||
|     Side, Mode>::run(nestedExpression(), otherCopy); | ||||
|  | ||||
|   if (copy) | ||||
|     other = otherCopy; | ||||
| } | ||||
|  | ||||
| /** \returns the product of the inverse of \c *this with \a other, \a *this being triangular. | ||||
|   * | ||||
|   * This function computes the inverse-matrix matrix product inverse(\c *this) * \a other if | ||||
|   * \a Side==OnTheLeft (the default), or the right-inverse-multiply  \a other * inverse(\c *this) if | ||||
|   * \a Side==OnTheRight. | ||||
|   * | ||||
|   * The matrix \c *this must be triangular and invertible (i.e., all the coefficients of the | ||||
|   * diagonal must be non zero). It works as a forward (resp. backward) substitution if \c *this | ||||
|   * is an upper (resp. lower) triangular matrix. | ||||
|   * | ||||
|   * Example: \include MatrixBase_marked.cpp | ||||
|   * Output: \verbinclude MatrixBase_marked.out | ||||
|   * | ||||
|   * This function returns an expression of the inverse-multiply and can works in-place if it is assigned | ||||
|   * to the same matrix or vector \a other. | ||||
|   * | ||||
|   * For users coming from BLAS, this function (and more specifically solveInPlace()) offer | ||||
|   * all the operations supported by the \c *TRSV and \c *TRSM BLAS routines. | ||||
|   * | ||||
|   * \sa TriangularView::solveInPlace() | ||||
|   */ | ||||
| template<typename Derived, unsigned int Mode> | ||||
| template<int Side, typename Other> | ||||
| const internal::triangular_solve_retval<Side,TriangularView<Derived,Mode>,Other> | ||||
| TriangularView<Derived,Mode>::solve(const MatrixBase<Other>& other) const | ||||
| { | ||||
|   return internal::triangular_solve_retval<Side,TriangularView,Other>(*this, other.derived()); | ||||
| } | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
|  | ||||
| template<int Side, typename TriangularType, typename Rhs> | ||||
| struct traits<triangular_solve_retval<Side, TriangularType, Rhs> > | ||||
| { | ||||
|   typedef typename internal::plain_matrix_type_column_major<Rhs>::type ReturnType; | ||||
| }; | ||||
|  | ||||
| template<int Side, typename TriangularType, typename Rhs> struct triangular_solve_retval | ||||
|  : public ReturnByValue<triangular_solve_retval<Side, TriangularType, Rhs> > | ||||
| { | ||||
|   typedef typename remove_all<typename Rhs::Nested>::type RhsNestedCleaned; | ||||
|   typedef ReturnByValue<triangular_solve_retval> Base; | ||||
|   typedef typename Base::Index Index; | ||||
|  | ||||
|   triangular_solve_retval(const TriangularType& tri, const Rhs& rhs) | ||||
|     : m_triangularMatrix(tri), m_rhs(rhs) | ||||
|   {} | ||||
|  | ||||
|   inline Index rows() const { return m_rhs.rows(); } | ||||
|   inline Index cols() const { return m_rhs.cols(); } | ||||
|  | ||||
|   template<typename Dest> inline void evalTo(Dest& dst) const | ||||
|   { | ||||
|     if(!(is_same<RhsNestedCleaned,Dest>::value && extract_data(dst) == extract_data(m_rhs))) | ||||
|       dst = m_rhs; | ||||
|     m_triangularMatrix.template solveInPlace<Side>(dst); | ||||
|   } | ||||
|  | ||||
|   protected: | ||||
|     const TriangularType& m_triangularMatrix; | ||||
|     typename Rhs::Nested m_rhs; | ||||
| }; | ||||
|  | ||||
| } // namespace internal | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_SOLVETRIANGULAR_H | ||||
							
								
								
									
										177
									
								
								latan/Eigen/src/Core/StableNorm.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								latan/Eigen/src/Core/StableNorm.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,177 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_STABLENORM_H | ||||
| #define EIGEN_STABLENORM_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename ExpressionType, typename Scalar> | ||||
| inline void stable_norm_kernel(const ExpressionType& bl, Scalar& ssq, Scalar& scale, Scalar& invScale) | ||||
| { | ||||
|   Scalar max = bl.cwiseAbs().maxCoeff(); | ||||
|   if (max>scale) | ||||
|   { | ||||
|     ssq = ssq * abs2(scale/max); | ||||
|     scale = max; | ||||
|     invScale = Scalar(1)/scale; | ||||
|   } | ||||
|   // TODO if the max is much much smaller than the current scale, | ||||
|   // then we can neglect this sub vector | ||||
|   ssq += (bl*invScale).squaredNorm(); | ||||
| } | ||||
| } | ||||
|  | ||||
| /** \returns the \em l2 norm of \c *this avoiding underflow and overflow. | ||||
|   * This version use a blockwise two passes algorithm: | ||||
|   *  1 - find the absolute largest coefficient \c s | ||||
|   *  2 - compute \f$ s \Vert \frac{*this}{s} \Vert \f$ in a standard way | ||||
|   * | ||||
|   * For architecture/scalar types supporting vectorization, this version | ||||
|   * is faster than blueNorm(). Otherwise the blueNorm() is much faster. | ||||
|   * | ||||
|   * \sa norm(), blueNorm(), hypotNorm() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real | ||||
| MatrixBase<Derived>::stableNorm() const | ||||
| { | ||||
|   using std::min; | ||||
|   const Index blockSize = 4096; | ||||
|   RealScalar scale(0); | ||||
|   RealScalar invScale(1); | ||||
|   RealScalar ssq(0); // sum of square | ||||
|   enum { | ||||
|     Alignment = (int(Flags)&DirectAccessBit) || (int(Flags)&AlignedBit) ? 1 : 0 | ||||
|   }; | ||||
|   Index n = size(); | ||||
|   Index bi = internal::first_aligned(derived()); | ||||
|   if (bi>0) | ||||
|     internal::stable_norm_kernel(this->head(bi), ssq, scale, invScale); | ||||
|   for (; bi<n; bi+=blockSize) | ||||
|     internal::stable_norm_kernel(this->segment(bi,(min)(blockSize, n - bi)).template forceAlignedAccessIf<Alignment>(), ssq, scale, invScale); | ||||
|   return scale * internal::sqrt(ssq); | ||||
| } | ||||
|  | ||||
| /** \returns the \em l2 norm of \c *this using the Blue's algorithm. | ||||
|   * A Portable Fortran Program to Find the Euclidean Norm of a Vector, | ||||
|   * ACM TOMS, Vol 4, Issue 1, 1978. | ||||
|   * | ||||
|   * For architecture/scalar types without vectorization, this version | ||||
|   * is much faster than stableNorm(). Otherwise the stableNorm() is faster. | ||||
|   * | ||||
|   * \sa norm(), stableNorm(), hypotNorm() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real | ||||
| MatrixBase<Derived>::blueNorm() const | ||||
| { | ||||
|   using std::pow; | ||||
|   using std::min; | ||||
|   using std::max; | ||||
|   static bool initialized = false; | ||||
|   static RealScalar b1, b2, s1m, s2m, overfl, rbig, relerr; | ||||
|   if(!initialized) | ||||
|   { | ||||
|     int ibeta, it, iemin, iemax, iexp; | ||||
|     RealScalar abig, eps; | ||||
|     // This program calculates the machine-dependent constants | ||||
|     // bl, b2, slm, s2m, relerr overfl | ||||
|     // from the "basic" machine-dependent numbers | ||||
|     // ibeta, it, iemin, iemax, rbig. | ||||
|     // The following define the basic machine-dependent constants. | ||||
|     // For portability, the PORT subprograms "ilmaeh" and "rlmach" | ||||
|     // are used. For any specific computer, each of the assignment | ||||
|     // statements can be replaced | ||||
|     ibeta = std::numeric_limits<RealScalar>::radix;         // base for floating-point numbers | ||||
|     it    = std::numeric_limits<RealScalar>::digits;        // number of base-beta digits in mantissa | ||||
|     iemin = std::numeric_limits<RealScalar>::min_exponent;  // minimum exponent | ||||
|     iemax = std::numeric_limits<RealScalar>::max_exponent;  // maximum exponent | ||||
|     rbig  = (std::numeric_limits<RealScalar>::max)();         // largest floating-point number | ||||
|  | ||||
|     iexp  = -((1-iemin)/2); | ||||
|     b1    = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp)));  // lower boundary of midrange | ||||
|     iexp  = (iemax + 1 - it)/2; | ||||
|     b2    = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp)));   // upper boundary of midrange | ||||
|  | ||||
|     iexp  = (2-iemin)/2; | ||||
|     s1m   = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp)));   // scaling factor for lower range | ||||
|     iexp  = - ((iemax+it)/2); | ||||
|     s2m   = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp)));   // scaling factor for upper range | ||||
|  | ||||
|     overfl  = rbig*s2m;             // overflow boundary for abig | ||||
|     eps     = RealScalar(pow(double(ibeta), 1-it)); | ||||
|     relerr  = internal::sqrt(eps);         // tolerance for neglecting asml | ||||
|     abig    = RealScalar(1.0/eps - 1.0); | ||||
|     initialized = true; | ||||
|   } | ||||
|   Index n = size(); | ||||
|   RealScalar ab2 = b2 / RealScalar(n); | ||||
|   RealScalar asml = RealScalar(0); | ||||
|   RealScalar amed = RealScalar(0); | ||||
|   RealScalar abig = RealScalar(0); | ||||
|   for(Index j=0; j<n; ++j) | ||||
|   { | ||||
|     RealScalar ax = internal::abs(coeff(j)); | ||||
|     if(ax > ab2)     abig += internal::abs2(ax*s2m); | ||||
|     else if(ax < b1) asml += internal::abs2(ax*s1m); | ||||
|     else             amed += internal::abs2(ax); | ||||
|   } | ||||
|   if(abig > RealScalar(0)) | ||||
|   { | ||||
|     abig = internal::sqrt(abig); | ||||
|     if(abig > overfl) | ||||
|     { | ||||
|       return rbig; | ||||
|     } | ||||
|     if(amed > RealScalar(0)) | ||||
|     { | ||||
|       abig = abig/s2m; | ||||
|       amed = internal::sqrt(amed); | ||||
|     } | ||||
|     else | ||||
|       return abig/s2m; | ||||
|   } | ||||
|   else if(asml > RealScalar(0)) | ||||
|   { | ||||
|     if (amed > RealScalar(0)) | ||||
|     { | ||||
|       abig = internal::sqrt(amed); | ||||
|       amed = internal::sqrt(asml) / s1m; | ||||
|     } | ||||
|     else | ||||
|       return internal::sqrt(asml)/s1m; | ||||
|   } | ||||
|   else | ||||
|     return internal::sqrt(amed); | ||||
|   asml = (min)(abig, amed); | ||||
|   abig = (max)(abig, amed); | ||||
|   if(asml <= abig*relerr) | ||||
|     return abig; | ||||
|   else | ||||
|     return abig * internal::sqrt(RealScalar(1) + internal::abs2(asml/abig)); | ||||
| } | ||||
|  | ||||
| /** \returns the \em l2 norm of \c *this avoiding undeflow and overflow. | ||||
|   * This version use a concatenation of hypot() calls, and it is very slow. | ||||
|   * | ||||
|   * \sa norm(), stableNorm() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real | ||||
| MatrixBase<Derived>::hypotNorm() const | ||||
| { | ||||
|   return this->cwiseAbs().redux(internal::scalar_hypot_op<RealScalar>()); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_STABLENORM_H | ||||
							
								
								
									
										108
									
								
								latan/Eigen/src/Core/Stride.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								latan/Eigen/src/Core/Stride.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_STRIDE_H | ||||
| #define EIGEN_STRIDE_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class Stride | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Holds strides information for Map | ||||
|   * | ||||
|   * This class holds the strides information for mapping arrays with strides with class Map. | ||||
|   * | ||||
|   * It holds two values: the inner stride and the outer stride. | ||||
|   * | ||||
|   * The inner stride is the pointer increment between two consecutive entries within a given row of a | ||||
|   * row-major matrix or within a given column of a column-major matrix. | ||||
|   * | ||||
|   * The outer stride is the pointer increment between two consecutive rows of a row-major matrix or | ||||
|   * between two consecutive columns of a column-major matrix. | ||||
|   * | ||||
|   * These two values can be passed either at compile-time as template parameters, or at runtime as | ||||
|   * arguments to the constructor. | ||||
|   * | ||||
|   * Indeed, this class takes two template parameters: | ||||
|   *  \param _OuterStrideAtCompileTime the outer stride, or Dynamic if you want to specify it at runtime. | ||||
|   *  \param _InnerStrideAtCompileTime the inner stride, or Dynamic if you want to specify it at runtime. | ||||
|   * | ||||
|   * Here is an example: | ||||
|   * \include Map_general_stride.cpp | ||||
|   * Output: \verbinclude Map_general_stride.out | ||||
|   * | ||||
|   * \sa class InnerStride, class OuterStride, \ref TopicStorageOrders | ||||
|   */ | ||||
| template<int _OuterStrideAtCompileTime, int _InnerStrideAtCompileTime> | ||||
| class Stride | ||||
| { | ||||
|   public: | ||||
|     typedef DenseIndex Index; | ||||
|     enum { | ||||
|       InnerStrideAtCompileTime = _InnerStrideAtCompileTime, | ||||
|       OuterStrideAtCompileTime = _OuterStrideAtCompileTime | ||||
|     }; | ||||
|  | ||||
|     /** Default constructor, for use when strides are fixed at compile time */ | ||||
|     Stride() | ||||
|       : m_outer(OuterStrideAtCompileTime), m_inner(InnerStrideAtCompileTime) | ||||
|     { | ||||
|       eigen_assert(InnerStrideAtCompileTime != Dynamic && OuterStrideAtCompileTime != Dynamic); | ||||
|     } | ||||
|  | ||||
|     /** Constructor allowing to pass the strides at runtime */ | ||||
|     Stride(Index outerStride, Index innerStride) | ||||
|       : m_outer(outerStride), m_inner(innerStride) | ||||
|     { | ||||
|       eigen_assert(innerStride>=0 && outerStride>=0); | ||||
|     } | ||||
|  | ||||
|     /** Copy constructor */ | ||||
|     Stride(const Stride& other) | ||||
|       : m_outer(other.outer()), m_inner(other.inner()) | ||||
|     {} | ||||
|  | ||||
|     /** \returns the outer stride */ | ||||
|     inline Index outer() const { return m_outer.value(); } | ||||
|     /** \returns the inner stride */ | ||||
|     inline Index inner() const { return m_inner.value(); } | ||||
|  | ||||
|   protected: | ||||
|     internal::variable_if_dynamic<Index, OuterStrideAtCompileTime> m_outer; | ||||
|     internal::variable_if_dynamic<Index, InnerStrideAtCompileTime> m_inner; | ||||
| }; | ||||
|  | ||||
| /** \brief Convenience specialization of Stride to specify only an inner stride | ||||
|   * See class Map for some examples */ | ||||
| template<int Value = Dynamic> | ||||
| class InnerStride : public Stride<0, Value> | ||||
| { | ||||
|     typedef Stride<0, Value> Base; | ||||
|   public: | ||||
|     typedef DenseIndex Index; | ||||
|     InnerStride() : Base() {} | ||||
|     InnerStride(Index v) : Base(0, v) {} | ||||
| }; | ||||
|  | ||||
| /** \brief Convenience specialization of Stride to specify only an outer stride | ||||
|   * See class Map for some examples */ | ||||
| template<int Value = Dynamic> | ||||
| class OuterStride : public Stride<Value, 0> | ||||
| { | ||||
|     typedef Stride<Value, 0> Base; | ||||
|   public: | ||||
|     typedef DenseIndex Index; | ||||
|     OuterStride() : Base() {} | ||||
|     OuterStride(Index v) : Base(v,0) {} | ||||
| }; | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_STRIDE_H | ||||
							
								
								
									
										126
									
								
								latan/Eigen/src/Core/Swap.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								latan/Eigen/src/Core/Swap.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_SWAP_H | ||||
| #define EIGEN_SWAP_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class SwapWrapper | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \internal | ||||
|   * | ||||
|   * \brief Internal helper class for swapping two expressions | ||||
|   */ | ||||
| namespace internal { | ||||
| template<typename ExpressionType> | ||||
| struct traits<SwapWrapper<ExpressionType> > : traits<ExpressionType> {}; | ||||
| } | ||||
|  | ||||
| template<typename ExpressionType> class SwapWrapper | ||||
|   : public internal::dense_xpr_base<SwapWrapper<ExpressionType> >::type | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef typename internal::dense_xpr_base<SwapWrapper>::type Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(SwapWrapper) | ||||
|     typedef typename internal::packet_traits<Scalar>::type Packet; | ||||
|  | ||||
|     inline SwapWrapper(ExpressionType& xpr) : m_expression(xpr) {} | ||||
|  | ||||
|     inline Index rows() const { return m_expression.rows(); } | ||||
|     inline Index cols() const { return m_expression.cols(); } | ||||
|     inline Index outerStride() const { return m_expression.outerStride(); } | ||||
|     inline Index innerStride() const { return m_expression.innerStride(); } | ||||
|      | ||||
|     typedef typename internal::conditional< | ||||
|                        internal::is_lvalue<ExpressionType>::value, | ||||
|                        Scalar, | ||||
|                        const Scalar | ||||
|                      >::type ScalarWithConstIfNotLvalue; | ||||
|                       | ||||
|     inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); } | ||||
|     inline const Scalar* data() const { return m_expression.data(); } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index row, Index col) | ||||
|     { | ||||
|       return m_expression.const_cast_derived().coeffRef(row, col); | ||||
|     } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index index) | ||||
|     { | ||||
|       return m_expression.const_cast_derived().coeffRef(index); | ||||
|     } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index row, Index col) const | ||||
|     { | ||||
|       return m_expression.coeffRef(row, col); | ||||
|     } | ||||
|  | ||||
|     inline Scalar& coeffRef(Index index) const | ||||
|     { | ||||
|       return m_expression.coeffRef(index); | ||||
|     } | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     void copyCoeff(Index row, Index col, const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       OtherDerived& _other = other.const_cast_derived(); | ||||
|       eigen_internal_assert(row >= 0 && row < rows() | ||||
|                          && col >= 0 && col < cols()); | ||||
|       Scalar tmp = m_expression.coeff(row, col); | ||||
|       m_expression.coeffRef(row, col) = _other.coeff(row, col); | ||||
|       _other.coeffRef(row, col) = tmp; | ||||
|     } | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     void copyCoeff(Index index, const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       OtherDerived& _other = other.const_cast_derived(); | ||||
|       eigen_internal_assert(index >= 0 && index < m_expression.size()); | ||||
|       Scalar tmp = m_expression.coeff(index); | ||||
|       m_expression.coeffRef(index) = _other.coeff(index); | ||||
|       _other.coeffRef(index) = tmp; | ||||
|     } | ||||
|  | ||||
|     template<typename OtherDerived, int StoreMode, int LoadMode> | ||||
|     void copyPacket(Index row, Index col, const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       OtherDerived& _other = other.const_cast_derived(); | ||||
|       eigen_internal_assert(row >= 0 && row < rows() | ||||
|                         && col >= 0 && col < cols()); | ||||
|       Packet tmp = m_expression.template packet<StoreMode>(row, col); | ||||
|       m_expression.template writePacket<StoreMode>(row, col, | ||||
|         _other.template packet<LoadMode>(row, col) | ||||
|       ); | ||||
|       _other.template writePacket<LoadMode>(row, col, tmp); | ||||
|     } | ||||
|  | ||||
|     template<typename OtherDerived, int StoreMode, int LoadMode> | ||||
|     void copyPacket(Index index, const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       OtherDerived& _other = other.const_cast_derived(); | ||||
|       eigen_internal_assert(index >= 0 && index < m_expression.size()); | ||||
|       Packet tmp = m_expression.template packet<StoreMode>(index); | ||||
|       m_expression.template writePacket<StoreMode>(index, | ||||
|         _other.template packet<LoadMode>(index) | ||||
|       ); | ||||
|       _other.template writePacket<LoadMode>(index, tmp); | ||||
|     } | ||||
|  | ||||
|     ExpressionType& expression() const { return m_expression; } | ||||
|  | ||||
|   protected: | ||||
|     ExpressionType& m_expression; | ||||
| }; | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_SWAP_H | ||||
							
								
								
									
										414
									
								
								latan/Eigen/src/Core/Transpose.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										414
									
								
								latan/Eigen/src/Core/Transpose.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,414 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_TRANSPOSE_H | ||||
| #define EIGEN_TRANSPOSE_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class Transpose | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Expression of the transpose of a matrix | ||||
|   * | ||||
|   * \param MatrixType the type of the object of which we are taking the transpose | ||||
|   * | ||||
|   * This class represents an expression of the transpose of a matrix. | ||||
|   * It is the return type of MatrixBase::transpose() and MatrixBase::adjoint() | ||||
|   * and most of the time this is the only way it is used. | ||||
|   * | ||||
|   * \sa MatrixBase::transpose(), MatrixBase::adjoint() | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename MatrixType> | ||||
| struct traits<Transpose<MatrixType> > : traits<MatrixType> | ||||
| { | ||||
|   typedef typename MatrixType::Scalar Scalar; | ||||
|   typedef typename nested<MatrixType>::type MatrixTypeNested; | ||||
|   typedef typename remove_reference<MatrixTypeNested>::type MatrixTypeNestedPlain; | ||||
|   typedef typename traits<MatrixType>::StorageKind StorageKind; | ||||
|   typedef typename traits<MatrixType>::XprKind XprKind; | ||||
|   enum { | ||||
|     RowsAtCompileTime = MatrixType::ColsAtCompileTime, | ||||
|     ColsAtCompileTime = MatrixType::RowsAtCompileTime, | ||||
|     MaxRowsAtCompileTime = MatrixType::MaxColsAtCompileTime, | ||||
|     MaxColsAtCompileTime = MatrixType::MaxRowsAtCompileTime, | ||||
|     FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0, | ||||
|     Flags0 = MatrixTypeNestedPlain::Flags & ~(LvalueBit | NestByRefBit), | ||||
|     Flags1 = Flags0 | FlagsLvalueBit, | ||||
|     Flags = Flags1 ^ RowMajorBit, | ||||
|     CoeffReadCost = MatrixTypeNestedPlain::CoeffReadCost, | ||||
|     InnerStrideAtCompileTime = inner_stride_at_compile_time<MatrixType>::ret, | ||||
|     OuterStrideAtCompileTime = outer_stride_at_compile_time<MatrixType>::ret | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename MatrixType, typename StorageKind> class TransposeImpl; | ||||
|  | ||||
| template<typename MatrixType> class Transpose | ||||
|   : public TransposeImpl<MatrixType,typename internal::traits<MatrixType>::StorageKind> | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef typename TransposeImpl<MatrixType,typename internal::traits<MatrixType>::StorageKind>::Base Base; | ||||
|     EIGEN_GENERIC_PUBLIC_INTERFACE(Transpose) | ||||
|  | ||||
|     inline Transpose(MatrixType& matrix) : m_matrix(matrix) {} | ||||
|  | ||||
|     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Transpose) | ||||
|  | ||||
|     inline Index rows() const { return m_matrix.cols(); } | ||||
|     inline Index cols() const { return m_matrix.rows(); } | ||||
|  | ||||
|     /** \returns the nested expression */ | ||||
|     const typename internal::remove_all<typename MatrixType::Nested>::type& | ||||
|     nestedExpression() const { return m_matrix; } | ||||
|  | ||||
|     /** \returns the nested expression */ | ||||
|     typename internal::remove_all<typename MatrixType::Nested>::type& | ||||
|     nestedExpression() { return m_matrix.const_cast_derived(); } | ||||
|  | ||||
|   protected: | ||||
|     typename MatrixType::Nested m_matrix; | ||||
| }; | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename MatrixType, bool HasDirectAccess = has_direct_access<MatrixType>::ret> | ||||
| struct TransposeImpl_base | ||||
| { | ||||
|   typedef typename dense_xpr_base<Transpose<MatrixType> >::type type; | ||||
| }; | ||||
|  | ||||
| template<typename MatrixType> | ||||
| struct TransposeImpl_base<MatrixType, false> | ||||
| { | ||||
|   typedef typename dense_xpr_base<Transpose<MatrixType> >::type type; | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| template<typename MatrixType> class TransposeImpl<MatrixType,Dense> | ||||
|   : public internal::TransposeImpl_base<MatrixType>::type | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef typename internal::TransposeImpl_base<MatrixType>::type Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>) | ||||
|  | ||||
|     inline Index innerStride() const { return derived().nestedExpression().innerStride(); } | ||||
|     inline Index outerStride() const { return derived().nestedExpression().outerStride(); } | ||||
|  | ||||
|     typedef typename internal::conditional< | ||||
|                        internal::is_lvalue<MatrixType>::value, | ||||
|                        Scalar, | ||||
|                        const Scalar | ||||
|                      >::type ScalarWithConstIfNotLvalue; | ||||
|  | ||||
|     inline ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); } | ||||
|     inline const Scalar* data() const { return derived().nestedExpression().data(); } | ||||
|  | ||||
|     inline ScalarWithConstIfNotLvalue& coeffRef(Index row, Index col) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_LVALUE(MatrixType) | ||||
|       return derived().nestedExpression().const_cast_derived().coeffRef(col, row); | ||||
|     } | ||||
|  | ||||
|     inline ScalarWithConstIfNotLvalue& coeffRef(Index index) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_LVALUE(MatrixType) | ||||
|       return derived().nestedExpression().const_cast_derived().coeffRef(index); | ||||
|     } | ||||
|  | ||||
|     inline const Scalar& coeffRef(Index row, Index col) const | ||||
|     { | ||||
|       return derived().nestedExpression().coeffRef(col, row); | ||||
|     } | ||||
|  | ||||
|     inline const Scalar& coeffRef(Index index) const | ||||
|     { | ||||
|       return derived().nestedExpression().coeffRef(index); | ||||
|     } | ||||
|  | ||||
|     inline CoeffReturnType coeff(Index row, Index col) const | ||||
|     { | ||||
|       return derived().nestedExpression().coeff(col, row); | ||||
|     } | ||||
|  | ||||
|     inline CoeffReturnType coeff(Index index) const | ||||
|     { | ||||
|       return derived().nestedExpression().coeff(index); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline const PacketScalar packet(Index row, Index col) const | ||||
|     { | ||||
|       return derived().nestedExpression().template packet<LoadMode>(col, row); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline void writePacket(Index row, Index col, const PacketScalar& x) | ||||
|     { | ||||
|       derived().nestedExpression().const_cast_derived().template writePacket<LoadMode>(col, row, x); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline const PacketScalar packet(Index index) const | ||||
|     { | ||||
|       return derived().nestedExpression().template packet<LoadMode>(index); | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     inline void writePacket(Index index, const PacketScalar& x) | ||||
|     { | ||||
|       derived().nestedExpression().const_cast_derived().template writePacket<LoadMode>(index, x); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| /** \returns an expression of the transpose of *this. | ||||
|   * | ||||
|   * Example: \include MatrixBase_transpose.cpp | ||||
|   * Output: \verbinclude MatrixBase_transpose.out | ||||
|   * | ||||
|   * \warning If you want to replace a matrix by its own transpose, do \b NOT do this: | ||||
|   * \code | ||||
|   * m = m.transpose(); // bug!!! caused by aliasing effect | ||||
|   * \endcode | ||||
|   * Instead, use the transposeInPlace() method: | ||||
|   * \code | ||||
|   * m.transposeInPlace(); | ||||
|   * \endcode | ||||
|   * which gives Eigen good opportunities for optimization, or alternatively you can also do: | ||||
|   * \code | ||||
|   * m = m.transpose().eval(); | ||||
|   * \endcode | ||||
|   * | ||||
|   * \sa transposeInPlace(), adjoint() */ | ||||
| template<typename Derived> | ||||
| inline Transpose<Derived> | ||||
| DenseBase<Derived>::transpose() | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| /** This is the const version of transpose(). | ||||
|   * | ||||
|   * Make sure you read the warning for transpose() ! | ||||
|   * | ||||
|   * \sa transposeInPlace(), adjoint() */ | ||||
| template<typename Derived> | ||||
| inline const typename DenseBase<Derived>::ConstTransposeReturnType | ||||
| DenseBase<Derived>::transpose() const | ||||
| { | ||||
|   return ConstTransposeReturnType(derived()); | ||||
| } | ||||
|  | ||||
| /** \returns an expression of the adjoint (i.e. conjugate transpose) of *this. | ||||
|   * | ||||
|   * Example: \include MatrixBase_adjoint.cpp | ||||
|   * Output: \verbinclude MatrixBase_adjoint.out | ||||
|   * | ||||
|   * \warning If you want to replace a matrix by its own adjoint, do \b NOT do this: | ||||
|   * \code | ||||
|   * m = m.adjoint(); // bug!!! caused by aliasing effect | ||||
|   * \endcode | ||||
|   * Instead, use the adjointInPlace() method: | ||||
|   * \code | ||||
|   * m.adjointInPlace(); | ||||
|   * \endcode | ||||
|   * which gives Eigen good opportunities for optimization, or alternatively you can also do: | ||||
|   * \code | ||||
|   * m = m.adjoint().eval(); | ||||
|   * \endcode | ||||
|   * | ||||
|   * \sa adjointInPlace(), transpose(), conjugate(), class Transpose, class internal::scalar_conjugate_op */ | ||||
| template<typename Derived> | ||||
| inline const typename MatrixBase<Derived>::AdjointReturnType | ||||
| MatrixBase<Derived>::adjoint() const | ||||
| { | ||||
|   return this->transpose(); // in the complex case, the .conjugate() is be implicit here | ||||
|                             // due to implicit conversion to return type | ||||
| } | ||||
|  | ||||
| /*************************************************************************** | ||||
| * "in place" transpose implementation | ||||
| ***************************************************************************/ | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename MatrixType, | ||||
|   bool IsSquare = (MatrixType::RowsAtCompileTime == MatrixType::ColsAtCompileTime) && MatrixType::RowsAtCompileTime!=Dynamic> | ||||
| struct inplace_transpose_selector; | ||||
|  | ||||
| template<typename MatrixType> | ||||
| struct inplace_transpose_selector<MatrixType,true> { // square matrix | ||||
|   static void run(MatrixType& m) { | ||||
|     m.template triangularView<StrictlyUpper>().swap(m.transpose()); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename MatrixType> | ||||
| struct inplace_transpose_selector<MatrixType,false> { // non square matrix | ||||
|   static void run(MatrixType& m) { | ||||
|     if (m.rows()==m.cols()) | ||||
|       m.template triangularView<StrictlyUpper>().swap(m.transpose()); | ||||
|     else | ||||
|       m = m.transpose().eval(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /** This is the "in place" version of transpose(): it replaces \c *this by its own transpose. | ||||
|   * Thus, doing | ||||
|   * \code | ||||
|   * m.transposeInPlace(); | ||||
|   * \endcode | ||||
|   * has the same effect on m as doing | ||||
|   * \code | ||||
|   * m = m.transpose().eval(); | ||||
|   * \endcode | ||||
|   * and is faster and also safer because in the latter line of code, forgetting the eval() results | ||||
|   * in a bug caused by aliasing. | ||||
|   * | ||||
|   * Notice however that this method is only useful if you want to replace a matrix by its own transpose. | ||||
|   * If you just need the transpose of a matrix, use transpose(). | ||||
|   * | ||||
|   * \note if the matrix is not square, then \c *this must be a resizable matrix. | ||||
|   * | ||||
|   * \sa transpose(), adjoint(), adjointInPlace() */ | ||||
| template<typename Derived> | ||||
| inline void DenseBase<Derived>::transposeInPlace() | ||||
| { | ||||
|   internal::inplace_transpose_selector<Derived>::run(derived()); | ||||
| } | ||||
|  | ||||
| /*************************************************************************** | ||||
| * "in place" adjoint implementation | ||||
| ***************************************************************************/ | ||||
|  | ||||
| /** This is the "in place" version of adjoint(): it replaces \c *this by its own transpose. | ||||
|   * Thus, doing | ||||
|   * \code | ||||
|   * m.adjointInPlace(); | ||||
|   * \endcode | ||||
|   * has the same effect on m as doing | ||||
|   * \code | ||||
|   * m = m.adjoint().eval(); | ||||
|   * \endcode | ||||
|   * and is faster and also safer because in the latter line of code, forgetting the eval() results | ||||
|   * in a bug caused by aliasing. | ||||
|   * | ||||
|   * Notice however that this method is only useful if you want to replace a matrix by its own adjoint. | ||||
|   * If you just need the adjoint of a matrix, use adjoint(). | ||||
|   * | ||||
|   * \note if the matrix is not square, then \c *this must be a resizable matrix. | ||||
|   * | ||||
|   * \sa transpose(), adjoint(), transposeInPlace() */ | ||||
| template<typename Derived> | ||||
| inline void MatrixBase<Derived>::adjointInPlace() | ||||
| { | ||||
|   derived() = adjoint().eval(); | ||||
| } | ||||
|  | ||||
| #ifndef EIGEN_NO_DEBUG | ||||
|  | ||||
| // The following is to detect aliasing problems in most common cases. | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename BinOp,typename NestedXpr,typename Rhs> | ||||
| struct blas_traits<SelfCwiseBinaryOp<BinOp,NestedXpr,Rhs> > | ||||
|  : blas_traits<NestedXpr> | ||||
| { | ||||
|   typedef SelfCwiseBinaryOp<BinOp,NestedXpr,Rhs> XprType; | ||||
|   static inline const XprType extract(const XprType& x) { return x; } | ||||
| }; | ||||
|  | ||||
| template<bool DestIsTransposed, typename OtherDerived> | ||||
| struct check_transpose_aliasing_compile_time_selector | ||||
| { | ||||
|   enum { ret = bool(blas_traits<OtherDerived>::IsTransposed) != DestIsTransposed }; | ||||
| }; | ||||
|  | ||||
| template<bool DestIsTransposed, typename BinOp, typename DerivedA, typename DerivedB> | ||||
| struct check_transpose_aliasing_compile_time_selector<DestIsTransposed,CwiseBinaryOp<BinOp,DerivedA,DerivedB> > | ||||
| { | ||||
|   enum { ret =    bool(blas_traits<DerivedA>::IsTransposed) != DestIsTransposed | ||||
|                || bool(blas_traits<DerivedB>::IsTransposed) != DestIsTransposed | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| template<typename Scalar, bool DestIsTransposed, typename OtherDerived> | ||||
| struct check_transpose_aliasing_run_time_selector | ||||
| { | ||||
|   static bool run(const Scalar* dest, const OtherDerived& src) | ||||
|   { | ||||
|     return (bool(blas_traits<OtherDerived>::IsTransposed) != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src)); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar, bool DestIsTransposed, typename BinOp, typename DerivedA, typename DerivedB> | ||||
| struct check_transpose_aliasing_run_time_selector<Scalar,DestIsTransposed,CwiseBinaryOp<BinOp,DerivedA,DerivedB> > | ||||
| { | ||||
|   static bool run(const Scalar* dest, const CwiseBinaryOp<BinOp,DerivedA,DerivedB>& src) | ||||
|   { | ||||
|     return ((blas_traits<DerivedA>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src.lhs()))) | ||||
|         || ((blas_traits<DerivedB>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src.rhs()))); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // the following selector, checkTransposeAliasing_impl, based on MightHaveTransposeAliasing, | ||||
| // is because when the condition controlling the assert is known at compile time, ICC emits a warning. | ||||
| // This is actually a good warning: in expressions that don't have any transposing, the condition is | ||||
| // known at compile time to be false, and using that, we can avoid generating the code of the assert again | ||||
| // and again for all these expressions that don't need it. | ||||
|  | ||||
| template<typename Derived, typename OtherDerived, | ||||
|          bool MightHaveTransposeAliasing | ||||
|                  = check_transpose_aliasing_compile_time_selector | ||||
|                      <blas_traits<Derived>::IsTransposed,OtherDerived>::ret | ||||
|         > | ||||
| struct checkTransposeAliasing_impl | ||||
| { | ||||
|     static void run(const Derived& dst, const OtherDerived& other) | ||||
|     { | ||||
|         eigen_assert((!check_transpose_aliasing_run_time_selector | ||||
|                       <typename Derived::Scalar,blas_traits<Derived>::IsTransposed,OtherDerived> | ||||
|                       ::run(extract_data(dst), other)) | ||||
|           && "aliasing detected during tranposition, use transposeInPlace() " | ||||
|              "or evaluate the rhs into a temporary using .eval()"); | ||||
|  | ||||
|     } | ||||
| }; | ||||
|  | ||||
| template<typename Derived, typename OtherDerived> | ||||
| struct checkTransposeAliasing_impl<Derived, OtherDerived, false> | ||||
| { | ||||
|     static void run(const Derived&, const OtherDerived&) | ||||
|     { | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| template<typename Derived> | ||||
| template<typename OtherDerived> | ||||
| void DenseBase<Derived>::checkTransposeAliasing(const OtherDerived& other) const | ||||
| { | ||||
|     internal::checkTransposeAliasing_impl<Derived, OtherDerived>::run(derived(), other); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_TRANSPOSE_H | ||||
							
								
								
									
										436
									
								
								latan/Eigen/src/Core/Transpositions.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										436
									
								
								latan/Eigen/src/Core/Transpositions.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,436 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2010-2011 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_TRANSPOSITIONS_H | ||||
| #define EIGEN_TRANSPOSITIONS_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class Transpositions | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Represents a sequence of transpositions (row/column interchange) | ||||
|   * | ||||
|   * \param SizeAtCompileTime the number of transpositions, or Dynamic | ||||
|   * \param MaxSizeAtCompileTime the maximum number of transpositions, or Dynamic. This optional parameter defaults to SizeAtCompileTime. Most of the time, you should not have to specify it. | ||||
|   * | ||||
|   * This class represents a permutation transformation as a sequence of \em n transpositions | ||||
|   * \f$[T_{n-1} \ldots T_{i} \ldots T_{0}]\f$. It is internally stored as a vector of integers \c indices. | ||||
|   * Each transposition \f$ T_{i} \f$ applied on the left of a matrix (\f$ T_{i} M\f$) interchanges | ||||
|   * the rows \c i and \c indices[i] of the matrix \c M. | ||||
|   * A transposition applied on the right (e.g., \f$ M T_{i}\f$) yields a column interchange. | ||||
|   * | ||||
|   * Compared to the class PermutationMatrix, such a sequence of transpositions is what is | ||||
|   * computed during a decomposition with pivoting, and it is faster when applying the permutation in-place. | ||||
|   *  | ||||
|   * To apply a sequence of transpositions to a matrix, simply use the operator * as in the following example: | ||||
|   * \code | ||||
|   * Transpositions tr; | ||||
|   * MatrixXf mat; | ||||
|   * mat = tr * mat; | ||||
|   * \endcode | ||||
|   * In this example, we detect that the matrix appears on both side, and so the transpositions | ||||
|   * are applied in-place without any temporary or extra copy. | ||||
|   * | ||||
|   * \sa class PermutationMatrix | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename TranspositionType, typename MatrixType, int Side, bool Transposed=false> struct transposition_matrix_product_retval; | ||||
| } | ||||
|  | ||||
| template<typename Derived> | ||||
| class TranspositionsBase | ||||
| { | ||||
|     typedef internal::traits<Derived> Traits; | ||||
|      | ||||
|   public: | ||||
|  | ||||
|     typedef typename Traits::IndicesType IndicesType; | ||||
|     typedef typename IndicesType::Scalar Index; | ||||
|  | ||||
|     Derived& derived() { return *static_cast<Derived*>(this); } | ||||
|     const Derived& derived() const { return *static_cast<const Derived*>(this); } | ||||
|  | ||||
|     /** Copies the \a other transpositions into \c *this */ | ||||
|     template<typename OtherDerived> | ||||
|     Derived& operator=(const TranspositionsBase<OtherDerived>& other) | ||||
|     { | ||||
|       indices() = other.indices(); | ||||
|       return derived(); | ||||
|     } | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /** This is a special case of the templated operator=. Its purpose is to | ||||
|       * prevent a default operator= from hiding the templated operator=. | ||||
|       */ | ||||
|     Derived& operator=(const TranspositionsBase& other) | ||||
|     { | ||||
|       indices() = other.indices(); | ||||
|       return derived(); | ||||
|     } | ||||
|     #endif | ||||
|  | ||||
|     /** \returns the number of transpositions */ | ||||
|     inline Index size() const { return indices().size(); } | ||||
|  | ||||
|     /** Direct access to the underlying index vector */ | ||||
|     inline const Index& coeff(Index i) const { return indices().coeff(i); } | ||||
|     /** Direct access to the underlying index vector */ | ||||
|     inline Index& coeffRef(Index i) { return indices().coeffRef(i); } | ||||
|     /** Direct access to the underlying index vector */ | ||||
|     inline const Index& operator()(Index i) const { return indices()(i); } | ||||
|     /** Direct access to the underlying index vector */ | ||||
|     inline Index& operator()(Index i) { return indices()(i); } | ||||
|     /** Direct access to the underlying index vector */ | ||||
|     inline const Index& operator[](Index i) const { return indices()(i); } | ||||
|     /** Direct access to the underlying index vector */ | ||||
|     inline Index& operator[](Index i) { return indices()(i); } | ||||
|  | ||||
|     /** const version of indices(). */ | ||||
|     const IndicesType& indices() const { return derived().indices(); } | ||||
|     /** \returns a reference to the stored array representing the transpositions. */ | ||||
|     IndicesType& indices() { return derived().indices(); } | ||||
|  | ||||
|     /** Resizes to given size. */ | ||||
|     inline void resize(int size) | ||||
|     { | ||||
|       indices().resize(size); | ||||
|     } | ||||
|  | ||||
|     /** Sets \c *this to represents an identity transformation */ | ||||
|     void setIdentity() | ||||
|     { | ||||
|       for(int i = 0; i < indices().size(); ++i) | ||||
|         coeffRef(i) = i; | ||||
|     } | ||||
|  | ||||
|     // FIXME: do we want such methods ? | ||||
|     // might be usefull when the target matrix expression is complex, e.g.: | ||||
|     // object.matrix().block(..,..,..,..) = trans * object.matrix().block(..,..,..,..); | ||||
|     /* | ||||
|     template<typename MatrixType> | ||||
|     void applyForwardToRows(MatrixType& mat) const | ||||
|     { | ||||
|       for(Index k=0 ; k<size() ; ++k) | ||||
|         if(m_indices(k)!=k) | ||||
|           mat.row(k).swap(mat.row(m_indices(k))); | ||||
|     } | ||||
|  | ||||
|     template<typename MatrixType> | ||||
|     void applyBackwardToRows(MatrixType& mat) const | ||||
|     { | ||||
|       for(Index k=size()-1 ; k>=0 ; --k) | ||||
|         if(m_indices(k)!=k) | ||||
|           mat.row(k).swap(mat.row(m_indices(k))); | ||||
|     } | ||||
|     */ | ||||
|  | ||||
|     /** \returns the inverse transformation */ | ||||
|     inline Transpose<TranspositionsBase> inverse() const | ||||
|     { return Transpose<TranspositionsBase>(derived()); } | ||||
|  | ||||
|     /** \returns the tranpose transformation */ | ||||
|     inline Transpose<TranspositionsBase> transpose() const | ||||
|     { return Transpose<TranspositionsBase>(derived()); } | ||||
|  | ||||
|   protected: | ||||
| }; | ||||
|  | ||||
| namespace internal { | ||||
| template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType> | ||||
| struct traits<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType> > | ||||
| { | ||||
|   typedef IndexType Index; | ||||
|   typedef Matrix<Index, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType> | ||||
| class Transpositions : public TranspositionsBase<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType> > | ||||
| { | ||||
|     typedef internal::traits<Transpositions> Traits; | ||||
|   public: | ||||
|  | ||||
|     typedef TranspositionsBase<Transpositions> Base; | ||||
|     typedef typename Traits::IndicesType IndicesType; | ||||
|     typedef typename IndicesType::Scalar Index; | ||||
|  | ||||
|     inline Transpositions() {} | ||||
|  | ||||
|     /** Copy constructor. */ | ||||
|     template<typename OtherDerived> | ||||
|     inline Transpositions(const TranspositionsBase<OtherDerived>& other) | ||||
|       : m_indices(other.indices()) {} | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /** Standard copy constructor. Defined only to prevent a default copy constructor | ||||
|       * from hiding the other templated constructor */ | ||||
|     inline Transpositions(const Transpositions& other) : m_indices(other.indices()) {} | ||||
|     #endif | ||||
|  | ||||
|     /** Generic constructor from expression of the transposition indices. */ | ||||
|     template<typename Other> | ||||
|     explicit inline Transpositions(const MatrixBase<Other>& indices) : m_indices(indices) | ||||
|     {} | ||||
|  | ||||
|     /** Copies the \a other transpositions into \c *this */ | ||||
|     template<typename OtherDerived> | ||||
|     Transpositions& operator=(const TranspositionsBase<OtherDerived>& other) | ||||
|     { | ||||
|       return Base::operator=(other); | ||||
|     } | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /** This is a special case of the templated operator=. Its purpose is to | ||||
|       * prevent a default operator= from hiding the templated operator=. | ||||
|       */ | ||||
|     Transpositions& operator=(const Transpositions& other) | ||||
|     { | ||||
|       m_indices = other.m_indices; | ||||
|       return *this; | ||||
|     } | ||||
|     #endif | ||||
|  | ||||
|     /** Constructs an uninitialized permutation matrix of given size. | ||||
|       */ | ||||
|     inline Transpositions(Index size) : m_indices(size) | ||||
|     {} | ||||
|  | ||||
|     /** const version of indices(). */ | ||||
|     const IndicesType& indices() const { return m_indices; } | ||||
|     /** \returns a reference to the stored array representing the transpositions. */ | ||||
|     IndicesType& indices() { return m_indices; } | ||||
|  | ||||
|   protected: | ||||
|  | ||||
|     IndicesType m_indices; | ||||
| }; | ||||
|  | ||||
|  | ||||
| namespace internal { | ||||
| template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int _PacketAccess> | ||||
| struct traits<Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,_PacketAccess> > | ||||
| { | ||||
|   typedef IndexType Index; | ||||
|   typedef Map<const Matrix<Index,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1>, _PacketAccess> IndicesType; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int PacketAccess> | ||||
| class Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,PacketAccess> | ||||
|  : public TranspositionsBase<Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,PacketAccess> > | ||||
| { | ||||
|     typedef internal::traits<Map> Traits; | ||||
|   public: | ||||
|  | ||||
|     typedef TranspositionsBase<Map> Base; | ||||
|     typedef typename Traits::IndicesType IndicesType; | ||||
|     typedef typename IndicesType::Scalar Index; | ||||
|  | ||||
|     inline Map(const Index* indices) | ||||
|       : m_indices(indices) | ||||
|     {} | ||||
|  | ||||
|     inline Map(const Index* indices, Index size) | ||||
|       : m_indices(indices,size) | ||||
|     {} | ||||
|  | ||||
|     /** Copies the \a other transpositions into \c *this */ | ||||
|     template<typename OtherDerived> | ||||
|     Map& operator=(const TranspositionsBase<OtherDerived>& other) | ||||
|     { | ||||
|       return Base::operator=(other); | ||||
|     } | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /** This is a special case of the templated operator=. Its purpose is to | ||||
|       * prevent a default operator= from hiding the templated operator=. | ||||
|       */ | ||||
|     Map& operator=(const Map& other) | ||||
|     { | ||||
|       m_indices = other.m_indices; | ||||
|       return *this; | ||||
|     } | ||||
|     #endif | ||||
|  | ||||
|     /** const version of indices(). */ | ||||
|     const IndicesType& indices() const { return m_indices; } | ||||
|      | ||||
|     /** \returns a reference to the stored array representing the transpositions. */ | ||||
|     IndicesType& indices() { return m_indices; } | ||||
|  | ||||
|   protected: | ||||
|  | ||||
|     IndicesType m_indices; | ||||
| }; | ||||
|  | ||||
| namespace internal { | ||||
| template<typename _IndicesType> | ||||
| struct traits<TranspositionsWrapper<_IndicesType> > | ||||
| { | ||||
|   typedef typename _IndicesType::Scalar Index; | ||||
|   typedef _IndicesType IndicesType; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename _IndicesType> | ||||
| class TranspositionsWrapper | ||||
|  : public TranspositionsBase<TranspositionsWrapper<_IndicesType> > | ||||
| { | ||||
|     typedef internal::traits<TranspositionsWrapper> Traits; | ||||
|   public: | ||||
|  | ||||
|     typedef TranspositionsBase<TranspositionsWrapper> Base; | ||||
|     typedef typename Traits::IndicesType IndicesType; | ||||
|     typedef typename IndicesType::Scalar Index; | ||||
|  | ||||
|     inline TranspositionsWrapper(IndicesType& indices) | ||||
|       : m_indices(indices) | ||||
|     {} | ||||
|  | ||||
|     /** Copies the \a other transpositions into \c *this */ | ||||
|     template<typename OtherDerived> | ||||
|     TranspositionsWrapper& operator=(const TranspositionsBase<OtherDerived>& other) | ||||
|     { | ||||
|       return Base::operator=(other); | ||||
|     } | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     /** This is a special case of the templated operator=. Its purpose is to | ||||
|       * prevent a default operator= from hiding the templated operator=. | ||||
|       */ | ||||
|     TranspositionsWrapper& operator=(const TranspositionsWrapper& other) | ||||
|     { | ||||
|       m_indices = other.m_indices; | ||||
|       return *this; | ||||
|     } | ||||
|     #endif | ||||
|  | ||||
|     /** const version of indices(). */ | ||||
|     const IndicesType& indices() const { return m_indices; } | ||||
|  | ||||
|     /** \returns a reference to the stored array representing the transpositions. */ | ||||
|     IndicesType& indices() { return m_indices; } | ||||
|  | ||||
|   protected: | ||||
|  | ||||
|     const typename IndicesType::Nested m_indices; | ||||
| }; | ||||
|  | ||||
| /** \returns the \a matrix with the \a transpositions applied to the columns. | ||||
|   */ | ||||
| template<typename Derived, typename TranspositionsDerived> | ||||
| inline const internal::transposition_matrix_product_retval<TranspositionsDerived, Derived, OnTheRight> | ||||
| operator*(const MatrixBase<Derived>& matrix, | ||||
|           const TranspositionsBase<TranspositionsDerived> &transpositions) | ||||
| { | ||||
|   return internal::transposition_matrix_product_retval | ||||
|            <TranspositionsDerived, Derived, OnTheRight> | ||||
|            (transpositions.derived(), matrix.derived()); | ||||
| } | ||||
|  | ||||
| /** \returns the \a matrix with the \a transpositions applied to the rows. | ||||
|   */ | ||||
| template<typename Derived, typename TranspositionDerived> | ||||
| inline const internal::transposition_matrix_product_retval | ||||
|                <TranspositionDerived, Derived, OnTheLeft> | ||||
| operator*(const TranspositionsBase<TranspositionDerived> &transpositions, | ||||
|           const MatrixBase<Derived>& matrix) | ||||
| { | ||||
|   return internal::transposition_matrix_product_retval | ||||
|            <TranspositionDerived, Derived, OnTheLeft> | ||||
|            (transpositions.derived(), matrix.derived()); | ||||
| } | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename TranspositionType, typename MatrixType, int Side, bool Transposed> | ||||
| struct traits<transposition_matrix_product_retval<TranspositionType, MatrixType, Side, Transposed> > | ||||
| { | ||||
|   typedef typename MatrixType::PlainObject ReturnType; | ||||
| }; | ||||
|  | ||||
| template<typename TranspositionType, typename MatrixType, int Side, bool Transposed> | ||||
| struct transposition_matrix_product_retval | ||||
|  : public ReturnByValue<transposition_matrix_product_retval<TranspositionType, MatrixType, Side, Transposed> > | ||||
| { | ||||
|     typedef typename remove_all<typename MatrixType::Nested>::type MatrixTypeNestedCleaned; | ||||
|     typedef typename TranspositionType::Index Index; | ||||
|  | ||||
|     transposition_matrix_product_retval(const TranspositionType& tr, const MatrixType& matrix) | ||||
|       : m_transpositions(tr), m_matrix(matrix) | ||||
|     {} | ||||
|  | ||||
|     inline int rows() const { return m_matrix.rows(); } | ||||
|     inline int cols() const { return m_matrix.cols(); } | ||||
|  | ||||
|     template<typename Dest> inline void evalTo(Dest& dst) const | ||||
|     { | ||||
|       const int size = m_transpositions.size(); | ||||
|       Index j = 0; | ||||
|  | ||||
|       if(!(is_same<MatrixTypeNestedCleaned,Dest>::value && extract_data(dst) == extract_data(m_matrix))) | ||||
|         dst = m_matrix; | ||||
|  | ||||
|       for(int k=(Transposed?size-1:0) ; Transposed?k>=0:k<size ; Transposed?--k:++k) | ||||
|         if((j=m_transpositions.coeff(k))!=k) | ||||
|         { | ||||
|           if(Side==OnTheLeft) | ||||
|             dst.row(k).swap(dst.row(j)); | ||||
|           else if(Side==OnTheRight) | ||||
|             dst.col(k).swap(dst.col(j)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   protected: | ||||
|     const TranspositionType& m_transpositions; | ||||
|     typename MatrixType::Nested m_matrix; | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /* Template partial specialization for transposed/inverse transpositions */ | ||||
|  | ||||
| template<typename TranspositionsDerived> | ||||
| class Transpose<TranspositionsBase<TranspositionsDerived> > | ||||
| { | ||||
|     typedef TranspositionsDerived TranspositionType; | ||||
|     typedef typename TranspositionType::IndicesType IndicesType; | ||||
|   public: | ||||
|  | ||||
|     Transpose(const TranspositionType& t) : m_transpositions(t) {} | ||||
|  | ||||
|     inline int size() const { return m_transpositions.size(); } | ||||
|  | ||||
|     /** \returns the \a matrix with the inverse transpositions applied to the columns. | ||||
|       */ | ||||
|     template<typename Derived> friend | ||||
|     inline const internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheRight, true> | ||||
|     operator*(const MatrixBase<Derived>& matrix, const Transpose& trt) | ||||
|     { | ||||
|       return internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheRight, true>(trt.m_transpositions, matrix.derived()); | ||||
|     } | ||||
|  | ||||
|     /** \returns the \a matrix with the inverse transpositions applied to the rows. | ||||
|       */ | ||||
|     template<typename Derived> | ||||
|     inline const internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheLeft, true> | ||||
|     operator*(const MatrixBase<Derived>& matrix) const | ||||
|     { | ||||
|       return internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheLeft, true>(m_transpositions, matrix.derived()); | ||||
|     } | ||||
|  | ||||
|   protected: | ||||
|     const TranspositionType& m_transpositions; | ||||
| }; | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_TRANSPOSITIONS_H | ||||
							
								
								
									
										828
									
								
								latan/Eigen/src/Core/TriangularMatrix.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										828
									
								
								latan/Eigen/src/Core/TriangularMatrix.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,828 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_TRIANGULARMATRIX_H | ||||
| #define EIGEN_TRIANGULARMATRIX_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| namespace internal { | ||||
|    | ||||
| template<int Side, typename TriangularType, typename Rhs> struct triangular_solve_retval; | ||||
|    | ||||
| } | ||||
|  | ||||
| /** \internal | ||||
|   * | ||||
|   * \class TriangularBase | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Base class for triangular part in a matrix | ||||
|   */ | ||||
| template<typename Derived> class TriangularBase : public EigenBase<Derived> | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     enum { | ||||
|       Mode = internal::traits<Derived>::Mode, | ||||
|       CoeffReadCost = internal::traits<Derived>::CoeffReadCost, | ||||
|       RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime, | ||||
|       ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime, | ||||
|       MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime, | ||||
|       MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime | ||||
|     }; | ||||
|     typedef typename internal::traits<Derived>::Scalar Scalar; | ||||
|     typedef typename internal::traits<Derived>::StorageKind StorageKind; | ||||
|     typedef typename internal::traits<Derived>::Index Index; | ||||
|     typedef typename internal::traits<Derived>::DenseMatrixType DenseMatrixType; | ||||
|     typedef DenseMatrixType DenseType; | ||||
|  | ||||
|     inline TriangularBase() { eigen_assert(!((Mode&UnitDiag) && (Mode&ZeroDiag))); } | ||||
|  | ||||
|     inline Index rows() const { return derived().rows(); } | ||||
|     inline Index cols() const { return derived().cols(); } | ||||
|     inline Index outerStride() const { return derived().outerStride(); } | ||||
|     inline Index innerStride() const { return derived().innerStride(); } | ||||
|  | ||||
|     inline Scalar coeff(Index row, Index col) const  { return derived().coeff(row,col); } | ||||
|     inline Scalar& coeffRef(Index row, Index col) { return derived().coeffRef(row,col); } | ||||
|  | ||||
|     /** \see MatrixBase::copyCoeff(row,col) | ||||
|       */ | ||||
|     template<typename Other> | ||||
|     EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, Other& other) | ||||
|     { | ||||
|       derived().coeffRef(row, col) = other.coeff(row, col); | ||||
|     } | ||||
|  | ||||
|     inline Scalar operator()(Index row, Index col) const | ||||
|     { | ||||
|       check_coordinates(row, col); | ||||
|       return coeff(row,col); | ||||
|     } | ||||
|     inline Scalar& operator()(Index row, Index col) | ||||
|     { | ||||
|       check_coordinates(row, col); | ||||
|       return coeffRef(row,col); | ||||
|     } | ||||
|  | ||||
|     #ifndef EIGEN_PARSED_BY_DOXYGEN | ||||
|     inline const Derived& derived() const { return *static_cast<const Derived*>(this); } | ||||
|     inline Derived& derived() { return *static_cast<Derived*>(this); } | ||||
|     #endif // not EIGEN_PARSED_BY_DOXYGEN | ||||
|  | ||||
|     template<typename DenseDerived> | ||||
|     void evalTo(MatrixBase<DenseDerived> &other) const; | ||||
|     template<typename DenseDerived> | ||||
|     void evalToLazy(MatrixBase<DenseDerived> &other) const; | ||||
|  | ||||
|     DenseMatrixType toDenseMatrix() const | ||||
|     { | ||||
|       DenseMatrixType res(rows(), cols()); | ||||
|       evalToLazy(res); | ||||
|       return res; | ||||
|     } | ||||
|  | ||||
|   protected: | ||||
|  | ||||
|     void check_coordinates(Index row, Index col) const | ||||
|     { | ||||
|       EIGEN_ONLY_USED_FOR_DEBUG(row); | ||||
|       EIGEN_ONLY_USED_FOR_DEBUG(col); | ||||
|       eigen_assert(col>=0 && col<cols() && row>=0 && row<rows()); | ||||
|       const int mode = int(Mode) & ~SelfAdjoint; | ||||
|       EIGEN_ONLY_USED_FOR_DEBUG(mode); | ||||
|       eigen_assert((mode==Upper && col>=row) | ||||
|                 || (mode==Lower && col<=row) | ||||
|                 || ((mode==StrictlyUpper || mode==UnitUpper) && col>row) | ||||
|                 || ((mode==StrictlyLower || mode==UnitLower) && col<row)); | ||||
|     } | ||||
|  | ||||
|     #ifdef EIGEN_INTERNAL_DEBUGGING | ||||
|     void check_coordinates_internal(Index row, Index col) const | ||||
|     { | ||||
|       check_coordinates(row, col); | ||||
|     } | ||||
|     #else | ||||
|     void check_coordinates_internal(Index , Index ) const {} | ||||
|     #endif | ||||
|  | ||||
| }; | ||||
|  | ||||
| /** \class TriangularView | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Base class for triangular part in a matrix | ||||
|   * | ||||
|   * \param MatrixType the type of the object in which we are taking the triangular part | ||||
|   * \param Mode the kind of triangular matrix expression to construct. Can be #Upper, | ||||
|   *             #Lower, #UnitUpper, #UnitLower, #StrictlyUpper, or #StrictlyLower. | ||||
|   *             This is in fact a bit field; it must have either #Upper or #Lower,  | ||||
|   *             and additionnaly it may have #UnitDiag or #ZeroDiag or neither. | ||||
|   * | ||||
|   * This class represents a triangular part of a matrix, not necessarily square. Strictly speaking, for rectangular | ||||
|   * matrices one should speak of "trapezoid" parts. This class is the return type | ||||
|   * of MatrixBase::triangularView() and most of the time this is the only way it is used. | ||||
|   * | ||||
|   * \sa MatrixBase::triangularView() | ||||
|   */ | ||||
| namespace internal { | ||||
| template<typename MatrixType, unsigned int _Mode> | ||||
| struct traits<TriangularView<MatrixType, _Mode> > : traits<MatrixType> | ||||
| { | ||||
|   typedef typename nested<MatrixType>::type MatrixTypeNested; | ||||
|   typedef typename remove_reference<MatrixTypeNested>::type MatrixTypeNestedNonRef; | ||||
|   typedef typename remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned; | ||||
|   typedef MatrixType ExpressionType; | ||||
|   typedef typename MatrixType::PlainObject DenseMatrixType; | ||||
|   enum { | ||||
|     Mode = _Mode, | ||||
|     Flags = (MatrixTypeNestedCleaned::Flags & (HereditaryBits) & (~(PacketAccessBit | DirectAccessBit | LinearAccessBit))) | Mode, | ||||
|     CoeffReadCost = MatrixTypeNestedCleaned::CoeffReadCost | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<int Mode, bool LhsIsTriangular, | ||||
|          typename Lhs, bool LhsIsVector, | ||||
|          typename Rhs, bool RhsIsVector> | ||||
| struct TriangularProduct; | ||||
|  | ||||
| template<typename _MatrixType, unsigned int _Mode> class TriangularView | ||||
|   : public TriangularBase<TriangularView<_MatrixType, _Mode> > | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef TriangularBase<TriangularView> Base; | ||||
|     typedef typename internal::traits<TriangularView>::Scalar Scalar; | ||||
|  | ||||
|     typedef _MatrixType MatrixType; | ||||
|     typedef typename internal::traits<TriangularView>::DenseMatrixType DenseMatrixType; | ||||
|     typedef DenseMatrixType PlainObject; | ||||
|  | ||||
|   protected: | ||||
|     typedef typename internal::traits<TriangularView>::MatrixTypeNested MatrixTypeNested; | ||||
|     typedef typename internal::traits<TriangularView>::MatrixTypeNestedNonRef MatrixTypeNestedNonRef; | ||||
|     typedef typename internal::traits<TriangularView>::MatrixTypeNestedCleaned MatrixTypeNestedCleaned; | ||||
|  | ||||
|     typedef typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type MatrixConjugateReturnType; | ||||
|      | ||||
|   public: | ||||
|     using Base::evalToLazy; | ||||
|    | ||||
|  | ||||
|     typedef typename internal::traits<TriangularView>::StorageKind StorageKind; | ||||
|     typedef typename internal::traits<TriangularView>::Index Index; | ||||
|  | ||||
|     enum { | ||||
|       Mode = _Mode, | ||||
|       TransposeMode = (Mode & Upper ? Lower : 0) | ||||
|                     | (Mode & Lower ? Upper : 0) | ||||
|                     | (Mode & (UnitDiag)) | ||||
|                     | (Mode & (ZeroDiag)) | ||||
|     }; | ||||
|  | ||||
|     inline TriangularView(const MatrixType& matrix) : m_matrix(matrix) | ||||
|     {} | ||||
|  | ||||
|     inline Index rows() const { return m_matrix.rows(); } | ||||
|     inline Index cols() const { return m_matrix.cols(); } | ||||
|     inline Index outerStride() const { return m_matrix.outerStride(); } | ||||
|     inline Index innerStride() const { return m_matrix.innerStride(); } | ||||
|  | ||||
|     /** \sa MatrixBase::operator+=() */ | ||||
|     template<typename Other> TriangularView&  operator+=(const DenseBase<Other>& other) { return *this = m_matrix + other.derived(); } | ||||
|     /** \sa MatrixBase::operator-=() */ | ||||
|     template<typename Other> TriangularView&  operator-=(const DenseBase<Other>& other) { return *this = m_matrix - other.derived(); } | ||||
|     /** \sa MatrixBase::operator*=() */ | ||||
|     TriangularView&  operator*=(const typename internal::traits<MatrixType>::Scalar& other) { return *this = m_matrix * other; } | ||||
|     /** \sa MatrixBase::operator/=() */ | ||||
|     TriangularView&  operator/=(const typename internal::traits<MatrixType>::Scalar& other) { return *this = m_matrix / other; } | ||||
|  | ||||
|     /** \sa MatrixBase::fill() */ | ||||
|     void fill(const Scalar& value) { setConstant(value); } | ||||
|     /** \sa MatrixBase::setConstant() */ | ||||
|     TriangularView& setConstant(const Scalar& value) | ||||
|     { return *this = MatrixType::Constant(rows(), cols(), value); } | ||||
|     /** \sa MatrixBase::setZero() */ | ||||
|     TriangularView& setZero() { return setConstant(Scalar(0)); } | ||||
|     /** \sa MatrixBase::setOnes() */ | ||||
|     TriangularView& setOnes() { return setConstant(Scalar(1)); } | ||||
|  | ||||
|     /** \sa MatrixBase::coeff() | ||||
|       * \warning the coordinates must fit into the referenced triangular part | ||||
|       */ | ||||
|     inline Scalar coeff(Index row, Index col) const | ||||
|     { | ||||
|       Base::check_coordinates_internal(row, col); | ||||
|       return m_matrix.coeff(row, col); | ||||
|     } | ||||
|  | ||||
|     /** \sa MatrixBase::coeffRef() | ||||
|       * \warning the coordinates must fit into the referenced triangular part | ||||
|       */ | ||||
|     inline Scalar& coeffRef(Index row, Index col) | ||||
|     { | ||||
|       Base::check_coordinates_internal(row, col); | ||||
|       return m_matrix.const_cast_derived().coeffRef(row, col); | ||||
|     } | ||||
|  | ||||
|     const MatrixTypeNestedCleaned& nestedExpression() const { return m_matrix; } | ||||
|     MatrixTypeNestedCleaned& nestedExpression() { return *const_cast<MatrixTypeNestedCleaned*>(&m_matrix); } | ||||
|  | ||||
|     /** Assigns a triangular matrix to a triangular part of a dense matrix */ | ||||
|     template<typename OtherDerived> | ||||
|     TriangularView& operator=(const TriangularBase<OtherDerived>& other); | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     TriangularView& operator=(const MatrixBase<OtherDerived>& other); | ||||
|  | ||||
|     TriangularView& operator=(const TriangularView& other) | ||||
|     { return *this = other.nestedExpression(); } | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     void lazyAssign(const TriangularBase<OtherDerived>& other); | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     void lazyAssign(const MatrixBase<OtherDerived>& other); | ||||
|  | ||||
|     /** \sa MatrixBase::conjugate() */ | ||||
|     inline TriangularView<MatrixConjugateReturnType,Mode> conjugate() | ||||
|     { return m_matrix.conjugate(); } | ||||
|     /** \sa MatrixBase::conjugate() const */ | ||||
|     inline const TriangularView<MatrixConjugateReturnType,Mode> conjugate() const | ||||
|     { return m_matrix.conjugate(); } | ||||
|  | ||||
|     /** \sa MatrixBase::adjoint() const */ | ||||
|     inline const TriangularView<const typename MatrixType::AdjointReturnType,TransposeMode> adjoint() const | ||||
|     { return m_matrix.adjoint(); } | ||||
|  | ||||
|     /** \sa MatrixBase::transpose() */ | ||||
|     inline TriangularView<Transpose<MatrixType>,TransposeMode> transpose() | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_LVALUE(MatrixType) | ||||
|       return m_matrix.const_cast_derived().transpose(); | ||||
|     } | ||||
|     /** \sa MatrixBase::transpose() const */ | ||||
|     inline const TriangularView<Transpose<MatrixType>,TransposeMode> transpose() const | ||||
|     { | ||||
|       return m_matrix.transpose(); | ||||
|     } | ||||
|  | ||||
|     /** Efficient triangular matrix times vector/matrix product */ | ||||
|     template<typename OtherDerived> | ||||
|     TriangularProduct<Mode,true,MatrixType,false,OtherDerived, OtherDerived::IsVectorAtCompileTime> | ||||
|     operator*(const MatrixBase<OtherDerived>& rhs) const | ||||
|     { | ||||
|       return TriangularProduct | ||||
|               <Mode,true,MatrixType,false,OtherDerived,OtherDerived::IsVectorAtCompileTime> | ||||
|               (m_matrix, rhs.derived()); | ||||
|     } | ||||
|  | ||||
|     /** Efficient vector/matrix times triangular matrix product */ | ||||
|     template<typename OtherDerived> friend | ||||
|     TriangularProduct<Mode,false,OtherDerived,OtherDerived::IsVectorAtCompileTime,MatrixType,false> | ||||
|     operator*(const MatrixBase<OtherDerived>& lhs, const TriangularView& rhs) | ||||
|     { | ||||
|       return TriangularProduct | ||||
|               <Mode,false,OtherDerived,OtherDerived::IsVectorAtCompileTime,MatrixType,false> | ||||
|               (lhs.derived(),rhs.m_matrix); | ||||
|     } | ||||
|  | ||||
|     #ifdef EIGEN2_SUPPORT | ||||
|     template<typename OtherDerived> | ||||
|     struct eigen2_product_return_type | ||||
|     { | ||||
|       typedef typename TriangularView<MatrixType,Mode>::DenseMatrixType DenseMatrixType; | ||||
|       typedef typename OtherDerived::PlainObject::DenseType OtherPlainObject; | ||||
|       typedef typename ProductReturnType<DenseMatrixType, OtherPlainObject>::Type ProdRetType; | ||||
|       typedef typename ProdRetType::PlainObject type; | ||||
|     }; | ||||
|     template<typename OtherDerived> | ||||
|     const typename eigen2_product_return_type<OtherDerived>::type | ||||
|     operator*(const EigenBase<OtherDerived>& rhs) const | ||||
|     { | ||||
|       typename OtherDerived::PlainObject::DenseType rhsPlainObject; | ||||
|       rhs.evalTo(rhsPlainObject); | ||||
|       return this->toDenseMatrix() * rhsPlainObject; | ||||
|     } | ||||
|     template<typename OtherMatrixType> | ||||
|     bool isApprox(const TriangularView<OtherMatrixType, Mode>& other, typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) const | ||||
|     { | ||||
|       return this->toDenseMatrix().isApprox(other.toDenseMatrix(), precision); | ||||
|     } | ||||
|     template<typename OtherDerived> | ||||
|     bool isApprox(const MatrixBase<OtherDerived>& other, typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) const | ||||
|     { | ||||
|       return this->toDenseMatrix().isApprox(other, precision); | ||||
|     } | ||||
|     #endif // EIGEN2_SUPPORT | ||||
|  | ||||
|     template<int Side, typename Other> | ||||
|     inline const internal::triangular_solve_retval<Side,TriangularView, Other> | ||||
|     solve(const MatrixBase<Other>& other) const; | ||||
|  | ||||
|     template<int Side, typename OtherDerived> | ||||
|     void solveInPlace(const MatrixBase<OtherDerived>& other) const; | ||||
|  | ||||
|     template<typename Other> | ||||
|     inline const internal::triangular_solve_retval<OnTheLeft,TriangularView, Other>  | ||||
|     solve(const MatrixBase<Other>& other) const | ||||
|     { return solve<OnTheLeft>(other); } | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     void solveInPlace(const MatrixBase<OtherDerived>& other) const | ||||
|     { return solveInPlace<OnTheLeft>(other); } | ||||
|  | ||||
|     const SelfAdjointView<MatrixTypeNestedNonRef,Mode> selfadjointView() const | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT((Mode&UnitDiag)==0,PROGRAMMING_ERROR); | ||||
|       return SelfAdjointView<MatrixTypeNestedNonRef,Mode>(m_matrix); | ||||
|     } | ||||
|     SelfAdjointView<MatrixTypeNestedNonRef,Mode> selfadjointView() | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT((Mode&UnitDiag)==0,PROGRAMMING_ERROR); | ||||
|       return SelfAdjointView<MatrixTypeNestedNonRef,Mode>(m_matrix); | ||||
|     } | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     void swap(TriangularBase<OtherDerived> const & other) | ||||
|     { | ||||
|       TriangularView<SwapWrapper<MatrixType>,Mode>(const_cast<MatrixType&>(m_matrix)).lazyAssign(other.derived()); | ||||
|     } | ||||
|  | ||||
|     template<typename OtherDerived> | ||||
|     void swap(MatrixBase<OtherDerived> const & other) | ||||
|     { | ||||
|       SwapWrapper<MatrixType> swaper(const_cast<MatrixType&>(m_matrix)); | ||||
|       TriangularView<SwapWrapper<MatrixType>,Mode>(swaper).lazyAssign(other.derived()); | ||||
|     } | ||||
|  | ||||
|     Scalar determinant() const | ||||
|     { | ||||
|       if (Mode & UnitDiag) | ||||
|         return 1; | ||||
|       else if (Mode & ZeroDiag) | ||||
|         return 0; | ||||
|       else | ||||
|         return m_matrix.diagonal().prod(); | ||||
|     } | ||||
|      | ||||
|     // TODO simplify the following: | ||||
|     template<typename ProductDerived, typename Lhs, typename Rhs> | ||||
|     EIGEN_STRONG_INLINE TriangularView& operator=(const ProductBase<ProductDerived, Lhs,Rhs>& other) | ||||
|     { | ||||
|       setZero(); | ||||
|       return assignProduct(other,1); | ||||
|     } | ||||
|      | ||||
|     template<typename ProductDerived, typename Lhs, typename Rhs> | ||||
|     EIGEN_STRONG_INLINE TriangularView& operator+=(const ProductBase<ProductDerived, Lhs,Rhs>& other) | ||||
|     { | ||||
|       return assignProduct(other,1); | ||||
|     } | ||||
|      | ||||
|     template<typename ProductDerived, typename Lhs, typename Rhs> | ||||
|     EIGEN_STRONG_INLINE TriangularView& operator-=(const ProductBase<ProductDerived, Lhs,Rhs>& other) | ||||
|     { | ||||
|       return assignProduct(other,-1); | ||||
|     } | ||||
|      | ||||
|      | ||||
|     template<typename ProductDerived> | ||||
|     EIGEN_STRONG_INLINE TriangularView& operator=(const ScaledProduct<ProductDerived>& other) | ||||
|     { | ||||
|       setZero(); | ||||
|       return assignProduct(other,other.alpha()); | ||||
|     } | ||||
|      | ||||
|     template<typename ProductDerived> | ||||
|     EIGEN_STRONG_INLINE TriangularView& operator+=(const ScaledProduct<ProductDerived>& other) | ||||
|     { | ||||
|       return assignProduct(other,other.alpha()); | ||||
|     } | ||||
|      | ||||
|     template<typename ProductDerived> | ||||
|     EIGEN_STRONG_INLINE TriangularView& operator-=(const ScaledProduct<ProductDerived>& other) | ||||
|     { | ||||
|       return assignProduct(other,-other.alpha()); | ||||
|     } | ||||
|      | ||||
|   protected: | ||||
|      | ||||
|     template<typename ProductDerived, typename Lhs, typename Rhs> | ||||
|     EIGEN_STRONG_INLINE TriangularView& assignProduct(const ProductBase<ProductDerived, Lhs,Rhs>& prod, const Scalar& alpha); | ||||
|  | ||||
|     MatrixTypeNested m_matrix; | ||||
| }; | ||||
|  | ||||
| /*************************************************************************** | ||||
| * Implementation of triangular evaluation/assignment | ||||
| ***************************************************************************/ | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename Derived1, typename Derived2, unsigned int Mode, int UnrollCount, bool ClearOpposite> | ||||
| struct triangular_assignment_selector | ||||
| { | ||||
|   enum { | ||||
|     col = (UnrollCount-1) / Derived1::RowsAtCompileTime, | ||||
|     row = (UnrollCount-1) % Derived1::RowsAtCompileTime | ||||
|   }; | ||||
|    | ||||
|   typedef typename Derived1::Scalar Scalar; | ||||
|  | ||||
|   static inline void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     triangular_assignment_selector<Derived1, Derived2, Mode, UnrollCount-1, ClearOpposite>::run(dst, src); | ||||
|  | ||||
|     eigen_assert( Mode == Upper || Mode == Lower | ||||
|             || Mode == StrictlyUpper || Mode == StrictlyLower | ||||
|             || Mode == UnitUpper || Mode == UnitLower); | ||||
|     if((Mode == Upper && row <= col) | ||||
|     || (Mode == Lower && row >= col) | ||||
|     || (Mode == StrictlyUpper && row < col) | ||||
|     || (Mode == StrictlyLower && row > col) | ||||
|     || (Mode == UnitUpper && row < col) | ||||
|     || (Mode == UnitLower && row > col)) | ||||
|       dst.copyCoeff(row, col, src); | ||||
|     else if(ClearOpposite) | ||||
|     { | ||||
|       if (Mode&UnitDiag && row==col) | ||||
|         dst.coeffRef(row, col) = Scalar(1); | ||||
|       else | ||||
|         dst.coeffRef(row, col) = Scalar(0); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // prevent buggy user code from causing an infinite recursion | ||||
| template<typename Derived1, typename Derived2, unsigned int Mode, bool ClearOpposite> | ||||
| struct triangular_assignment_selector<Derived1, Derived2, Mode, 0, ClearOpposite> | ||||
| { | ||||
|   static inline void run(Derived1 &, const Derived2 &) {} | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, bool ClearOpposite> | ||||
| struct triangular_assignment_selector<Derived1, Derived2, Upper, Dynamic, ClearOpposite> | ||||
| { | ||||
|   typedef typename Derived1::Index Index; | ||||
|   typedef typename Derived1::Scalar Scalar; | ||||
|   static inline void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     for(Index j = 0; j < dst.cols(); ++j) | ||||
|     { | ||||
|       Index maxi = (std::min)(j, dst.rows()-1); | ||||
|       for(Index i = 0; i <= maxi; ++i) | ||||
|         dst.copyCoeff(i, j, src); | ||||
|       if (ClearOpposite) | ||||
|         for(Index i = maxi+1; i < dst.rows(); ++i) | ||||
|           dst.coeffRef(i, j) = Scalar(0); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, bool ClearOpposite> | ||||
| struct triangular_assignment_selector<Derived1, Derived2, Lower, Dynamic, ClearOpposite> | ||||
| { | ||||
|   typedef typename Derived1::Index Index; | ||||
|   static inline void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     for(Index j = 0; j < dst.cols(); ++j) | ||||
|     { | ||||
|       for(Index i = j; i < dst.rows(); ++i) | ||||
|         dst.copyCoeff(i, j, src); | ||||
|       Index maxi = (std::min)(j, dst.rows()); | ||||
|       if (ClearOpposite) | ||||
|         for(Index i = 0; i < maxi; ++i) | ||||
|           dst.coeffRef(i, j) = static_cast<typename Derived1::Scalar>(0); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, bool ClearOpposite> | ||||
| struct triangular_assignment_selector<Derived1, Derived2, StrictlyUpper, Dynamic, ClearOpposite> | ||||
| { | ||||
|   typedef typename Derived1::Index Index; | ||||
|   typedef typename Derived1::Scalar Scalar; | ||||
|   static inline void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     for(Index j = 0; j < dst.cols(); ++j) | ||||
|     { | ||||
|       Index maxi = (std::min)(j, dst.rows()); | ||||
|       for(Index i = 0; i < maxi; ++i) | ||||
|         dst.copyCoeff(i, j, src); | ||||
|       if (ClearOpposite) | ||||
|         for(Index i = maxi; i < dst.rows(); ++i) | ||||
|           dst.coeffRef(i, j) = Scalar(0); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, bool ClearOpposite> | ||||
| struct triangular_assignment_selector<Derived1, Derived2, StrictlyLower, Dynamic, ClearOpposite> | ||||
| { | ||||
|   typedef typename Derived1::Index Index; | ||||
|   static inline void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     for(Index j = 0; j < dst.cols(); ++j) | ||||
|     { | ||||
|       for(Index i = j+1; i < dst.rows(); ++i) | ||||
|         dst.copyCoeff(i, j, src); | ||||
|       Index maxi = (std::min)(j, dst.rows()-1); | ||||
|       if (ClearOpposite) | ||||
|         for(Index i = 0; i <= maxi; ++i) | ||||
|           dst.coeffRef(i, j) = static_cast<typename Derived1::Scalar>(0); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Derived1, typename Derived2, bool ClearOpposite> | ||||
| struct triangular_assignment_selector<Derived1, Derived2, UnitUpper, Dynamic, ClearOpposite> | ||||
| { | ||||
|   typedef typename Derived1::Index Index; | ||||
|   static inline void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     for(Index j = 0; j < dst.cols(); ++j) | ||||
|     { | ||||
|       Index maxi = (std::min)(j, dst.rows()); | ||||
|       for(Index i = 0; i < maxi; ++i) | ||||
|         dst.copyCoeff(i, j, src); | ||||
|       if (ClearOpposite) | ||||
|       { | ||||
|         for(Index i = maxi+1; i < dst.rows(); ++i) | ||||
|           dst.coeffRef(i, j) = 0; | ||||
|       } | ||||
|     } | ||||
|     dst.diagonal().setOnes(); | ||||
|   } | ||||
| }; | ||||
| template<typename Derived1, typename Derived2, bool ClearOpposite> | ||||
| struct triangular_assignment_selector<Derived1, Derived2, UnitLower, Dynamic, ClearOpposite> | ||||
| { | ||||
|   typedef typename Derived1::Index Index; | ||||
|   static inline void run(Derived1 &dst, const Derived2 &src) | ||||
|   { | ||||
|     for(Index j = 0; j < dst.cols(); ++j) | ||||
|     { | ||||
|       Index maxi = (std::min)(j, dst.rows()); | ||||
|       for(Index i = maxi+1; i < dst.rows(); ++i) | ||||
|         dst.copyCoeff(i, j, src); | ||||
|       if (ClearOpposite) | ||||
|       { | ||||
|         for(Index i = 0; i < maxi; ++i) | ||||
|           dst.coeffRef(i, j) = 0; | ||||
|       } | ||||
|     } | ||||
|     dst.diagonal().setOnes(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| // FIXME should we keep that possibility | ||||
| template<typename MatrixType, unsigned int Mode> | ||||
| template<typename OtherDerived> | ||||
| inline TriangularView<MatrixType, Mode>& | ||||
| TriangularView<MatrixType, Mode>::operator=(const MatrixBase<OtherDerived>& other) | ||||
| { | ||||
|   if(OtherDerived::Flags & EvalBeforeAssigningBit) | ||||
|   { | ||||
|     typename internal::plain_matrix_type<OtherDerived>::type other_evaluated(other.rows(), other.cols()); | ||||
|     other_evaluated.template triangularView<Mode>().lazyAssign(other.derived()); | ||||
|     lazyAssign(other_evaluated); | ||||
|   } | ||||
|   else | ||||
|     lazyAssign(other.derived()); | ||||
|   return *this; | ||||
| } | ||||
|  | ||||
| // FIXME should we keep that possibility | ||||
| template<typename MatrixType, unsigned int Mode> | ||||
| template<typename OtherDerived> | ||||
| void TriangularView<MatrixType, Mode>::lazyAssign(const MatrixBase<OtherDerived>& other) | ||||
| { | ||||
|   enum { | ||||
|     unroll = MatrixType::SizeAtCompileTime != Dynamic | ||||
|           && internal::traits<OtherDerived>::CoeffReadCost != Dynamic | ||||
|           && MatrixType::SizeAtCompileTime*internal::traits<OtherDerived>::CoeffReadCost/2 <= EIGEN_UNROLLING_LIMIT | ||||
|   }; | ||||
|   eigen_assert(m_matrix.rows() == other.rows() && m_matrix.cols() == other.cols()); | ||||
|  | ||||
|   internal::triangular_assignment_selector | ||||
|     <MatrixType, OtherDerived, int(Mode), | ||||
|     unroll ? int(MatrixType::SizeAtCompileTime) : Dynamic, | ||||
|     false // do not change the opposite triangular part | ||||
|     >::run(m_matrix.const_cast_derived(), other.derived()); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| template<typename MatrixType, unsigned int Mode> | ||||
| template<typename OtherDerived> | ||||
| inline TriangularView<MatrixType, Mode>& | ||||
| TriangularView<MatrixType, Mode>::operator=(const TriangularBase<OtherDerived>& other) | ||||
| { | ||||
|   eigen_assert(Mode == int(OtherDerived::Mode)); | ||||
|   if(internal::traits<OtherDerived>::Flags & EvalBeforeAssigningBit) | ||||
|   { | ||||
|     typename OtherDerived::DenseMatrixType other_evaluated(other.rows(), other.cols()); | ||||
|     other_evaluated.template triangularView<Mode>().lazyAssign(other.derived().nestedExpression()); | ||||
|     lazyAssign(other_evaluated); | ||||
|   } | ||||
|   else | ||||
|     lazyAssign(other.derived().nestedExpression()); | ||||
|   return *this; | ||||
| } | ||||
|  | ||||
| template<typename MatrixType, unsigned int Mode> | ||||
| template<typename OtherDerived> | ||||
| void TriangularView<MatrixType, Mode>::lazyAssign(const TriangularBase<OtherDerived>& other) | ||||
| { | ||||
|   enum { | ||||
|     unroll = MatrixType::SizeAtCompileTime != Dynamic | ||||
|                    && internal::traits<OtherDerived>::CoeffReadCost != Dynamic | ||||
|                    && MatrixType::SizeAtCompileTime * internal::traits<OtherDerived>::CoeffReadCost / 2 | ||||
|                         <= EIGEN_UNROLLING_LIMIT | ||||
|   }; | ||||
|   eigen_assert(m_matrix.rows() == other.rows() && m_matrix.cols() == other.cols()); | ||||
|  | ||||
|   internal::triangular_assignment_selector | ||||
|     <MatrixType, OtherDerived, int(Mode), | ||||
|     unroll ? int(MatrixType::SizeAtCompileTime) : Dynamic, | ||||
|     false // preserve the opposite triangular part | ||||
|     >::run(m_matrix.const_cast_derived(), other.derived().nestedExpression()); | ||||
| } | ||||
|  | ||||
| /*************************************************************************** | ||||
| * Implementation of TriangularBase methods | ||||
| ***************************************************************************/ | ||||
|  | ||||
| /** Assigns a triangular or selfadjoint matrix to a dense matrix. | ||||
|   * If the matrix is triangular, the opposite part is set to zero. */ | ||||
| template<typename Derived> | ||||
| template<typename DenseDerived> | ||||
| void TriangularBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const | ||||
| { | ||||
|   if(internal::traits<Derived>::Flags & EvalBeforeAssigningBit) | ||||
|   { | ||||
|     typename internal::plain_matrix_type<Derived>::type other_evaluated(rows(), cols()); | ||||
|     evalToLazy(other_evaluated); | ||||
|     other.derived().swap(other_evaluated); | ||||
|   } | ||||
|   else | ||||
|     evalToLazy(other.derived()); | ||||
| } | ||||
|  | ||||
| /** Assigns a triangular or selfadjoint matrix to a dense matrix. | ||||
|   * If the matrix is triangular, the opposite part is set to zero. */ | ||||
| template<typename Derived> | ||||
| template<typename DenseDerived> | ||||
| void TriangularBase<Derived>::evalToLazy(MatrixBase<DenseDerived> &other) const | ||||
| { | ||||
|   enum { | ||||
|     unroll = DenseDerived::SizeAtCompileTime != Dynamic | ||||
|                    && internal::traits<Derived>::CoeffReadCost != Dynamic | ||||
|                    && DenseDerived::SizeAtCompileTime * internal::traits<Derived>::CoeffReadCost / 2 | ||||
|                         <= EIGEN_UNROLLING_LIMIT | ||||
|   }; | ||||
|   other.derived().resize(this->rows(), this->cols()); | ||||
|  | ||||
|   internal::triangular_assignment_selector | ||||
|     <DenseDerived, typename internal::traits<Derived>::MatrixTypeNestedCleaned, Derived::Mode, | ||||
|     unroll ? int(DenseDerived::SizeAtCompileTime) : Dynamic, | ||||
|     true // clear the opposite triangular part | ||||
|     >::run(other.derived(), derived().nestedExpression()); | ||||
| } | ||||
|  | ||||
| /*************************************************************************** | ||||
| * Implementation of TriangularView methods | ||||
| ***************************************************************************/ | ||||
|  | ||||
| /*************************************************************************** | ||||
| * Implementation of MatrixBase methods | ||||
| ***************************************************************************/ | ||||
|  | ||||
| #ifdef EIGEN2_SUPPORT | ||||
|  | ||||
| // implementation of part<>(), including the SelfAdjoint case. | ||||
|  | ||||
| namespace internal { | ||||
| template<typename MatrixType, unsigned int Mode> | ||||
| struct eigen2_part_return_type | ||||
| { | ||||
|   typedef TriangularView<MatrixType, Mode> type; | ||||
| }; | ||||
|  | ||||
| template<typename MatrixType> | ||||
| struct eigen2_part_return_type<MatrixType, SelfAdjoint> | ||||
| { | ||||
|   typedef SelfAdjointView<MatrixType, Upper> type; | ||||
| }; | ||||
| } | ||||
|  | ||||
| /** \deprecated use MatrixBase::triangularView() */ | ||||
| template<typename Derived> | ||||
| template<unsigned int Mode> | ||||
| const typename internal::eigen2_part_return_type<Derived, Mode>::type MatrixBase<Derived>::part() const | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| /** \deprecated use MatrixBase::triangularView() */ | ||||
| template<typename Derived> | ||||
| template<unsigned int Mode> | ||||
| typename internal::eigen2_part_return_type<Derived, Mode>::type MatrixBase<Derived>::part() | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|   * \returns an expression of a triangular view extracted from the current matrix | ||||
|   * | ||||
|   * The parameter \a Mode can have the following values: \c #Upper, \c #StrictlyUpper, \c #UnitUpper, | ||||
|   * \c #Lower, \c #StrictlyLower, \c #UnitLower. | ||||
|   * | ||||
|   * Example: \include MatrixBase_extract.cpp | ||||
|   * Output: \verbinclude MatrixBase_extract.out | ||||
|   * | ||||
|   * \sa class TriangularView | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<unsigned int Mode> | ||||
| typename MatrixBase<Derived>::template TriangularViewReturnType<Mode>::Type | ||||
| MatrixBase<Derived>::triangularView() | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| /** This is the const version of MatrixBase::triangularView() */ | ||||
| template<typename Derived> | ||||
| template<unsigned int Mode> | ||||
| typename MatrixBase<Derived>::template ConstTriangularViewReturnType<Mode>::Type | ||||
| MatrixBase<Derived>::triangularView() const | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| /** \returns true if *this is approximately equal to an upper triangular matrix, | ||||
|   *          within the precision given by \a prec. | ||||
|   * | ||||
|   * \sa isLowerTriangular() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| bool MatrixBase<Derived>::isUpperTriangular(RealScalar prec) const | ||||
| { | ||||
|   RealScalar maxAbsOnUpperPart = static_cast<RealScalar>(-1); | ||||
|   for(Index j = 0; j < cols(); ++j) | ||||
|   { | ||||
|     Index maxi = (std::min)(j, rows()-1); | ||||
|     for(Index i = 0; i <= maxi; ++i) | ||||
|     { | ||||
|       RealScalar absValue = internal::abs(coeff(i,j)); | ||||
|       if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue; | ||||
|     } | ||||
|   } | ||||
|   RealScalar threshold = maxAbsOnUpperPart * prec; | ||||
|   for(Index j = 0; j < cols(); ++j) | ||||
|     for(Index i = j+1; i < rows(); ++i) | ||||
|       if(internal::abs(coeff(i, j)) > threshold) return false; | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| /** \returns true if *this is approximately equal to a lower triangular matrix, | ||||
|   *          within the precision given by \a prec. | ||||
|   * | ||||
|   * \sa isUpperTriangular() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| bool MatrixBase<Derived>::isLowerTriangular(RealScalar prec) const | ||||
| { | ||||
|   RealScalar maxAbsOnLowerPart = static_cast<RealScalar>(-1); | ||||
|   for(Index j = 0; j < cols(); ++j) | ||||
|     for(Index i = j; i < rows(); ++i) | ||||
|     { | ||||
|       RealScalar absValue = internal::abs(coeff(i,j)); | ||||
|       if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue; | ||||
|     } | ||||
|   RealScalar threshold = maxAbsOnLowerPart * prec; | ||||
|   for(Index j = 1; j < cols(); ++j) | ||||
|   { | ||||
|     Index maxi = (std::min)(j, rows()-1); | ||||
|     for(Index i = 0; i < maxi; ++i) | ||||
|       if(internal::abs(coeff(i, j)) > threshold) return false; | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_TRIANGULARMATRIX_H | ||||
							
								
								
									
										284
									
								
								latan/Eigen/src/Core/VectorBlock.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										284
									
								
								latan/Eigen/src/Core/VectorBlock.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,284 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_VECTORBLOCK_H | ||||
| #define EIGEN_VECTORBLOCK_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class VectorBlock | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Expression of a fixed-size or dynamic-size sub-vector | ||||
|   * | ||||
|   * \param VectorType the type of the object in which we are taking a sub-vector | ||||
|   * \param Size size of the sub-vector we are taking at compile time (optional) | ||||
|   * | ||||
|   * This class represents an expression of either a fixed-size or dynamic-size sub-vector. | ||||
|   * It is the return type of DenseBase::segment(Index,Index) and DenseBase::segment<int>(Index) and | ||||
|   * most of the time this is the only way it is used. | ||||
|   * | ||||
|   * However, if you want to directly maniputate sub-vector expressions, | ||||
|   * for instance if you want to write a function returning such an expression, you | ||||
|   * will need to use this class. | ||||
|   * | ||||
|   * Here is an example illustrating the dynamic case: | ||||
|   * \include class_VectorBlock.cpp | ||||
|   * Output: \verbinclude class_VectorBlock.out | ||||
|   * | ||||
|   * \note Even though this expression has dynamic size, in the case where \a VectorType | ||||
|   * has fixed size, this expression inherits a fixed maximal size which means that evaluating | ||||
|   * it does not cause a dynamic memory allocation. | ||||
|   * | ||||
|   * Here is an example illustrating the fixed-size case: | ||||
|   * \include class_FixedVectorBlock.cpp | ||||
|   * Output: \verbinclude class_FixedVectorBlock.out | ||||
|   * | ||||
|   * \sa class Block, DenseBase::segment(Index,Index,Index,Index), DenseBase::segment(Index,Index) | ||||
|   */ | ||||
|  | ||||
| namespace internal { | ||||
| template<typename VectorType, int Size> | ||||
| struct traits<VectorBlock<VectorType, Size> > | ||||
|   : public traits<Block<VectorType, | ||||
|                      traits<VectorType>::Flags & RowMajorBit ? 1 : Size, | ||||
|                      traits<VectorType>::Flags & RowMajorBit ? Size : 1> > | ||||
| { | ||||
| }; | ||||
| } | ||||
|  | ||||
| template<typename VectorType, int Size> class VectorBlock | ||||
|   : public Block<VectorType, | ||||
|                      internal::traits<VectorType>::Flags & RowMajorBit ? 1 : Size, | ||||
|                      internal::traits<VectorType>::Flags & RowMajorBit ? Size : 1> | ||||
| { | ||||
|     typedef Block<VectorType, | ||||
|                      internal::traits<VectorType>::Flags & RowMajorBit ? 1 : Size, | ||||
|                      internal::traits<VectorType>::Flags & RowMajorBit ? Size : 1> Base; | ||||
|     enum { | ||||
|       IsColVector = !(internal::traits<VectorType>::Flags & RowMajorBit) | ||||
|     }; | ||||
|   public: | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(VectorBlock) | ||||
|  | ||||
|     using Base::operator=; | ||||
|  | ||||
|     /** Dynamic-size constructor | ||||
|       */ | ||||
|     inline VectorBlock(VectorType& vector, Index start, Index size) | ||||
|       : Base(vector, | ||||
|              IsColVector ? start : 0, IsColVector ? 0 : start, | ||||
|              IsColVector ? size  : 1, IsColVector ? 1 : size) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock); | ||||
|     } | ||||
|  | ||||
|     /** Fixed-size constructor | ||||
|       */ | ||||
|     inline VectorBlock(VectorType& vector, Index start) | ||||
|       : Base(vector, IsColVector ? start : 0, IsColVector ? 0 : start) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock); | ||||
|     } | ||||
| }; | ||||
|  | ||||
|  | ||||
| /** \returns a dynamic-size expression of a segment (i.e. a vector block) in *this. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * \param start the first coefficient in the segment | ||||
|   * \param size the number of coefficients in the segment | ||||
|   * | ||||
|   * Example: \include MatrixBase_segment_int_int.cpp | ||||
|   * Output: \verbinclude MatrixBase_segment_int_int.out | ||||
|   * | ||||
|   * \note Even though the returned expression has dynamic size, in the case | ||||
|   * when it is applied to a fixed-size vector, it inherits a fixed maximal size, | ||||
|   * which means that evaluating it does not cause a dynamic memory allocation. | ||||
|   * | ||||
|   * \sa class Block, segment(Index) | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline typename DenseBase<Derived>::SegmentReturnType | ||||
| DenseBase<Derived>::segment(Index start, Index size) | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   return SegmentReturnType(derived(), start, size); | ||||
| } | ||||
|  | ||||
| /** This is the const version of segment(Index,Index).*/ | ||||
| template<typename Derived> | ||||
| inline typename DenseBase<Derived>::ConstSegmentReturnType | ||||
| DenseBase<Derived>::segment(Index start, Index size) const | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   return ConstSegmentReturnType(derived(), start, size); | ||||
| } | ||||
|  | ||||
| /** \returns a dynamic-size expression of the first coefficients of *this. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * \param size the number of coefficients in the block | ||||
|   * | ||||
|   * Example: \include MatrixBase_start_int.cpp | ||||
|   * Output: \verbinclude MatrixBase_start_int.out | ||||
|   * | ||||
|   * \note Even though the returned expression has dynamic size, in the case | ||||
|   * when it is applied to a fixed-size vector, it inherits a fixed maximal size, | ||||
|   * which means that evaluating it does not cause a dynamic memory allocation. | ||||
|   * | ||||
|   * \sa class Block, block(Index,Index) | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline typename DenseBase<Derived>::SegmentReturnType | ||||
| DenseBase<Derived>::head(Index size) | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   return SegmentReturnType(derived(), 0, size); | ||||
| } | ||||
|  | ||||
| /** This is the const version of head(Index).*/ | ||||
| template<typename Derived> | ||||
| inline typename DenseBase<Derived>::ConstSegmentReturnType | ||||
| DenseBase<Derived>::head(Index size) const | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   return ConstSegmentReturnType(derived(), 0, size); | ||||
| } | ||||
|  | ||||
| /** \returns a dynamic-size expression of the last coefficients of *this. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * \param size the number of coefficients in the block | ||||
|   * | ||||
|   * Example: \include MatrixBase_end_int.cpp | ||||
|   * Output: \verbinclude MatrixBase_end_int.out | ||||
|   * | ||||
|   * \note Even though the returned expression has dynamic size, in the case | ||||
|   * when it is applied to a fixed-size vector, it inherits a fixed maximal size, | ||||
|   * which means that evaluating it does not cause a dynamic memory allocation. | ||||
|   * | ||||
|   * \sa class Block, block(Index,Index) | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline typename DenseBase<Derived>::SegmentReturnType | ||||
| DenseBase<Derived>::tail(Index size) | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   return SegmentReturnType(derived(), this->size() - size, size); | ||||
| } | ||||
|  | ||||
| /** This is the const version of tail(Index).*/ | ||||
| template<typename Derived> | ||||
| inline typename DenseBase<Derived>::ConstSegmentReturnType | ||||
| DenseBase<Derived>::tail(Index size) const | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   return ConstSegmentReturnType(derived(), this->size() - size, size); | ||||
| } | ||||
|  | ||||
| /** \returns a fixed-size expression of a segment (i.e. a vector block) in \c *this | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * The template parameter \a Size is the number of coefficients in the block | ||||
|   * | ||||
|   * \param start the index of the first element of the sub-vector | ||||
|   * | ||||
|   * Example: \include MatrixBase_template_int_segment.cpp | ||||
|   * Output: \verbinclude MatrixBase_template_int_segment.out | ||||
|   * | ||||
|   * \sa class Block | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<int Size> | ||||
| inline typename DenseBase<Derived>::template FixedSegmentReturnType<Size>::Type | ||||
| DenseBase<Derived>::segment(Index start) | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   return typename FixedSegmentReturnType<Size>::Type(derived(), start); | ||||
| } | ||||
|  | ||||
| /** This is the const version of segment<int>(Index).*/ | ||||
| template<typename Derived> | ||||
| template<int Size> | ||||
| inline typename DenseBase<Derived>::template ConstFixedSegmentReturnType<Size>::Type | ||||
| DenseBase<Derived>::segment(Index start) const | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   return typename ConstFixedSegmentReturnType<Size>::Type(derived(), start); | ||||
| } | ||||
|  | ||||
| /** \returns a fixed-size expression of the first coefficients of *this. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * The template parameter \a Size is the number of coefficients in the block | ||||
|   * | ||||
|   * Example: \include MatrixBase_template_int_start.cpp | ||||
|   * Output: \verbinclude MatrixBase_template_int_start.out | ||||
|   * | ||||
|   * \sa class Block | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<int Size> | ||||
| inline typename DenseBase<Derived>::template FixedSegmentReturnType<Size>::Type | ||||
| DenseBase<Derived>::head() | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   return typename FixedSegmentReturnType<Size>::Type(derived(), 0); | ||||
| } | ||||
|  | ||||
| /** This is the const version of head<int>().*/ | ||||
| template<typename Derived> | ||||
| template<int Size> | ||||
| inline typename DenseBase<Derived>::template ConstFixedSegmentReturnType<Size>::Type | ||||
| DenseBase<Derived>::head() const | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   return typename ConstFixedSegmentReturnType<Size>::Type(derived(), 0); | ||||
| } | ||||
|  | ||||
| /** \returns a fixed-size expression of the last coefficients of *this. | ||||
|   * | ||||
|   * \only_for_vectors | ||||
|   * | ||||
|   * The template parameter \a Size is the number of coefficients in the block | ||||
|   * | ||||
|   * Example: \include MatrixBase_template_int_end.cpp | ||||
|   * Output: \verbinclude MatrixBase_template_int_end.out | ||||
|   * | ||||
|   * \sa class Block | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<int Size> | ||||
| inline typename DenseBase<Derived>::template FixedSegmentReturnType<Size>::Type | ||||
| DenseBase<Derived>::tail() | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   return typename FixedSegmentReturnType<Size>::Type(derived(), size() - Size); | ||||
| } | ||||
|  | ||||
| /** This is the const version of tail<int>.*/ | ||||
| template<typename Derived> | ||||
| template<int Size> | ||||
| inline typename DenseBase<Derived>::template ConstFixedSegmentReturnType<Size>::Type | ||||
| DenseBase<Derived>::tail() const | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   return typename ConstFixedSegmentReturnType<Size>::Type(derived(), size() - Size); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_VECTORBLOCK_H | ||||
							
								
								
									
										598
									
								
								latan/Eigen/src/Core/VectorwiseOp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										598
									
								
								latan/Eigen/src/Core/VectorwiseOp.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,598 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_PARTIAL_REDUX_H | ||||
| #define EIGEN_PARTIAL_REDUX_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| /** \class PartialReduxExpr | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Generic expression of a partially reduxed matrix | ||||
|   * | ||||
|   * \tparam MatrixType the type of the matrix we are applying the redux operation | ||||
|   * \tparam MemberOp type of the member functor | ||||
|   * \tparam Direction indicates the direction of the redux (#Vertical or #Horizontal) | ||||
|   * | ||||
|   * This class represents an expression of a partial redux operator of a matrix. | ||||
|   * It is the return type of some VectorwiseOp functions, | ||||
|   * and most of the time this is the only way it is used. | ||||
|   * | ||||
|   * \sa class VectorwiseOp | ||||
|   */ | ||||
|  | ||||
| template< typename MatrixType, typename MemberOp, int Direction> | ||||
| class PartialReduxExpr; | ||||
|  | ||||
| namespace internal { | ||||
| template<typename MatrixType, typename MemberOp, int Direction> | ||||
| struct traits<PartialReduxExpr<MatrixType, MemberOp, Direction> > | ||||
|  : traits<MatrixType> | ||||
| { | ||||
|   typedef typename MemberOp::result_type Scalar; | ||||
|   typedef typename traits<MatrixType>::StorageKind StorageKind; | ||||
|   typedef typename traits<MatrixType>::XprKind XprKind; | ||||
|   typedef typename MatrixType::Scalar InputScalar; | ||||
|   typedef typename nested<MatrixType>::type MatrixTypeNested; | ||||
|   typedef typename remove_all<MatrixTypeNested>::type _MatrixTypeNested; | ||||
|   enum { | ||||
|     RowsAtCompileTime = Direction==Vertical   ? 1 : MatrixType::RowsAtCompileTime, | ||||
|     ColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::ColsAtCompileTime, | ||||
|     MaxRowsAtCompileTime = Direction==Vertical   ? 1 : MatrixType::MaxRowsAtCompileTime, | ||||
|     MaxColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::MaxColsAtCompileTime, | ||||
|     Flags0 = (unsigned int)_MatrixTypeNested::Flags & HereditaryBits, | ||||
|     Flags = (Flags0 & ~RowMajorBit) | (RowsAtCompileTime == 1 ? RowMajorBit : 0), | ||||
|     TraversalSize = Direction==Vertical ? RowsAtCompileTime : ColsAtCompileTime | ||||
|   }; | ||||
|   #if EIGEN_GNUC_AT_LEAST(3,4) | ||||
|   typedef typename MemberOp::template Cost<InputScalar,int(TraversalSize)> CostOpType; | ||||
|   #else | ||||
|   typedef typename MemberOp::template Cost<InputScalar,TraversalSize> CostOpType; | ||||
|   #endif | ||||
|   enum { | ||||
|     CoeffReadCost = TraversalSize * traits<_MatrixTypeNested>::CoeffReadCost + int(CostOpType::value) | ||||
|   }; | ||||
| }; | ||||
| } | ||||
|  | ||||
| template< typename MatrixType, typename MemberOp, int Direction> | ||||
| class PartialReduxExpr : internal::no_assignment_operator, | ||||
|   public internal::dense_xpr_base< PartialReduxExpr<MatrixType, MemberOp, Direction> >::type | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef typename internal::dense_xpr_base<PartialReduxExpr>::type Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(PartialReduxExpr) | ||||
|     typedef typename internal::traits<PartialReduxExpr>::MatrixTypeNested MatrixTypeNested; | ||||
|     typedef typename internal::traits<PartialReduxExpr>::_MatrixTypeNested _MatrixTypeNested; | ||||
|  | ||||
|     PartialReduxExpr(const MatrixType& mat, const MemberOp& func = MemberOp()) | ||||
|       : m_matrix(mat), m_functor(func) {} | ||||
|  | ||||
|     Index rows() const { return (Direction==Vertical   ? 1 : m_matrix.rows()); } | ||||
|     Index cols() const { return (Direction==Horizontal ? 1 : m_matrix.cols()); } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE const Scalar coeff(Index i, Index j) const | ||||
|     { | ||||
|       if (Direction==Vertical) | ||||
|         return m_functor(m_matrix.col(j)); | ||||
|       else | ||||
|         return m_functor(m_matrix.row(i)); | ||||
|     } | ||||
|  | ||||
|     const Scalar coeff(Index index) const | ||||
|     { | ||||
|       if (Direction==Vertical) | ||||
|         return m_functor(m_matrix.col(index)); | ||||
|       else | ||||
|         return m_functor(m_matrix.row(index)); | ||||
|     } | ||||
|  | ||||
|   protected: | ||||
|     MatrixTypeNested m_matrix; | ||||
|     const MemberOp m_functor; | ||||
| }; | ||||
|  | ||||
| #define EIGEN_MEMBER_FUNCTOR(MEMBER,COST)                               \ | ||||
|   template <typename ResultType>                                        \ | ||||
|   struct member_##MEMBER {                                           \ | ||||
|     EIGEN_EMPTY_STRUCT_CTOR(member_##MEMBER)                         \ | ||||
|     typedef ResultType result_type;                                     \ | ||||
|     template<typename Scalar, int Size> struct Cost                     \ | ||||
|     { enum { value = COST }; };                                         \ | ||||
|     template<typename XprType>                                          \ | ||||
|     EIGEN_STRONG_INLINE ResultType operator()(const XprType& mat) const \ | ||||
|     { return mat.MEMBER(); } \ | ||||
|   } | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| EIGEN_MEMBER_FUNCTOR(squaredNorm, Size * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost); | ||||
| EIGEN_MEMBER_FUNCTOR(norm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost); | ||||
| EIGEN_MEMBER_FUNCTOR(stableNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost); | ||||
| EIGEN_MEMBER_FUNCTOR(blueNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost); | ||||
| EIGEN_MEMBER_FUNCTOR(hypotNorm, (Size-1) * functor_traits<scalar_hypot_op<Scalar> >::Cost ); | ||||
| EIGEN_MEMBER_FUNCTOR(sum, (Size-1)*NumTraits<Scalar>::AddCost); | ||||
| EIGEN_MEMBER_FUNCTOR(mean, (Size-1)*NumTraits<Scalar>::AddCost + NumTraits<Scalar>::MulCost); | ||||
| EIGEN_MEMBER_FUNCTOR(minCoeff, (Size-1)*NumTraits<Scalar>::AddCost); | ||||
| EIGEN_MEMBER_FUNCTOR(maxCoeff, (Size-1)*NumTraits<Scalar>::AddCost); | ||||
| EIGEN_MEMBER_FUNCTOR(all, (Size-1)*NumTraits<Scalar>::AddCost); | ||||
| EIGEN_MEMBER_FUNCTOR(any, (Size-1)*NumTraits<Scalar>::AddCost); | ||||
| EIGEN_MEMBER_FUNCTOR(count, (Size-1)*NumTraits<Scalar>::AddCost); | ||||
| EIGEN_MEMBER_FUNCTOR(prod, (Size-1)*NumTraits<Scalar>::MulCost); | ||||
|  | ||||
|  | ||||
| template <typename BinaryOp, typename Scalar> | ||||
| struct member_redux { | ||||
|   typedef typename result_of< | ||||
|                      BinaryOp(Scalar) | ||||
|                    >::type  result_type; | ||||
|   template<typename _Scalar, int Size> struct Cost | ||||
|   { enum { value = (Size-1) * functor_traits<BinaryOp>::Cost }; }; | ||||
|   member_redux(const BinaryOp func) : m_functor(func) {} | ||||
|   template<typename Derived> | ||||
|   inline result_type operator()(const DenseBase<Derived>& mat) const | ||||
|   { return mat.redux(m_functor); } | ||||
|   const BinaryOp m_functor; | ||||
| }; | ||||
| } | ||||
|  | ||||
| /** \class VectorwiseOp | ||||
|   * \ingroup Core_Module | ||||
|   * | ||||
|   * \brief Pseudo expression providing partial reduction operations | ||||
|   * | ||||
|   * \param ExpressionType the type of the object on which to do partial reductions | ||||
|   * \param Direction indicates the direction of the redux (#Vertical or #Horizontal) | ||||
|   * | ||||
|   * This class represents a pseudo expression with partial reduction features. | ||||
|   * It is the return type of DenseBase::colwise() and DenseBase::rowwise() | ||||
|   * and most of the time this is the only way it is used. | ||||
|   * | ||||
|   * Example: \include MatrixBase_colwise.cpp | ||||
|   * Output: \verbinclude MatrixBase_colwise.out | ||||
|   * | ||||
|   * \sa DenseBase::colwise(), DenseBase::rowwise(), class PartialReduxExpr | ||||
|   */ | ||||
| template<typename ExpressionType, int Direction> class VectorwiseOp | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef typename ExpressionType::Scalar Scalar; | ||||
|     typedef typename ExpressionType::RealScalar RealScalar; | ||||
|     typedef typename ExpressionType::Index Index; | ||||
|     typedef typename internal::conditional<internal::must_nest_by_value<ExpressionType>::ret, | ||||
|         ExpressionType, ExpressionType&>::type ExpressionTypeNested; | ||||
|     typedef typename internal::remove_all<ExpressionTypeNested>::type ExpressionTypeNestedCleaned; | ||||
|  | ||||
|     template<template<typename _Scalar> class Functor, | ||||
|                       typename Scalar=typename internal::traits<ExpressionType>::Scalar> struct ReturnType | ||||
|     { | ||||
|       typedef PartialReduxExpr<ExpressionType, | ||||
|                                Functor<Scalar>, | ||||
|                                Direction | ||||
|                               > Type; | ||||
|     }; | ||||
|  | ||||
|     template<typename BinaryOp> struct ReduxReturnType | ||||
|     { | ||||
|       typedef PartialReduxExpr<ExpressionType, | ||||
|                                internal::member_redux<BinaryOp,typename internal::traits<ExpressionType>::Scalar>, | ||||
|                                Direction | ||||
|                               > Type; | ||||
|     }; | ||||
|  | ||||
|     enum { | ||||
|       IsVertical   = (Direction==Vertical) ? 1 : 0, | ||||
|       IsHorizontal = (Direction==Horizontal) ? 1 : 0 | ||||
|     }; | ||||
|  | ||||
|   protected: | ||||
|  | ||||
|     /** \internal | ||||
|       * \returns the i-th subvector according to the \c Direction */ | ||||
|     typedef typename internal::conditional<Direction==Vertical, | ||||
|                                typename ExpressionType::ColXpr, | ||||
|                                typename ExpressionType::RowXpr>::type SubVector; | ||||
|     SubVector subVector(Index i) | ||||
|     { | ||||
|       return SubVector(m_matrix.derived(),i); | ||||
|     } | ||||
|  | ||||
|     /** \internal | ||||
|       * \returns the number of subvectors in the direction \c Direction */ | ||||
|     Index subVectors() const | ||||
|     { return Direction==Vertical?m_matrix.cols():m_matrix.rows(); } | ||||
|  | ||||
|     template<typename OtherDerived> struct ExtendedType { | ||||
|       typedef Replicate<OtherDerived, | ||||
|                         Direction==Vertical   ? 1 : ExpressionType::RowsAtCompileTime, | ||||
|                         Direction==Horizontal ? 1 : ExpressionType::ColsAtCompileTime> Type; | ||||
|     }; | ||||
|  | ||||
|     /** \internal | ||||
|       * Replicates a vector to match the size of \c *this */ | ||||
|     template<typename OtherDerived> | ||||
|     typename ExtendedType<OtherDerived>::Type | ||||
|     extendedTo(const DenseBase<OtherDerived>& other) const | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Vertical, OtherDerived::MaxColsAtCompileTime==1), | ||||
|                           YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED) | ||||
|       EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Horizontal, OtherDerived::MaxRowsAtCompileTime==1), | ||||
|                           YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED) | ||||
|       return typename ExtendedType<OtherDerived>::Type | ||||
|                       (other.derived(), | ||||
|                        Direction==Vertical   ? 1 : m_matrix.rows(), | ||||
|                        Direction==Horizontal ? 1 : m_matrix.cols()); | ||||
|     } | ||||
|  | ||||
|   public: | ||||
|  | ||||
|     inline VectorwiseOp(ExpressionType& matrix) : m_matrix(matrix) {} | ||||
|  | ||||
|     /** \internal */ | ||||
|     inline const ExpressionType& _expression() const { return m_matrix; } | ||||
|  | ||||
|     /** \returns a row or column vector expression of \c *this reduxed by \a func | ||||
|       * | ||||
|       * The template parameter \a BinaryOp is the type of the functor | ||||
|       * of the custom redux operator. Note that func must be an associative operator. | ||||
|       * | ||||
|       * \sa class VectorwiseOp, DenseBase::colwise(), DenseBase::rowwise() | ||||
|       */ | ||||
|     template<typename BinaryOp> | ||||
|     const typename ReduxReturnType<BinaryOp>::Type | ||||
|     redux(const BinaryOp& func = BinaryOp()) const | ||||
|     { return typename ReduxReturnType<BinaryOp>::Type(_expression(), func); } | ||||
|  | ||||
|     /** \returns a row (or column) vector expression of the smallest coefficient | ||||
|       * of each column (or row) of the referenced expression. | ||||
|       * | ||||
|       * Example: \include PartialRedux_minCoeff.cpp | ||||
|       * Output: \verbinclude PartialRedux_minCoeff.out | ||||
|       * | ||||
|       * \sa DenseBase::minCoeff() */ | ||||
|     const typename ReturnType<internal::member_minCoeff>::Type minCoeff() const | ||||
|     { return _expression(); } | ||||
|  | ||||
|     /** \returns a row (or column) vector expression of the largest coefficient | ||||
|       * of each column (or row) of the referenced expression. | ||||
|       * | ||||
|       * Example: \include PartialRedux_maxCoeff.cpp | ||||
|       * Output: \verbinclude PartialRedux_maxCoeff.out | ||||
|       * | ||||
|       * \sa DenseBase::maxCoeff() */ | ||||
|     const typename ReturnType<internal::member_maxCoeff>::Type maxCoeff() const | ||||
|     { return _expression(); } | ||||
|  | ||||
|     /** \returns a row (or column) vector expression of the squared norm | ||||
|       * of each column (or row) of the referenced expression. | ||||
|       * | ||||
|       * Example: \include PartialRedux_squaredNorm.cpp | ||||
|       * Output: \verbinclude PartialRedux_squaredNorm.out | ||||
|       * | ||||
|       * \sa DenseBase::squaredNorm() */ | ||||
|     const typename ReturnType<internal::member_squaredNorm,RealScalar>::Type squaredNorm() const | ||||
|     { return _expression(); } | ||||
|  | ||||
|     /** \returns a row (or column) vector expression of the norm | ||||
|       * of each column (or row) of the referenced expression. | ||||
|       * | ||||
|       * Example: \include PartialRedux_norm.cpp | ||||
|       * Output: \verbinclude PartialRedux_norm.out | ||||
|       * | ||||
|       * \sa DenseBase::norm() */ | ||||
|     const typename ReturnType<internal::member_norm,RealScalar>::Type norm() const | ||||
|     { return _expression(); } | ||||
|  | ||||
|  | ||||
|     /** \returns a row (or column) vector expression of the norm | ||||
|       * of each column (or row) of the referenced expression, using | ||||
|       * blue's algorithm. | ||||
|       * | ||||
|       * \sa DenseBase::blueNorm() */ | ||||
|     const typename ReturnType<internal::member_blueNorm,RealScalar>::Type blueNorm() const | ||||
|     { return _expression(); } | ||||
|  | ||||
|  | ||||
|     /** \returns a row (or column) vector expression of the norm | ||||
|       * of each column (or row) of the referenced expression, avoiding | ||||
|       * underflow and overflow. | ||||
|       * | ||||
|       * \sa DenseBase::stableNorm() */ | ||||
|     const typename ReturnType<internal::member_stableNorm,RealScalar>::Type stableNorm() const | ||||
|     { return _expression(); } | ||||
|  | ||||
|  | ||||
|     /** \returns a row (or column) vector expression of the norm | ||||
|       * of each column (or row) of the referenced expression, avoiding | ||||
|       * underflow and overflow using a concatenation of hypot() calls. | ||||
|       * | ||||
|       * \sa DenseBase::hypotNorm() */ | ||||
|     const typename ReturnType<internal::member_hypotNorm,RealScalar>::Type hypotNorm() const | ||||
|     { return _expression(); } | ||||
|  | ||||
|     /** \returns a row (or column) vector expression of the sum | ||||
|       * of each column (or row) of the referenced expression. | ||||
|       * | ||||
|       * Example: \include PartialRedux_sum.cpp | ||||
|       * Output: \verbinclude PartialRedux_sum.out | ||||
|       * | ||||
|       * \sa DenseBase::sum() */ | ||||
|     const typename ReturnType<internal::member_sum>::Type sum() const | ||||
|     { return _expression(); } | ||||
|  | ||||
|     /** \returns a row (or column) vector expression of the mean | ||||
|     * of each column (or row) of the referenced expression. | ||||
|     * | ||||
|     * \sa DenseBase::mean() */ | ||||
|     const typename ReturnType<internal::member_mean>::Type mean() const | ||||
|     { return _expression(); } | ||||
|  | ||||
|     /** \returns a row (or column) vector expression representing | ||||
|       * whether \b all coefficients of each respective column (or row) are \c true. | ||||
|       * | ||||
|       * \sa DenseBase::all() */ | ||||
|     const typename ReturnType<internal::member_all>::Type all() const | ||||
|     { return _expression(); } | ||||
|  | ||||
|     /** \returns a row (or column) vector expression representing | ||||
|       * whether \b at \b least one coefficient of each respective column (or row) is \c true. | ||||
|       * | ||||
|       * \sa DenseBase::any() */ | ||||
|     const typename ReturnType<internal::member_any>::Type any() const | ||||
|     { return _expression(); } | ||||
|  | ||||
|     /** \returns a row (or column) vector expression representing | ||||
|       * the number of \c true coefficients of each respective column (or row). | ||||
|       * | ||||
|       * Example: \include PartialRedux_count.cpp | ||||
|       * Output: \verbinclude PartialRedux_count.out | ||||
|       * | ||||
|       * \sa DenseBase::count() */ | ||||
|     const PartialReduxExpr<ExpressionType, internal::member_count<Index>, Direction> count() const | ||||
|     { return _expression(); } | ||||
|  | ||||
|     /** \returns a row (or column) vector expression of the product | ||||
|       * of each column (or row) of the referenced expression. | ||||
|       * | ||||
|       * Example: \include PartialRedux_prod.cpp | ||||
|       * Output: \verbinclude PartialRedux_prod.out | ||||
|       * | ||||
|       * \sa DenseBase::prod() */ | ||||
|     const typename ReturnType<internal::member_prod>::Type prod() const | ||||
|     { return _expression(); } | ||||
|  | ||||
|  | ||||
|     /** \returns a matrix expression | ||||
|       * where each column (or row) are reversed. | ||||
|       * | ||||
|       * Example: \include Vectorwise_reverse.cpp | ||||
|       * Output: \verbinclude Vectorwise_reverse.out | ||||
|       * | ||||
|       * \sa DenseBase::reverse() */ | ||||
|     const Reverse<ExpressionType, Direction> reverse() const | ||||
|     { return Reverse<ExpressionType, Direction>( _expression() ); } | ||||
|  | ||||
|     typedef Replicate<ExpressionType,Direction==Vertical?Dynamic:1,Direction==Horizontal?Dynamic:1> ReplicateReturnType; | ||||
|     const ReplicateReturnType replicate(Index factor) const; | ||||
|  | ||||
|     /** | ||||
|       * \return an expression of the replication of each column (or row) of \c *this | ||||
|       * | ||||
|       * Example: \include DirectionWise_replicate.cpp | ||||
|       * Output: \verbinclude DirectionWise_replicate.out | ||||
|       * | ||||
|       * \sa VectorwiseOp::replicate(Index), DenseBase::replicate(), class Replicate | ||||
|       */ | ||||
|     // NOTE implemented here because of sunstudio's compilation errors | ||||
|     template<int Factor> const Replicate<ExpressionType,(IsVertical?Factor:1),(IsHorizontal?Factor:1)> | ||||
|     replicate(Index factor = Factor) const | ||||
|     { | ||||
|       return Replicate<ExpressionType,Direction==Vertical?Factor:1,Direction==Horizontal?Factor:1> | ||||
|           (_expression(),Direction==Vertical?factor:1,Direction==Horizontal?factor:1); | ||||
|     } | ||||
|  | ||||
| /////////// Artithmetic operators /////////// | ||||
|  | ||||
|     /** Copies the vector \a other to each subvector of \c *this */ | ||||
|     template<typename OtherDerived> | ||||
|     ExpressionType& operator=(const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) | ||||
|       EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) | ||||
|       //eigen_assert((m_matrix.isNull()) == (other.isNull())); FIXME | ||||
|       return const_cast<ExpressionType&>(m_matrix = extendedTo(other.derived())); | ||||
|     } | ||||
|  | ||||
|     /** Adds the vector \a other to each subvector of \c *this */ | ||||
|     template<typename OtherDerived> | ||||
|     ExpressionType& operator+=(const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) | ||||
|       EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) | ||||
|       return const_cast<ExpressionType&>(m_matrix += extendedTo(other.derived())); | ||||
|     } | ||||
|  | ||||
|     /** Substracts the vector \a other to each subvector of \c *this */ | ||||
|     template<typename OtherDerived> | ||||
|     ExpressionType& operator-=(const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) | ||||
|       EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) | ||||
|       return const_cast<ExpressionType&>(m_matrix -= extendedTo(other.derived())); | ||||
|     } | ||||
|  | ||||
|     /** Multiples each subvector of \c *this by the vector \a other */ | ||||
|     template<typename OtherDerived> | ||||
|     ExpressionType& operator*=(const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) | ||||
|       EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType) | ||||
|       EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) | ||||
|       m_matrix *= extendedTo(other.derived()); | ||||
|       return const_cast<ExpressionType&>(m_matrix); | ||||
|     } | ||||
|  | ||||
|     /** Divides each subvector of \c *this by the vector \a other */ | ||||
|     template<typename OtherDerived> | ||||
|     ExpressionType& operator/=(const DenseBase<OtherDerived>& other) | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) | ||||
|       EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType) | ||||
|       EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) | ||||
|       m_matrix /= extendedTo(other.derived()); | ||||
|       return const_cast<ExpressionType&>(m_matrix); | ||||
|     } | ||||
|  | ||||
|     /** Returns the expression of the sum of the vector \a other to each subvector of \c *this */ | ||||
|     template<typename OtherDerived> EIGEN_STRONG_INLINE | ||||
|     CwiseBinaryOp<internal::scalar_sum_op<Scalar>, | ||||
|                   const ExpressionTypeNestedCleaned, | ||||
|                   const typename ExtendedType<OtherDerived>::Type> | ||||
|     operator+(const DenseBase<OtherDerived>& other) const | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) | ||||
|       EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) | ||||
|       return m_matrix + extendedTo(other.derived()); | ||||
|     } | ||||
|  | ||||
|     /** Returns the expression of the difference between each subvector of \c *this and the vector \a other */ | ||||
|     template<typename OtherDerived> | ||||
|     CwiseBinaryOp<internal::scalar_difference_op<Scalar>, | ||||
|                   const ExpressionTypeNestedCleaned, | ||||
|                   const typename ExtendedType<OtherDerived>::Type> | ||||
|     operator-(const DenseBase<OtherDerived>& other) const | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) | ||||
|       EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) | ||||
|       return m_matrix - extendedTo(other.derived()); | ||||
|     } | ||||
|  | ||||
|     /** Returns the expression where each subvector is the product of the vector \a other | ||||
|       * by the corresponding subvector of \c *this */ | ||||
|     template<typename OtherDerived> EIGEN_STRONG_INLINE | ||||
|     CwiseBinaryOp<internal::scalar_product_op<Scalar>, | ||||
|                   const ExpressionTypeNestedCleaned, | ||||
|                   const typename ExtendedType<OtherDerived>::Type> | ||||
|     operator*(const DenseBase<OtherDerived>& other) const | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) | ||||
|       EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType) | ||||
|       EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) | ||||
|       return m_matrix * extendedTo(other.derived()); | ||||
|     } | ||||
|  | ||||
|     /** Returns the expression where each subvector is the quotient of the corresponding | ||||
|       * subvector of \c *this by the vector \a other */ | ||||
|     template<typename OtherDerived> | ||||
|     CwiseBinaryOp<internal::scalar_quotient_op<Scalar>, | ||||
|                   const ExpressionTypeNestedCleaned, | ||||
|                   const typename ExtendedType<OtherDerived>::Type> | ||||
|     operator/(const DenseBase<OtherDerived>& other) const | ||||
|     { | ||||
|       EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) | ||||
|       EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType) | ||||
|       EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) | ||||
|       return m_matrix / extendedTo(other.derived()); | ||||
|     } | ||||
|  | ||||
| /////////// Geometry module /////////// | ||||
|  | ||||
|     #if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS | ||||
|     Homogeneous<ExpressionType,Direction> homogeneous() const; | ||||
|     #endif | ||||
|  | ||||
|     typedef typename ExpressionType::PlainObject CrossReturnType; | ||||
|     template<typename OtherDerived> | ||||
|     const CrossReturnType cross(const MatrixBase<OtherDerived>& other) const; | ||||
|  | ||||
|     enum { | ||||
|       HNormalized_Size = Direction==Vertical ? internal::traits<ExpressionType>::RowsAtCompileTime | ||||
|                                              : internal::traits<ExpressionType>::ColsAtCompileTime, | ||||
|       HNormalized_SizeMinusOne = HNormalized_Size==Dynamic ? Dynamic : HNormalized_Size-1 | ||||
|     }; | ||||
|     typedef Block<const ExpressionType, | ||||
|                   Direction==Vertical   ? int(HNormalized_SizeMinusOne) | ||||
|                                         : int(internal::traits<ExpressionType>::RowsAtCompileTime), | ||||
|                   Direction==Horizontal ? int(HNormalized_SizeMinusOne) | ||||
|                                         : int(internal::traits<ExpressionType>::ColsAtCompileTime)> | ||||
|             HNormalized_Block; | ||||
|     typedef Block<const ExpressionType, | ||||
|                   Direction==Vertical   ? 1 : int(internal::traits<ExpressionType>::RowsAtCompileTime), | ||||
|                   Direction==Horizontal ? 1 : int(internal::traits<ExpressionType>::ColsAtCompileTime)> | ||||
|             HNormalized_Factors; | ||||
|     typedef CwiseBinaryOp<internal::scalar_quotient_op<typename internal::traits<ExpressionType>::Scalar>, | ||||
|                 const HNormalized_Block, | ||||
|                 const Replicate<HNormalized_Factors, | ||||
|                   Direction==Vertical   ? HNormalized_SizeMinusOne : 1, | ||||
|                   Direction==Horizontal ? HNormalized_SizeMinusOne : 1> > | ||||
|             HNormalizedReturnType; | ||||
|  | ||||
|     const HNormalizedReturnType hnormalized() const; | ||||
|  | ||||
|   protected: | ||||
|     ExpressionTypeNested m_matrix; | ||||
| }; | ||||
|  | ||||
| /** \returns a VectorwiseOp wrapper of *this providing additional partial reduction operations | ||||
|   * | ||||
|   * Example: \include MatrixBase_colwise.cpp | ||||
|   * Output: \verbinclude MatrixBase_colwise.out | ||||
|   * | ||||
|   * \sa rowwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline const typename DenseBase<Derived>::ConstColwiseReturnType | ||||
| DenseBase<Derived>::colwise() const | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| /** \returns a writable VectorwiseOp wrapper of *this providing additional partial reduction operations | ||||
|   * | ||||
|   * \sa rowwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline typename DenseBase<Derived>::ColwiseReturnType | ||||
| DenseBase<Derived>::colwise() | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| /** \returns a VectorwiseOp wrapper of *this providing additional partial reduction operations | ||||
|   * | ||||
|   * Example: \include MatrixBase_rowwise.cpp | ||||
|   * Output: \verbinclude MatrixBase_rowwise.out | ||||
|   * | ||||
|   * \sa colwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline const typename DenseBase<Derived>::ConstRowwiseReturnType | ||||
| DenseBase<Derived>::rowwise() const | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| /** \returns a writable VectorwiseOp wrapper of *this providing additional partial reduction operations | ||||
|   * | ||||
|   * \sa colwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting | ||||
|   */ | ||||
| template<typename Derived> | ||||
| inline typename DenseBase<Derived>::RowwiseReturnType | ||||
| DenseBase<Derived>::rowwise() | ||||
| { | ||||
|   return derived(); | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_PARTIAL_REDUX_H | ||||
							
								
								
									
										237
									
								
								latan/Eigen/src/Core/Visitor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										237
									
								
								latan/Eigen/src/Core/Visitor.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,237 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_VISITOR_H | ||||
| #define EIGEN_VISITOR_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<typename Visitor, typename Derived, int UnrollCount> | ||||
| struct visitor_impl | ||||
| { | ||||
|   enum { | ||||
|     col = (UnrollCount-1) / Derived::RowsAtCompileTime, | ||||
|     row = (UnrollCount-1) % Derived::RowsAtCompileTime | ||||
|   }; | ||||
|  | ||||
|   static inline void run(const Derived &mat, Visitor& visitor) | ||||
|   { | ||||
|     visitor_impl<Visitor, Derived, UnrollCount-1>::run(mat, visitor); | ||||
|     visitor(mat.coeff(row, col), row, col); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Visitor, typename Derived> | ||||
| struct visitor_impl<Visitor, Derived, 1> | ||||
| { | ||||
|   static inline void run(const Derived &mat, Visitor& visitor) | ||||
|   { | ||||
|     return visitor.init(mat.coeff(0, 0), 0, 0); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Visitor, typename Derived> | ||||
| struct visitor_impl<Visitor, Derived, Dynamic> | ||||
| { | ||||
|   typedef typename Derived::Index Index; | ||||
|   static inline void run(const Derived& mat, Visitor& visitor) | ||||
|   { | ||||
|     visitor.init(mat.coeff(0,0), 0, 0); | ||||
|     for(Index i = 1; i < mat.rows(); ++i) | ||||
|       visitor(mat.coeff(i, 0), i, 0); | ||||
|     for(Index j = 1; j < mat.cols(); ++j) | ||||
|       for(Index i = 0; i < mat.rows(); ++i) | ||||
|         visitor(mat.coeff(i, j), i, j); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /** Applies the visitor \a visitor to the whole coefficients of the matrix or vector. | ||||
|   * | ||||
|   * The template parameter \a Visitor is the type of the visitor and provides the following interface: | ||||
|   * \code | ||||
|   * struct MyVisitor { | ||||
|   *   // called for the first coefficient | ||||
|   *   void init(const Scalar& value, Index i, Index j); | ||||
|   *   // called for all other coefficients | ||||
|   *   void operator() (const Scalar& value, Index i, Index j); | ||||
|   * }; | ||||
|   * \endcode | ||||
|   * | ||||
|   * \note compared to one or two \em for \em loops, visitors offer automatic | ||||
|   * unrolling for small fixed size matrix. | ||||
|   * | ||||
|   * \sa minCoeff(Index*,Index*), maxCoeff(Index*,Index*), DenseBase::redux() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename Visitor> | ||||
| void DenseBase<Derived>::visit(Visitor& visitor) const | ||||
| { | ||||
|   enum { unroll = SizeAtCompileTime != Dynamic | ||||
|                    && CoeffReadCost != Dynamic | ||||
|                    && (SizeAtCompileTime == 1 || internal::functor_traits<Visitor>::Cost != Dynamic) | ||||
|                    && SizeAtCompileTime * CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost | ||||
|                       <= EIGEN_UNROLLING_LIMIT }; | ||||
|   return internal::visitor_impl<Visitor, Derived, | ||||
|       unroll ? int(SizeAtCompileTime) : Dynamic | ||||
|     >::run(derived(), visitor); | ||||
| } | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Base class to implement min and max visitors | ||||
|   */ | ||||
| template <typename Derived> | ||||
| struct coeff_visitor | ||||
| { | ||||
|   typedef typename Derived::Index Index; | ||||
|   typedef typename Derived::Scalar Scalar; | ||||
|   Index row, col; | ||||
|   Scalar res; | ||||
|   inline void init(const Scalar& value, Index i, Index j) | ||||
|   { | ||||
|     res = value; | ||||
|     row = i; | ||||
|     col = j; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Visitor computing the min coefficient with its value and coordinates | ||||
|   * | ||||
|   * \sa DenseBase::minCoeff(Index*, Index*) | ||||
|   */ | ||||
| template <typename Derived> | ||||
| struct min_coeff_visitor : coeff_visitor<Derived> | ||||
| { | ||||
|   typedef typename Derived::Index Index; | ||||
|   typedef typename Derived::Scalar Scalar; | ||||
|   void operator() (const Scalar& value, Index i, Index j) | ||||
|   { | ||||
|     if(value < this->res) | ||||
|     { | ||||
|       this->res = value; | ||||
|       this->row = i; | ||||
|       this->col = j; | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct functor_traits<min_coeff_visitor<Scalar> > { | ||||
|   enum { | ||||
|     Cost = NumTraits<Scalar>::AddCost | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /** \internal | ||||
|   * \brief Visitor computing the max coefficient with its value and coordinates | ||||
|   * | ||||
|   * \sa DenseBase::maxCoeff(Index*, Index*) | ||||
|   */ | ||||
| template <typename Derived> | ||||
| struct max_coeff_visitor : coeff_visitor<Derived> | ||||
| { | ||||
|   typedef typename Derived::Index Index; | ||||
|   typedef typename Derived::Scalar Scalar; | ||||
|   void operator() (const Scalar& value, Index i, Index j) | ||||
|   { | ||||
|     if(value > this->res) | ||||
|     { | ||||
|       this->res = value; | ||||
|       this->row = i; | ||||
|       this->col = j; | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Scalar> | ||||
| struct functor_traits<max_coeff_visitor<Scalar> > { | ||||
|   enum { | ||||
|     Cost = NumTraits<Scalar>::AddCost | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| /** \returns the minimum of all coefficients of *this | ||||
|   * and puts in *row and *col its location. | ||||
|   * | ||||
|   * \sa DenseBase::minCoeff(Index*), DenseBase::maxCoeff(Index*,Index*), DenseBase::visitor(), DenseBase::minCoeff() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename IndexType> | ||||
| typename internal::traits<Derived>::Scalar | ||||
| DenseBase<Derived>::minCoeff(IndexType* row, IndexType* col) const | ||||
| { | ||||
|   internal::min_coeff_visitor<Derived> minVisitor; | ||||
|   this->visit(minVisitor); | ||||
|   *row = minVisitor.row; | ||||
|   if (col) *col = minVisitor.col; | ||||
|   return minVisitor.res; | ||||
| } | ||||
|  | ||||
| /** \returns the minimum of all coefficients of *this | ||||
|   * and puts in *index its location. | ||||
|   * | ||||
|   * \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::minCoeff() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename IndexType> | ||||
| typename internal::traits<Derived>::Scalar | ||||
| DenseBase<Derived>::minCoeff(IndexType* index) const | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   internal::min_coeff_visitor<Derived> minVisitor; | ||||
|   this->visit(minVisitor); | ||||
|   *index = (RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row; | ||||
|   return minVisitor.res; | ||||
| } | ||||
|  | ||||
| /** \returns the maximum of all coefficients of *this | ||||
|   * and puts in *row and *col its location. | ||||
|   * | ||||
|   * \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::maxCoeff() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename IndexType> | ||||
| typename internal::traits<Derived>::Scalar | ||||
| DenseBase<Derived>::maxCoeff(IndexType* row, IndexType* col) const | ||||
| { | ||||
|   internal::max_coeff_visitor<Derived> maxVisitor; | ||||
|   this->visit(maxVisitor); | ||||
|   *row = maxVisitor.row; | ||||
|   if (col) *col = maxVisitor.col; | ||||
|   return maxVisitor.res; | ||||
| } | ||||
|  | ||||
| /** \returns the maximum of all coefficients of *this | ||||
|   * and puts in *index its location. | ||||
|   * | ||||
|   * \sa DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::maxCoeff() | ||||
|   */ | ||||
| template<typename Derived> | ||||
| template<typename IndexType> | ||||
| typename internal::traits<Derived>::Scalar | ||||
| DenseBase<Derived>::maxCoeff(IndexType* index) const | ||||
| { | ||||
|   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | ||||
|   internal::max_coeff_visitor<Derived> maxVisitor; | ||||
|   this->visit(maxVisitor); | ||||
|   *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row; | ||||
|   return maxVisitor.res; | ||||
| } | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_VISITOR_H | ||||
							
								
								
									
										217
									
								
								latan/Eigen/src/Core/arch/AltiVec/Complex.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								latan/Eigen/src/Core/arch/AltiVec/Complex.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,217 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_COMPLEX_ALTIVEC_H | ||||
| #define EIGEN_COMPLEX_ALTIVEC_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| static Packet4ui  p4ui_CONJ_XOR = vec_mergeh((Packet4ui)p4i_ZERO, (Packet4ui)p4f_ZERO_);//{ 0x00000000, 0x80000000, 0x00000000, 0x80000000 }; | ||||
| static Packet16uc p16uc_COMPLEX_RE   = vec_sld((Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 0), (Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 2), 8);//{ 0,1,2,3, 0,1,2,3, 8,9,10,11, 8,9,10,11 }; | ||||
| static Packet16uc p16uc_COMPLEX_IM   = vec_sld((Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 1), (Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 3), 8);//{ 4,5,6,7, 4,5,6,7, 12,13,14,15, 12,13,14,15 }; | ||||
| static Packet16uc p16uc_COMPLEX_REV  = vec_sld(p16uc_REVERSE, p16uc_REVERSE, 8);//{ 4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11 }; | ||||
| static Packet16uc p16uc_COMPLEX_REV2 = vec_sld(p16uc_FORWARD, p16uc_FORWARD, 8);//{ 8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7 }; | ||||
| static Packet16uc p16uc_PSET_HI = (Packet16uc) vec_mergeh((Packet4ui) vec_splat((Packet4ui)p16uc_FORWARD, 0), (Packet4ui) vec_splat((Packet4ui)p16uc_FORWARD, 1));//{ 0,1,2,3, 4,5,6,7, 0,1,2,3, 4,5,6,7 }; | ||||
| static Packet16uc p16uc_PSET_LO = (Packet16uc) vec_mergeh((Packet4ui) vec_splat((Packet4ui)p16uc_FORWARD, 2), (Packet4ui) vec_splat((Packet4ui)p16uc_FORWARD, 3));//{ 8,9,10,11, 12,13,14,15, 8,9,10,11, 12,13,14,15 }; | ||||
|  | ||||
| //---------- float ---------- | ||||
| struct Packet2cf | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet2cf() {} | ||||
|   EIGEN_STRONG_INLINE explicit Packet2cf(const Packet4f& a) : v(a) {} | ||||
|   Packet4f  v; | ||||
| }; | ||||
|  | ||||
| template<> struct packet_traits<std::complex<float> >  : default_packet_traits | ||||
| { | ||||
|   typedef Packet2cf type; | ||||
|   enum { | ||||
|     Vectorizable = 1, | ||||
|     AlignedOnScalar = 1, | ||||
|     size = 2, | ||||
|  | ||||
|     HasAdd    = 1, | ||||
|     HasSub    = 1, | ||||
|     HasMul    = 1, | ||||
|     HasDiv    = 1, | ||||
|     HasNegate = 1, | ||||
|     HasAbs    = 0, | ||||
|     HasAbs2   = 0, | ||||
|     HasMin    = 0, | ||||
|     HasMax    = 0, | ||||
|     HasSetLinear = 0 | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| template<> struct unpacket_traits<Packet2cf> { typedef std::complex<float> type; enum {size=2}; }; | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<float>&  from) | ||||
| { | ||||
|   Packet2cf res; | ||||
|   /* On AltiVec we cannot load 64-bit registers, so wa have to take care of alignment */ | ||||
|   if((ptrdiff_t(&from) % 16) == 0) | ||||
|     res.v = pload<Packet4f>((const float *)&from); | ||||
|   else | ||||
|     res.v = ploadu<Packet4f>((const float *)&from); | ||||
|   res.v = vec_perm(res.v, res.v, p16uc_PSET_HI); | ||||
|   return res; | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf padd<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_add(a.v,b.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf psub<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_sub(a.v,b.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pnegate(const Packet2cf& a) { return Packet2cf(pnegate(a.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pconj(const Packet2cf& a) { return Packet2cf((Packet4f)vec_xor((Packet4ui)a.v, p4ui_CONJ_XOR)); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pmul<Packet2cf>(const Packet2cf& a, const Packet2cf& b) | ||||
| { | ||||
|   Packet4f v1, v2; | ||||
|  | ||||
|   // Permute and multiply the real parts of a and b | ||||
|   v1 = vec_perm(a.v, a.v, p16uc_COMPLEX_RE); | ||||
|   // Get the imaginary parts of a | ||||
|   v2 = vec_perm(a.v, a.v, p16uc_COMPLEX_IM); | ||||
|   // multiply a_re * b  | ||||
|   v1 = vec_madd(v1, b.v, p4f_ZERO); | ||||
|   // multiply a_im * b and get the conjugate result | ||||
|   v2 = vec_madd(v2, b.v, p4f_ZERO); | ||||
|   v2 = (Packet4f) vec_xor((Packet4ui)v2, p4ui_CONJ_XOR); | ||||
|   // permute back to a proper order | ||||
|   v2 = vec_perm(v2, v2, p16uc_COMPLEX_REV); | ||||
|    | ||||
|   return Packet2cf(vec_add(v1, v2)); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pand   <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_and(a.v,b.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf por    <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_or(a.v,b.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pxor   <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_xor(a.v,b.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pandnot<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(vec_and(a.v, vec_nor(b.v,b.v))); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pload <Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload<Packet4f>((const float*)from)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf ploadu<Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu<Packet4f>((const float*)from)); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf ploaddup<Packet2cf>(const std::complex<float>*     from) | ||||
| { | ||||
|   return pset1<Packet2cf>(*from); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE void pstore <std::complex<float> >(std::complex<float> *   to, const Packet2cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((float*)to, from.v); } | ||||
| template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float> *   to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((float*)to, from.v); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE void prefetch<std::complex<float> >(const std::complex<float> *   addr) { vec_dstt((float *)addr, DST_CTRL(2,2,32), DST_CHAN); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE std::complex<float>  pfirst<Packet2cf>(const Packet2cf& a) | ||||
| { | ||||
|   std::complex<float> EIGEN_ALIGN16 res[2]; | ||||
|   pstore((float *)&res, a.v); | ||||
|  | ||||
|   return res[0]; | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf preverse(const Packet2cf& a) | ||||
| { | ||||
|   Packet4f rev_a; | ||||
|   rev_a = vec_perm(a.v, a.v, p16uc_COMPLEX_REV2); | ||||
|   return Packet2cf(rev_a); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE std::complex<float> predux<Packet2cf>(const Packet2cf& a) | ||||
| { | ||||
|   Packet4f b; | ||||
|   b = (Packet4f) vec_sld(a.v, a.v, 8); | ||||
|   b = padd(a.v, b); | ||||
|   return pfirst(Packet2cf(b)); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf preduxp<Packet2cf>(const Packet2cf* vecs) | ||||
| { | ||||
|   Packet4f b1, b2; | ||||
|    | ||||
|   b1 = (Packet4f) vec_sld(vecs[0].v, vecs[1].v, 8); | ||||
|   b2 = (Packet4f) vec_sld(vecs[1].v, vecs[0].v, 8); | ||||
|   b2 = (Packet4f) vec_sld(b2, b2, 8); | ||||
|   b2 = padd(b1, b2); | ||||
|  | ||||
|   return Packet2cf(b2); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE std::complex<float> predux_mul<Packet2cf>(const Packet2cf& a) | ||||
| { | ||||
|   Packet4f b; | ||||
|   Packet2cf prod; | ||||
|   b = (Packet4f) vec_sld(a.v, a.v, 8); | ||||
|   prod = pmul(a, Packet2cf(b)); | ||||
|  | ||||
|   return pfirst(prod); | ||||
| } | ||||
|  | ||||
| template<int Offset> | ||||
| struct palign_impl<Offset,Packet2cf> | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Packet2cf& first, const Packet2cf& second) | ||||
|   { | ||||
|     if (Offset==1) | ||||
|     { | ||||
|       first.v = vec_sld(first.v, second.v, 8); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct conj_helper<Packet2cf, Packet2cf, false,true> | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const | ||||
|   { return padd(pmul(x,y),c); } | ||||
|  | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const | ||||
|   { | ||||
|     return internal::pmul(a, pconj(b)); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct conj_helper<Packet2cf, Packet2cf, true,false> | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const | ||||
|   { return padd(pmul(x,y),c); } | ||||
|  | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const | ||||
|   { | ||||
|     return internal::pmul(pconj(a), b); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct conj_helper<Packet2cf, Packet2cf, true,true> | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const | ||||
|   { return padd(pmul(x,y),c); } | ||||
|  | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const | ||||
|   { | ||||
|     return pconj(internal::pmul(a, b)); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, const Packet2cf& b) | ||||
| { | ||||
|   // TODO optimize it for AltiVec | ||||
|   Packet2cf res = conj_helper<Packet2cf,Packet2cf,false,true>().pmul(a,b); | ||||
|   Packet4f s = vec_madd(b.v, b.v, p4f_ZERO); | ||||
|   return Packet2cf(pdiv(res.v, vec_add(s,vec_perm(s, s, p16uc_COMPLEX_REV)))); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pcplxflip<Packet2cf>(const Packet2cf& x) | ||||
| { | ||||
|   return Packet2cf(vec_perm(x.v, x.v, p16uc_COMPLEX_REV)); | ||||
| } | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_COMPLEX_ALTIVEC_H | ||||
							
								
								
									
										498
									
								
								latan/Eigen/src/Core/arch/AltiVec/PacketMath.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										498
									
								
								latan/Eigen/src/Core/arch/AltiVec/PacketMath.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,498 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008 Konstantinos Margaritis <markos@codex.gr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_PACKET_MATH_ALTIVEC_H | ||||
| #define EIGEN_PACKET_MATH_ALTIVEC_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| #ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD | ||||
| #define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 4 | ||||
| #endif | ||||
|  | ||||
| #ifndef EIGEN_HAS_FUSE_CJMADD | ||||
| #define EIGEN_HAS_FUSE_CJMADD 1 | ||||
| #endif | ||||
|  | ||||
| // NOTE Altivec has 32 registers, but Eigen only accepts a value of 8 or 16 | ||||
| #ifndef EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS | ||||
| #define EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS 16 | ||||
| #endif | ||||
|  | ||||
| typedef __vector float          Packet4f; | ||||
| typedef __vector int            Packet4i; | ||||
| typedef __vector unsigned int   Packet4ui; | ||||
| typedef __vector __bool int     Packet4bi; | ||||
| typedef __vector short int      Packet8i; | ||||
| typedef __vector unsigned char  Packet16uc; | ||||
|  | ||||
| // We don't want to write the same code all the time, but we need to reuse the constants | ||||
| // and it doesn't really work to declare them global, so we define macros instead | ||||
|  | ||||
| #define _EIGEN_DECLARE_CONST_FAST_Packet4f(NAME,X) \ | ||||
|   Packet4f p4f_##NAME = (Packet4f) vec_splat_s32(X) | ||||
|  | ||||
| #define _EIGEN_DECLARE_CONST_FAST_Packet4i(NAME,X) \ | ||||
|   Packet4i p4i_##NAME = vec_splat_s32(X) | ||||
|  | ||||
| #define _EIGEN_DECLARE_CONST_Packet4f(NAME,X) \ | ||||
|   Packet4f p4f_##NAME = pset1<Packet4f>(X) | ||||
|  | ||||
| #define _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(NAME,X) \ | ||||
|   Packet4f p4f_##NAME = vreinterpretq_f32_u32(pset1<int>(X)) | ||||
|  | ||||
| #define _EIGEN_DECLARE_CONST_Packet4i(NAME,X) \ | ||||
|   Packet4i p4i_##NAME = pset1<Packet4i>(X) | ||||
|  | ||||
| #define DST_CHAN 1 | ||||
| #define DST_CTRL(size, count, stride) (((size) << 24) | ((count) << 16) | (stride)) | ||||
|  | ||||
| // Define global static constants: | ||||
| static Packet4f p4f_COUNTDOWN = { 3.0, 2.0, 1.0, 0.0 }; | ||||
| static Packet4i p4i_COUNTDOWN = { 3, 2, 1, 0 }; | ||||
| static Packet16uc p16uc_REVERSE = {12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3}; | ||||
| static Packet16uc p16uc_FORWARD = vec_lvsl(0, (float*)0); | ||||
| static Packet16uc p16uc_DUPLICATE = {0,1,2,3, 0,1,2,3, 4,5,6,7, 4,5,6,7}; | ||||
|  | ||||
| static _EIGEN_DECLARE_CONST_FAST_Packet4f(ZERO, 0); | ||||
| static _EIGEN_DECLARE_CONST_FAST_Packet4i(ZERO, 0); | ||||
| static _EIGEN_DECLARE_CONST_FAST_Packet4i(ONE,1); | ||||
| static _EIGEN_DECLARE_CONST_FAST_Packet4i(MINUS16,-16); | ||||
| static _EIGEN_DECLARE_CONST_FAST_Packet4i(MINUS1,-1); | ||||
| static Packet4f p4f_ONE = vec_ctf(p4i_ONE, 0); | ||||
| static Packet4f p4f_ZERO_ = (Packet4f) vec_sl((Packet4ui)p4i_MINUS1, (Packet4ui)p4i_MINUS1); | ||||
|  | ||||
| template<> struct packet_traits<float>  : default_packet_traits | ||||
| { | ||||
|   typedef Packet4f type; | ||||
|   enum { | ||||
|     Vectorizable = 1, | ||||
|     AlignedOnScalar = 1, | ||||
|     size=4, | ||||
|  | ||||
|     // FIXME check the Has* | ||||
|     HasSin  = 0, | ||||
|     HasCos  = 0, | ||||
|     HasLog  = 0, | ||||
|     HasExp  = 0, | ||||
|     HasSqrt = 0 | ||||
|   }; | ||||
| }; | ||||
| template<> struct packet_traits<int>    : default_packet_traits | ||||
| { | ||||
|   typedef Packet4i type; | ||||
|   enum { | ||||
|     // FIXME check the Has* | ||||
|     Vectorizable = 1, | ||||
|     AlignedOnScalar = 1, | ||||
|     size=4 | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| template<> struct unpacket_traits<Packet4f> { typedef float  type; enum {size=4}; }; | ||||
| template<> struct unpacket_traits<Packet4i> { typedef int    type; enum {size=4}; }; | ||||
| /* | ||||
| inline std::ostream & operator <<(std::ostream & s, const Packet4f & v) | ||||
| { | ||||
|   union { | ||||
|     Packet4f   v; | ||||
|     float n[4]; | ||||
|   } vt; | ||||
|   vt.v = v; | ||||
|   s << vt.n[0] << ", " << vt.n[1] << ", " << vt.n[2] << ", " << vt.n[3]; | ||||
|   return s; | ||||
| } | ||||
|  | ||||
| inline std::ostream & operator <<(std::ostream & s, const Packet4i & v) | ||||
| { | ||||
|   union { | ||||
|     Packet4i   v; | ||||
|     int n[4]; | ||||
|   } vt; | ||||
|   vt.v = v; | ||||
|   s << vt.n[0] << ", " << vt.n[1] << ", " << vt.n[2] << ", " << vt.n[3]; | ||||
|   return s; | ||||
| } | ||||
|  | ||||
| inline std::ostream & operator <<(std::ostream & s, const Packet4ui & v) | ||||
| { | ||||
|   union { | ||||
|     Packet4ui   v; | ||||
|     unsigned int n[4]; | ||||
|   } vt; | ||||
|   vt.v = v; | ||||
|   s << vt.n[0] << ", " << vt.n[1] << ", " << vt.n[2] << ", " << vt.n[3]; | ||||
|   return s; | ||||
| } | ||||
|  | ||||
| inline std::ostream & operator <<(std::ostream & s, const Packetbi & v) | ||||
| { | ||||
|   union { | ||||
|     Packet4bi v; | ||||
|     unsigned int n[4]; | ||||
|   } vt; | ||||
|   vt.v = v; | ||||
|   s << vt.n[0] << ", " << vt.n[1] << ", " << vt.n[2] << ", " << vt.n[3]; | ||||
|   return s; | ||||
| } | ||||
| */ | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pset1<Packet4f>(const float&  from) { | ||||
|   // Taken from http://developer.apple.com/hardwaredrivers/ve/alignment.html | ||||
|   float EIGEN_ALIGN16 af[4]; | ||||
|   af[0] = from; | ||||
|   Packet4f vc = vec_ld(0, af); | ||||
|   vc = vec_splat(vc, 0); | ||||
|   return vc; | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pset1<Packet4i>(const int&    from)   { | ||||
|   int EIGEN_ALIGN16 ai[4]; | ||||
|   ai[0] = from; | ||||
|   Packet4i vc = vec_ld(0, ai); | ||||
|   vc = vec_splat(vc, 0); | ||||
|   return vc; | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f plset<float>(const float& a) { return vec_add(pset1<Packet4f>(a), p4f_COUNTDOWN); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i plset<int>(const int& a)     { return vec_add(pset1<Packet4i>(a), p4i_COUNTDOWN); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f padd<Packet4f>(const Packet4f& a, const Packet4f& b) { return vec_add(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i padd<Packet4i>(const Packet4i& a, const Packet4i& b) { return vec_add(a,b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f psub<Packet4f>(const Packet4f& a, const Packet4f& b) { return vec_sub(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i psub<Packet4i>(const Packet4i& a, const Packet4i& b) { return vec_sub(a,b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pnegate(const Packet4f& a) { return psub<Packet4f>(p4f_ZERO, a); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pnegate(const Packet4i& a) { return psub<Packet4i>(p4i_ZERO, a); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pmul<Packet4f>(const Packet4f& a, const Packet4f& b) { return vec_madd(a,b,p4f_ZERO); } | ||||
| /* Commented out: it's actually slower than processing it scalar | ||||
|  * | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pmul<Packet4i>(const Packet4i& a, const Packet4i& b) | ||||
| { | ||||
|   // Detailed in: http://freevec.org/content/32bit_signed_integer_multiplication_altivec | ||||
|   //Set up constants, variables | ||||
|   Packet4i a1, b1, bswap, low_prod, high_prod, prod, prod_, v1sel; | ||||
|  | ||||
|   // Get the absolute values | ||||
|   a1  = vec_abs(a); | ||||
|   b1  = vec_abs(b); | ||||
|  | ||||
|   // Get the signs using xor | ||||
|   Packet4bi sgn = (Packet4bi) vec_cmplt(vec_xor(a, b), p4i_ZERO); | ||||
|  | ||||
|   // Do the multiplication for the asbolute values. | ||||
|   bswap = (Packet4i) vec_rl((Packet4ui) b1, (Packet4ui) p4i_MINUS16 ); | ||||
|   low_prod = vec_mulo((Packet8i) a1, (Packet8i)b1); | ||||
|   high_prod = vec_msum((Packet8i) a1, (Packet8i) bswap, p4i_ZERO); | ||||
|   high_prod = (Packet4i) vec_sl((Packet4ui) high_prod, (Packet4ui) p4i_MINUS16); | ||||
|   prod = vec_add( low_prod, high_prod ); | ||||
|  | ||||
|   // NOR the product and select only the negative elements according to the sign mask | ||||
|   prod_ = vec_nor(prod, prod); | ||||
|   prod_ = vec_sel(p4i_ZERO, prod_, sgn); | ||||
|  | ||||
|   // Add 1 to the result to get the negative numbers | ||||
|   v1sel = vec_sel(p4i_ZERO, p4i_ONE, sgn); | ||||
|   prod_ = vec_add(prod_, v1sel); | ||||
|  | ||||
|   // Merge the results back to the final vector. | ||||
|   prod = vec_sel(prod, prod_, sgn); | ||||
|  | ||||
|   return prod; | ||||
| } | ||||
| */ | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pdiv<Packet4f>(const Packet4f& a, const Packet4f& b) | ||||
| { | ||||
|   Packet4f t, y_0, y_1, res; | ||||
|  | ||||
|   // Altivec does not offer a divide instruction, we have to do a reciprocal approximation | ||||
|   y_0 = vec_re(b); | ||||
|  | ||||
|   // Do one Newton-Raphson iteration to get the needed accuracy | ||||
|   t   = vec_nmsub(y_0, b, p4f_ONE); | ||||
|   y_1 = vec_madd(y_0, t, y_0); | ||||
|  | ||||
|   res = vec_madd(a, y_1, p4f_ZERO); | ||||
|   return res; | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pdiv<Packet4i>(const Packet4i& /*a*/, const Packet4i& /*b*/) | ||||
| { eigen_assert(false && "packet integer division are not supported by AltiVec"); | ||||
|   return pset1<Packet4i>(0); | ||||
| } | ||||
|  | ||||
| // for some weird raisons, it has to be overloaded for packet of integers | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pmadd(const Packet4f& a, const Packet4f& b, const Packet4f& c) { return vec_madd(a, b, c); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pmadd(const Packet4i& a, const Packet4i& b, const Packet4i& c) { return padd(pmul(a,b), c); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pmin<Packet4f>(const Packet4f& a, const Packet4f& b) { return vec_min(a, b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pmin<Packet4i>(const Packet4i& a, const Packet4i& b) { return vec_min(a, b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pmax<Packet4f>(const Packet4f& a, const Packet4f& b) { return vec_max(a, b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pmax<Packet4i>(const Packet4i& a, const Packet4i& b) { return vec_max(a, b); } | ||||
|  | ||||
| // Logical Operations are not supported for float, so we have to reinterpret casts using NEON intrinsics | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pand<Packet4f>(const Packet4f& a, const Packet4f& b) { return vec_and(a, b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pand<Packet4i>(const Packet4i& a, const Packet4i& b) { return vec_and(a, b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f por<Packet4f>(const Packet4f& a, const Packet4f& b) { return vec_or(a, b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i por<Packet4i>(const Packet4i& a, const Packet4i& b) { return vec_or(a, b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pxor<Packet4f>(const Packet4f& a, const Packet4f& b) { return vec_xor(a, b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pxor<Packet4i>(const Packet4i& a, const Packet4i& b) { return vec_xor(a, b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pandnot<Packet4f>(const Packet4f& a, const Packet4f& b) { return vec_and(a, vec_nor(b, b)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pandnot<Packet4i>(const Packet4i& a, const Packet4i& b) { return vec_and(a, vec_nor(b, b)); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pload<Packet4f>(const float* from) { EIGEN_DEBUG_ALIGNED_LOAD return vec_ld(0, from); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pload<Packet4i>(const int*     from) { EIGEN_DEBUG_ALIGNED_LOAD return vec_ld(0, from); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f ploadu<Packet4f>(const float* from) | ||||
| { | ||||
|   EIGEN_DEBUG_ALIGNED_LOAD | ||||
|   // Taken from http://developer.apple.com/hardwaredrivers/ve/alignment.html | ||||
|   Packet16uc MSQ, LSQ; | ||||
|   Packet16uc mask; | ||||
|   MSQ = vec_ld(0, (unsigned char *)from);          // most significant quadword | ||||
|   LSQ = vec_ld(15, (unsigned char *)from);         // least significant quadword | ||||
|   mask = vec_lvsl(0, from);                        // create the permute mask | ||||
|   return (Packet4f) vec_perm(MSQ, LSQ, mask);           // align the data | ||||
|  | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i ploadu<Packet4i>(const int* from) | ||||
| { | ||||
|   EIGEN_DEBUG_ALIGNED_LOAD | ||||
|   // Taken from http://developer.apple.com/hardwaredrivers/ve/alignment.html | ||||
|   Packet16uc MSQ, LSQ; | ||||
|   Packet16uc mask; | ||||
|   MSQ = vec_ld(0, (unsigned char *)from);          // most significant quadword | ||||
|   LSQ = vec_ld(15, (unsigned char *)from);         // least significant quadword | ||||
|   mask = vec_lvsl(0, from);                        // create the permute mask | ||||
|   return (Packet4i) vec_perm(MSQ, LSQ, mask);    // align the data | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f ploaddup<Packet4f>(const float*   from) | ||||
| { | ||||
|   Packet4f p; | ||||
|   if((ptrdiff_t(&from) % 16) == 0)  p = pload<Packet4f>(from); | ||||
|   else                              p = ploadu<Packet4f>(from); | ||||
|   return vec_perm(p, p, p16uc_DUPLICATE); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i ploaddup<Packet4i>(const int*     from) | ||||
| { | ||||
|   Packet4i p; | ||||
|   if((ptrdiff_t(&from) % 16) == 0)  p = pload<Packet4i>(from); | ||||
|   else                              p = ploadu<Packet4i>(from); | ||||
|   return vec_perm(p, p, p16uc_DUPLICATE); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE void pstore<float>(float*   to, const Packet4f& from) { EIGEN_DEBUG_ALIGNED_STORE vec_st(from, 0, to); } | ||||
| template<> EIGEN_STRONG_INLINE void pstore<int>(int*       to, const Packet4i& from) { EIGEN_DEBUG_ALIGNED_STORE vec_st(from, 0, to); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE void pstoreu<float>(float*  to, const Packet4f& from) | ||||
| { | ||||
|   EIGEN_DEBUG_UNALIGNED_STORE | ||||
|   // Taken from http://developer.apple.com/hardwaredrivers/ve/alignment.html | ||||
|   // Warning: not thread safe! | ||||
|   Packet16uc MSQ, LSQ, edges; | ||||
|   Packet16uc edgeAlign, align; | ||||
|  | ||||
|   MSQ = vec_ld(0, (unsigned char *)to);                     // most significant quadword | ||||
|   LSQ = vec_ld(15, (unsigned char *)to);                    // least significant quadword | ||||
|   edgeAlign = vec_lvsl(0, to);                              // permute map to extract edges | ||||
|   edges=vec_perm(LSQ,MSQ,edgeAlign);                        // extract the edges | ||||
|   align = vec_lvsr( 0, to );                                // permute map to misalign data | ||||
|   MSQ = vec_perm(edges,(Packet16uc)from,align);             // misalign the data (MSQ) | ||||
|   LSQ = vec_perm((Packet16uc)from,edges,align);             // misalign the data (LSQ) | ||||
|   vec_st( LSQ, 15, (unsigned char *)to );                   // Store the LSQ part first | ||||
|   vec_st( MSQ, 0, (unsigned char *)to );                    // Store the MSQ part | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE void pstoreu<int>(int*      to, const Packet4i& from) | ||||
| { | ||||
|   EIGEN_DEBUG_UNALIGNED_STORE | ||||
|   // Taken from http://developer.apple.com/hardwaredrivers/ve/alignment.html | ||||
|   // Warning: not thread safe! | ||||
|   Packet16uc MSQ, LSQ, edges; | ||||
|   Packet16uc edgeAlign, align; | ||||
|  | ||||
|   MSQ = vec_ld(0, (unsigned char *)to);                     // most significant quadword | ||||
|   LSQ = vec_ld(15, (unsigned char *)to);                    // least significant quadword | ||||
|   edgeAlign = vec_lvsl(0, to);                              // permute map to extract edges | ||||
|   edges=vec_perm(LSQ, MSQ, edgeAlign);                      // extract the edges | ||||
|   align = vec_lvsr( 0, to );                                // permute map to misalign data | ||||
|   MSQ = vec_perm(edges, (Packet16uc) from, align);          // misalign the data (MSQ) | ||||
|   LSQ = vec_perm((Packet16uc) from, edges, align);          // misalign the data (LSQ) | ||||
|   vec_st( LSQ, 15, (unsigned char *)to );                   // Store the LSQ part first | ||||
|   vec_st( MSQ, 0, (unsigned char *)to );                    // Store the MSQ part | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE void prefetch<float>(const float* addr) { vec_dstt(addr, DST_CTRL(2,2,32), DST_CHAN); } | ||||
| template<> EIGEN_STRONG_INLINE void prefetch<int>(const int*     addr) { vec_dstt(addr, DST_CTRL(2,2,32), DST_CHAN); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE float  pfirst<Packet4f>(const Packet4f& a) { float EIGEN_ALIGN16 x[4]; vec_st(a, 0, x); return x[0]; } | ||||
| template<> EIGEN_STRONG_INLINE int    pfirst<Packet4i>(const Packet4i& a) { int   EIGEN_ALIGN16 x[4]; vec_st(a, 0, x); return x[0]; } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f preverse(const Packet4f& a) { return (Packet4f)vec_perm((Packet16uc)a,(Packet16uc)a, p16uc_REVERSE); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i preverse(const Packet4i& a) { return (Packet4i)vec_perm((Packet16uc)a,(Packet16uc)a, p16uc_REVERSE); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pabs(const Packet4f& a) { return vec_abs(a); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pabs(const Packet4i& a) { return vec_abs(a); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE float predux<Packet4f>(const Packet4f& a) | ||||
| { | ||||
|   Packet4f b, sum; | ||||
|   b   = (Packet4f) vec_sld(a, a, 8); | ||||
|   sum = vec_add(a, b); | ||||
|   b   = (Packet4f) vec_sld(sum, sum, 4); | ||||
|   sum = vec_add(sum, b); | ||||
|   return pfirst(sum); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f preduxp<Packet4f>(const Packet4f* vecs) | ||||
| { | ||||
|   Packet4f v[4], sum[4]; | ||||
|  | ||||
|   // It's easier and faster to transpose then add as columns | ||||
|   // Check: http://www.freevec.org/function/matrix_4x4_transpose_floats for explanation | ||||
|   // Do the transpose, first set of moves | ||||
|   v[0] = vec_mergeh(vecs[0], vecs[2]); | ||||
|   v[1] = vec_mergel(vecs[0], vecs[2]); | ||||
|   v[2] = vec_mergeh(vecs[1], vecs[3]); | ||||
|   v[3] = vec_mergel(vecs[1], vecs[3]); | ||||
|   // Get the resulting vectors | ||||
|   sum[0] = vec_mergeh(v[0], v[2]); | ||||
|   sum[1] = vec_mergel(v[0], v[2]); | ||||
|   sum[2] = vec_mergeh(v[1], v[3]); | ||||
|   sum[3] = vec_mergel(v[1], v[3]); | ||||
|  | ||||
|   // Now do the summation: | ||||
|   // Lines 0+1 | ||||
|   sum[0] = vec_add(sum[0], sum[1]); | ||||
|   // Lines 2+3 | ||||
|   sum[1] = vec_add(sum[2], sum[3]); | ||||
|   // Add the results | ||||
|   sum[0] = vec_add(sum[0], sum[1]); | ||||
|  | ||||
|   return sum[0]; | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE int predux<Packet4i>(const Packet4i& a) | ||||
| { | ||||
|   Packet4i sum; | ||||
|   sum = vec_sums(a, p4i_ZERO); | ||||
|   sum = vec_sld(sum, p4i_ZERO, 12); | ||||
|   return pfirst(sum); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4i preduxp<Packet4i>(const Packet4i* vecs) | ||||
| { | ||||
|   Packet4i v[4], sum[4]; | ||||
|  | ||||
|   // It's easier and faster to transpose then add as columns | ||||
|   // Check: http://www.freevec.org/function/matrix_4x4_transpose_floats for explanation | ||||
|   // Do the transpose, first set of moves | ||||
|   v[0] = vec_mergeh(vecs[0], vecs[2]); | ||||
|   v[1] = vec_mergel(vecs[0], vecs[2]); | ||||
|   v[2] = vec_mergeh(vecs[1], vecs[3]); | ||||
|   v[3] = vec_mergel(vecs[1], vecs[3]); | ||||
|   // Get the resulting vectors | ||||
|   sum[0] = vec_mergeh(v[0], v[2]); | ||||
|   sum[1] = vec_mergel(v[0], v[2]); | ||||
|   sum[2] = vec_mergeh(v[1], v[3]); | ||||
|   sum[3] = vec_mergel(v[1], v[3]); | ||||
|  | ||||
|   // Now do the summation: | ||||
|   // Lines 0+1 | ||||
|   sum[0] = vec_add(sum[0], sum[1]); | ||||
|   // Lines 2+3 | ||||
|   sum[1] = vec_add(sum[2], sum[3]); | ||||
|   // Add the results | ||||
|   sum[0] = vec_add(sum[0], sum[1]); | ||||
|  | ||||
|   return sum[0]; | ||||
| } | ||||
|  | ||||
| // Other reduction functions: | ||||
| // mul | ||||
| template<> EIGEN_STRONG_INLINE float predux_mul<Packet4f>(const Packet4f& a) | ||||
| { | ||||
|   Packet4f prod; | ||||
|   prod = pmul(a, (Packet4f)vec_sld(a, a, 8)); | ||||
|   return pfirst(pmul(prod, (Packet4f)vec_sld(prod, prod, 4))); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE int predux_mul<Packet4i>(const Packet4i& a) | ||||
| { | ||||
|   EIGEN_ALIGN16 int aux[4]; | ||||
|   pstore(aux, a); | ||||
|   return aux[0] * aux[1] * aux[2] * aux[3]; | ||||
| } | ||||
|  | ||||
| // min | ||||
| template<> EIGEN_STRONG_INLINE float predux_min<Packet4f>(const Packet4f& a) | ||||
| { | ||||
|   Packet4f b, res; | ||||
|   b = vec_min(a, vec_sld(a, a, 8)); | ||||
|   res = vec_min(b, vec_sld(b, b, 4)); | ||||
|   return pfirst(res); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE int predux_min<Packet4i>(const Packet4i& a) | ||||
| { | ||||
|   Packet4i b, res; | ||||
|   b = vec_min(a, vec_sld(a, a, 8)); | ||||
|   res = vec_min(b, vec_sld(b, b, 4)); | ||||
|   return pfirst(res); | ||||
| } | ||||
|  | ||||
| // max | ||||
| template<> EIGEN_STRONG_INLINE float predux_max<Packet4f>(const Packet4f& a) | ||||
| { | ||||
|   Packet4f b, res; | ||||
|   b = vec_max(a, vec_sld(a, a, 8)); | ||||
|   res = vec_max(b, vec_sld(b, b, 4)); | ||||
|   return pfirst(res); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE int predux_max<Packet4i>(const Packet4i& a) | ||||
| { | ||||
|   Packet4i b, res; | ||||
|   b = vec_max(a, vec_sld(a, a, 8)); | ||||
|   res = vec_max(b, vec_sld(b, b, 4)); | ||||
|   return pfirst(res); | ||||
| } | ||||
|  | ||||
| template<int Offset> | ||||
| struct palign_impl<Offset,Packet4f> | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Packet4f& first, const Packet4f& second) | ||||
|   { | ||||
|     if (Offset!=0) | ||||
|       first = vec_sld(first, second, Offset*4); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<int Offset> | ||||
| struct palign_impl<Offset,Packet4i> | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Packet4i& first, const Packet4i& second) | ||||
|   { | ||||
|     if (Offset!=0) | ||||
|       first = vec_sld(first, second, Offset*4); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_PACKET_MATH_ALTIVEC_H | ||||
							
								
								
									
										49
									
								
								latan/Eigen/src/Core/arch/Default/Settings.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								latan/Eigen/src/Core/arch/Default/Settings.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
|  | ||||
| /* All the parameters defined in this file can be specialized in the | ||||
|  * architecture specific files, and/or by the user. | ||||
|  * More to come... */ | ||||
|  | ||||
| #ifndef EIGEN_DEFAULT_SETTINGS_H | ||||
| #define EIGEN_DEFAULT_SETTINGS_H | ||||
|  | ||||
| /** 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 | ||||
|  | ||||
| /** Defines the threshold between a "small" and a "large" matrix. | ||||
|   * This threshold is mainly used to select the proper product implementation. | ||||
|   */ | ||||
| #ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD | ||||
| #define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 8 | ||||
| #endif | ||||
|  | ||||
| /** Defines the maximal width of the blocks used in the triangular product and solver | ||||
|   * for vectors (level 2 blas xTRMV and xTRSV). The default is 8. | ||||
|   */ | ||||
| #ifndef EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH | ||||
| #define EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH 8 | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /** Defines the default number of registers available for that architecture. | ||||
|   * Currently it must be 8 or 16. Other values will fail. | ||||
|   */ | ||||
| #ifndef EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS | ||||
| #define EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS 8 | ||||
| #endif | ||||
|  | ||||
| #endif // EIGEN_DEFAULT_SETTINGS_H | ||||
							
								
								
									
										259
									
								
								latan/Eigen/src/Core/arch/NEON/Complex.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										259
									
								
								latan/Eigen/src/Core/arch/NEON/Complex.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,259 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_COMPLEX_NEON_H | ||||
| #define EIGEN_COMPLEX_NEON_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| 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 | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet2cf() {} | ||||
|   EIGEN_STRONG_INLINE explicit Packet2cf(const Packet4f& a) : v(a) {} | ||||
|   Packet4f  v; | ||||
| }; | ||||
|  | ||||
| template<> struct packet_traits<std::complex<float> >  : default_packet_traits | ||||
| { | ||||
|   typedef Packet2cf type; | ||||
|   enum { | ||||
|     Vectorizable = 1, | ||||
|     AlignedOnScalar = 1, | ||||
|     size = 2, | ||||
|  | ||||
|     HasAdd    = 1, | ||||
|     HasSub    = 1, | ||||
|     HasMul    = 1, | ||||
|     HasDiv    = 1, | ||||
|     HasNegate = 1, | ||||
|     HasAbs    = 0, | ||||
|     HasAbs2   = 0, | ||||
|     HasMin    = 0, | ||||
|     HasMax    = 0, | ||||
|     HasSetLinear = 0 | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| template<> struct unpacket_traits<Packet2cf> { typedef std::complex<float> type; enum {size=2}; }; | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<float>&  from) | ||||
| { | ||||
|   float32x2_t r64; | ||||
|   r64 = vld1_f32((float *)&from); | ||||
|  | ||||
|   return Packet2cf(vcombine_f32(r64, r64)); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf padd<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(padd<Packet4f>(a.v,b.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf psub<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(psub<Packet4f>(a.v,b.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pnegate(const Packet2cf& a) { return Packet2cf(pnegate<Packet4f>(a.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pconj(const Packet2cf& a) | ||||
| { | ||||
|   Packet4ui b = vreinterpretq_u32_f32(a.v); | ||||
|   return Packet2cf(vreinterpretq_f32_u32(veorq_u32(b, p4ui_CONJ_XOR))); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pmul<Packet2cf>(const Packet2cf& a, const Packet2cf& b) | ||||
| { | ||||
|   Packet4f v1, v2; | ||||
|   float32x2_t a_lo, a_hi; | ||||
|  | ||||
|   // Get the real values of a | a1_re | a1_re | a2_re | a2_re | | ||||
|   v1 = vcombine_f32(vdup_lane_f32(vget_low_f32(a.v), 0), vdup_lane_f32(vget_high_f32(a.v), 0)); | ||||
|   // Get the real values of a | a1_im | a1_im | a2_im | a2_im | | ||||
|   v2 = vcombine_f32(vdup_lane_f32(vget_low_f32(a.v), 1), vdup_lane_f32(vget_high_f32(a.v), 1)); | ||||
|   // Multiply the real a with b | ||||
|   v1 = vmulq_f32(v1, b.v); | ||||
|   // Multiply the imag a with b | ||||
|   v2 = vmulq_f32(v2, b.v); | ||||
|   // Conjugate v2  | ||||
|   v2 = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(v2), p4ui_CONJ_XOR)); | ||||
|   // Swap real/imag elements in v2. | ||||
|   a_lo = vrev64_f32(vget_low_f32(v2)); | ||||
|   a_hi = vrev64_f32(vget_high_f32(v2)); | ||||
|   v2 = vcombine_f32(a_lo, a_hi); | ||||
|   // Add and return the result | ||||
|   return Packet2cf(vaddq_f32(v1, v2)); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pand   <Packet2cf>(const Packet2cf& a, const Packet2cf& b) | ||||
| { | ||||
|   return Packet2cf(vreinterpretq_f32_u32(vorrq_u32(vreinterpretq_u32_f32(a.v),vreinterpretq_u32_f32(b.v)))); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf por    <Packet2cf>(const Packet2cf& a, const Packet2cf& b) | ||||
| { | ||||
|   return Packet2cf(vreinterpretq_f32_u32(vorrq_u32(vreinterpretq_u32_f32(a.v),vreinterpretq_u32_f32(b.v)))); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pxor   <Packet2cf>(const Packet2cf& a, const Packet2cf& b) | ||||
| { | ||||
|   return Packet2cf(vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(a.v),vreinterpretq_u32_f32(b.v)))); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pandnot<Packet2cf>(const Packet2cf& a, const Packet2cf& b) | ||||
| { | ||||
|   return Packet2cf(vreinterpretq_f32_u32(vbicq_u32(vreinterpretq_u32_f32(a.v),vreinterpretq_u32_f32(b.v)))); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pload<Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload<Packet4f>((const float*)from)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf ploadu<Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu<Packet4f>((const float*)from)); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf ploaddup<Packet2cf>(const std::complex<float>* from) { return pset1<Packet2cf>(*from); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE void pstore <std::complex<float> >(std::complex<float> *   to, const Packet2cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((float*)to, from.v); } | ||||
| template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float> *   to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((float*)to, from.v); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE void prefetch<std::complex<float> >(const std::complex<float> *   addr) { __pld((float *)addr); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE std::complex<float>  pfirst<Packet2cf>(const Packet2cf& a) | ||||
| { | ||||
|   std::complex<float> EIGEN_ALIGN16 x[2]; | ||||
|   vst1q_f32((float *)x, a.v); | ||||
|   return x[0]; | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf preverse(const Packet2cf& a) | ||||
| { | ||||
|   float32x2_t a_lo, a_hi; | ||||
|   Packet4f a_r128; | ||||
|  | ||||
|   a_lo = vget_low_f32(a.v); | ||||
|   a_hi = vget_high_f32(a.v); | ||||
|   a_r128 = vcombine_f32(a_hi, a_lo); | ||||
|  | ||||
|   return Packet2cf(a_r128); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pcplxflip<Packet2cf>(const Packet2cf& a) | ||||
| { | ||||
|   return Packet2cf(vrev64q_f32(a.v)); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE std::complex<float> predux<Packet2cf>(const Packet2cf& a) | ||||
| { | ||||
|   float32x2_t a1, a2; | ||||
|   std::complex<float> s; | ||||
|  | ||||
|   a1 = vget_low_f32(a.v); | ||||
|   a2 = vget_high_f32(a.v); | ||||
|   a2 = vadd_f32(a1, a2); | ||||
|   vst1_f32((float *)&s, a2); | ||||
|  | ||||
|   return s; | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf preduxp<Packet2cf>(const Packet2cf* vecs) | ||||
| { | ||||
|   Packet4f sum1, sum2, sum; | ||||
|  | ||||
|   // Add the first two 64-bit float32x2_t of vecs[0] | ||||
|   sum1 = vcombine_f32(vget_low_f32(vecs[0].v), vget_low_f32(vecs[1].v)); | ||||
|   sum2 = vcombine_f32(vget_high_f32(vecs[0].v), vget_high_f32(vecs[1].v)); | ||||
|   sum = vaddq_f32(sum1, sum2); | ||||
|  | ||||
|   return Packet2cf(sum); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE std::complex<float> predux_mul<Packet2cf>(const Packet2cf& a) | ||||
| { | ||||
|   float32x2_t a1, a2, v1, v2, prod; | ||||
|   std::complex<float> s; | ||||
|  | ||||
|   a1 = vget_low_f32(a.v); | ||||
|   a2 = vget_high_f32(a.v); | ||||
|    // Get the real values of a | a1_re | a1_re | a2_re | a2_re | | ||||
|   v1 = vdup_lane_f32(a1, 0); | ||||
|   // Get the real values of a | a1_im | a1_im | a2_im | a2_im | | ||||
|   v2 = vdup_lane_f32(a1, 1); | ||||
|   // Multiply the real a with b | ||||
|   v1 = vmul_f32(v1, a2); | ||||
|   // Multiply the imag a with b | ||||
|   v2 = vmul_f32(v2, a2); | ||||
|   // Conjugate v2  | ||||
|   v2 = vreinterpret_f32_u32(veor_u32(vreinterpret_u32_f32(v2), p2ui_CONJ_XOR)); | ||||
|   // Swap real/imag elements in v2. | ||||
|   v2 = vrev64_f32(v2); | ||||
|   // Add v1, v2 | ||||
|   prod = vadd_f32(v1, v2); | ||||
|  | ||||
|   vst1_f32((float *)&s, prod); | ||||
|  | ||||
|   return s; | ||||
| } | ||||
|  | ||||
| template<int Offset> | ||||
| struct palign_impl<Offset,Packet2cf> | ||||
| { | ||||
|   EIGEN_STRONG_INLINE static void run(Packet2cf& first, const Packet2cf& second) | ||||
|   { | ||||
|     if (Offset==1) | ||||
|     { | ||||
|       first.v = vextq_f32(first.v, second.v, 2); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct conj_helper<Packet2cf, Packet2cf, false,true> | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const | ||||
|   { return padd(pmul(x,y),c); } | ||||
|  | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const | ||||
|   { | ||||
|     return internal::pmul(a, pconj(b)); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct conj_helper<Packet2cf, Packet2cf, true,false> | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const | ||||
|   { return padd(pmul(x,y),c); } | ||||
|  | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const | ||||
|   { | ||||
|     return internal::pmul(pconj(a), b); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct conj_helper<Packet2cf, Packet2cf, true,true> | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const | ||||
|   { return padd(pmul(x,y),c); } | ||||
|  | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const | ||||
|   { | ||||
|     return pconj(internal::pmul(a, b)); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, const Packet2cf& b) | ||||
| { | ||||
|   // TODO optimize it for AltiVec | ||||
|   Packet2cf res = conj_helper<Packet2cf,Packet2cf,false,true>().pmul(a,b); | ||||
|   Packet4f s, rev_s; | ||||
|   float32x2_t a_lo, a_hi; | ||||
|  | ||||
|   // this computes the norm | ||||
|   s = vmulq_f32(b.v, b.v); | ||||
|   a_lo = vrev64_f32(vget_low_f32(s)); | ||||
|   a_hi = vrev64_f32(vget_high_f32(s)); | ||||
|   rev_s = vcombine_f32(a_lo, a_hi); | ||||
|  | ||||
|   return Packet2cf(pdiv(res.v, vaddq_f32(s,rev_s))); | ||||
| } | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_COMPLEX_NEON_H | ||||
							
								
								
									
										424
									
								
								latan/Eigen/src/Core/arch/NEON/PacketMath.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										424
									
								
								latan/Eigen/src/Core/arch/NEON/PacketMath.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,424 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // Copyright (C) 2010 Konstantinos Margaritis <markos@codex.gr> | ||||
| // Heavily based on Gael's SSE version. | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_PACKET_MATH_NEON_H | ||||
| #define EIGEN_PACKET_MATH_NEON_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| #ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD | ||||
| #define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 8 | ||||
| #endif | ||||
|  | ||||
| // FIXME NEON has 16 quad registers, but since the current register allocator | ||||
| // is so bad, it is much better to reduce it to 8 | ||||
| #ifndef EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS | ||||
| #define EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS 8 | ||||
| #endif | ||||
|  | ||||
| typedef float32x4_t Packet4f; | ||||
| typedef int32x4_t   Packet4i; | ||||
| typedef uint32x4_t  Packet4ui; | ||||
|  | ||||
| #define _EIGEN_DECLARE_CONST_Packet4f(NAME,X) \ | ||||
|   const Packet4f p4f_##NAME = pset1<Packet4f>(X) | ||||
|  | ||||
| #define _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(NAME,X) \ | ||||
|   const Packet4f p4f_##NAME = vreinterpretq_f32_u32(pset1<int>(X)) | ||||
|  | ||||
| #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 | ||||
|  | ||||
| template<> struct packet_traits<float>  : default_packet_traits | ||||
| { | ||||
|   typedef Packet4f type; | ||||
|   enum { | ||||
|     Vectorizable = 1, | ||||
|     AlignedOnScalar = 1, | ||||
|     size = 4, | ||||
|     | ||||
|     HasDiv  = 1, | ||||
|     // FIXME check the Has* | ||||
|     HasSin  = 0, | ||||
|     HasCos  = 0, | ||||
|     HasLog  = 0, | ||||
|     HasExp  = 0, | ||||
|     HasSqrt = 0 | ||||
|   }; | ||||
| }; | ||||
| template<> struct packet_traits<int>    : default_packet_traits | ||||
| { | ||||
|   typedef Packet4i type; | ||||
|   enum { | ||||
|     Vectorizable = 1, | ||||
|     AlignedOnScalar = 1, | ||||
|     size=4 | ||||
|     // FIXME check the Has* | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| #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); } | ||||
| EIGEN_STRONG_INLINE void        vst1q_f32(float* to, float32x4_t from) { ::vst1q_f32((float32_t*)to,from); } | ||||
| EIGEN_STRONG_INLINE void        vst1_f32 (float* to, float32x2_t from) { ::vst1_f32 ((float32_t*)to,from); } | ||||
| #endif | ||||
|  | ||||
| template<> struct unpacket_traits<Packet4f> { typedef float  type; enum {size=4}; }; | ||||
| template<> struct unpacket_traits<Packet4i> { typedef int    type; enum {size=4}; }; | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pset1<Packet4f>(const float&  from) { return vdupq_n_f32(from); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pset1<Packet4i>(const int&    from)   { return vdupq_n_s32(from); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f plset<float>(const float& a) | ||||
| { | ||||
|   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 = EIGEN_INIT_NEON_PACKET4(0, 1, 2, 3); | ||||
|   return vaddq_s32(pset1<Packet4i>(a), countdown); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f padd<Packet4f>(const Packet4f& a, const Packet4f& b) { return vaddq_f32(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i padd<Packet4i>(const Packet4i& a, const Packet4i& b) { return vaddq_s32(a,b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f psub<Packet4f>(const Packet4f& a, const Packet4f& b) { return vsubq_f32(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i psub<Packet4i>(const Packet4i& a, const Packet4i& b) { return vsubq_s32(a,b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pnegate(const Packet4f& a) { return vnegq_f32(a); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pnegate(const Packet4i& a) { return vnegq_s32(a); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pmul<Packet4f>(const Packet4f& a, const Packet4f& b) { return vmulq_f32(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pmul<Packet4i>(const Packet4i& a, const Packet4i& b) { return vmulq_s32(a,b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pdiv<Packet4f>(const Packet4f& a, const Packet4f& b) | ||||
| { | ||||
|   Packet4f inv, restep, div; | ||||
|  | ||||
|   // NEON does not offer a divide instruction, we have to do a reciprocal approximation | ||||
|   // However NEON in contrast to other SIMD engines (AltiVec/SSE), offers | ||||
|   // a reciprocal estimate AND a reciprocal step -which saves a few instructions | ||||
|   // vrecpeq_f32() returns an estimate to 1/b, which we will finetune with | ||||
|   // Newton-Raphson and vrecpsq_f32() | ||||
|   inv = vrecpeq_f32(b); | ||||
|  | ||||
|   // This returns a differential, by which we will have to multiply inv to get a better | ||||
|   // approximation of 1/b. | ||||
|   restep = vrecpsq_f32(b, inv); | ||||
|   inv = vmulq_f32(restep, inv); | ||||
|  | ||||
|   // Finally, multiply a by 1/b and get the wanted result of the division. | ||||
|   div = vmulq_f32(a, inv); | ||||
|  | ||||
|   return div; | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pdiv<Packet4i>(const Packet4i& /*a*/, const Packet4i& /*b*/) | ||||
| { eigen_assert(false && "packet integer division are not supported by NEON"); | ||||
|   return pset1<Packet4i>(0); | ||||
| } | ||||
|  | ||||
| // for some weird raisons, it has to be overloaded for packet of integers | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pmadd(const Packet4f& a, const Packet4f& b, const Packet4f& c) { return vmlaq_f32(c,a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pmadd(const Packet4i& a, const Packet4i& b, const Packet4i& c) { return vmlaq_s32(c,a,b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pmin<Packet4f>(const Packet4f& a, const Packet4f& b) { return vminq_f32(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pmin<Packet4i>(const Packet4i& a, const Packet4i& b) { return vminq_s32(a,b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pmax<Packet4f>(const Packet4f& a, const Packet4f& b) { return vmaxq_f32(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pmax<Packet4i>(const Packet4i& a, const Packet4i& b) { return vmaxq_s32(a,b); } | ||||
|  | ||||
| // Logical Operations are not supported for float, so we have to reinterpret casts using NEON intrinsics | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pand<Packet4f>(const Packet4f& a, const Packet4f& b) | ||||
| { | ||||
|   return vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(a),vreinterpretq_u32_f32(b))); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pand<Packet4i>(const Packet4i& a, const Packet4i& b) { return vandq_s32(a,b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f por<Packet4f>(const Packet4f& a, const Packet4f& b) | ||||
| { | ||||
|   return vreinterpretq_f32_u32(vorrq_u32(vreinterpretq_u32_f32(a),vreinterpretq_u32_f32(b))); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i por<Packet4i>(const Packet4i& a, const Packet4i& b) { return vorrq_s32(a,b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pxor<Packet4f>(const Packet4f& a, const Packet4f& b) | ||||
| { | ||||
|   return vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(a),vreinterpretq_u32_f32(b))); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pxor<Packet4i>(const Packet4i& a, const Packet4i& b) { return veorq_s32(a,b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pandnot<Packet4f>(const Packet4f& a, const Packet4f& b) | ||||
| { | ||||
|   return vreinterpretq_f32_u32(vbicq_u32(vreinterpretq_u32_f32(a),vreinterpretq_u32_f32(b))); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pandnot<Packet4i>(const Packet4i& a, const Packet4i& b) { return vbicq_s32(a,b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pload<Packet4f>(const float* from) { EIGEN_DEBUG_ALIGNED_LOAD return vld1q_f32(from); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pload<Packet4i>(const int*   from) { EIGEN_DEBUG_ALIGNED_LOAD return vld1q_s32(from); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f ploadu<Packet4f>(const float* from) { EIGEN_DEBUG_UNALIGNED_LOAD return vld1q_f32(from); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i ploadu<Packet4i>(const int* from)   { EIGEN_DEBUG_UNALIGNED_LOAD return vld1q_s32(from); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f ploaddup<Packet4f>(const float*   from) | ||||
| { | ||||
|   float32x2_t lo, hi; | ||||
|   lo = vdup_n_f32(*from); | ||||
|   hi = vdup_n_f32(*(from+1)); | ||||
|   return vcombine_f32(lo, hi); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i ploaddup<Packet4i>(const int*     from) | ||||
| { | ||||
|   int32x2_t lo, hi; | ||||
|   lo = vdup_n_s32(*from); | ||||
|   hi = vdup_n_s32(*(from+1)); | ||||
|   return vcombine_s32(lo, hi); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE void pstore<float>(float*   to, const Packet4f& from) { EIGEN_DEBUG_ALIGNED_STORE vst1q_f32(to, from); } | ||||
| template<> EIGEN_STRONG_INLINE void pstore<int>(int*       to, const Packet4i& from) { EIGEN_DEBUG_ALIGNED_STORE vst1q_s32(to, from); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE void pstoreu<float>(float*  to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_f32(to, from); } | ||||
| template<> EIGEN_STRONG_INLINE void pstoreu<int>(int*      to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_s32(to, from); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE void prefetch<float>(const float* addr) { __pld(addr); } | ||||
| template<> EIGEN_STRONG_INLINE void prefetch<int>(const int*     addr) { __pld(addr); } | ||||
|  | ||||
| // FIXME only store the 2 first elements ? | ||||
| template<> EIGEN_STRONG_INLINE float  pfirst<Packet4f>(const Packet4f& a) { float EIGEN_ALIGN16 x[4]; vst1q_f32(x, a); return x[0]; } | ||||
| template<> EIGEN_STRONG_INLINE int    pfirst<Packet4i>(const Packet4i& a) { int   EIGEN_ALIGN16 x[4]; vst1q_s32(x, a); return x[0]; } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f preverse(const Packet4f& a) { | ||||
|   float32x2_t a_lo, a_hi; | ||||
|   Packet4f a_r64; | ||||
|  | ||||
|   a_r64 = vrev64q_f32(a); | ||||
|   a_lo = vget_low_f32(a_r64); | ||||
|   a_hi = vget_high_f32(a_r64); | ||||
|   return vcombine_f32(a_hi, a_lo); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i preverse(const Packet4i& a) { | ||||
|   int32x2_t a_lo, a_hi; | ||||
|   Packet4i a_r64; | ||||
|  | ||||
|   a_r64 = vrev64q_s32(a); | ||||
|   a_lo = vget_low_s32(a_r64); | ||||
|   a_hi = vget_high_s32(a_r64); | ||||
|   return vcombine_s32(a_hi, a_lo); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pabs(const Packet4f& a) { return vabsq_f32(a); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pabs(const Packet4i& a) { return vabsq_s32(a); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE float predux<Packet4f>(const Packet4f& a) | ||||
| { | ||||
|   float32x2_t a_lo, a_hi, sum; | ||||
|   float s[2]; | ||||
|  | ||||
|   a_lo = vget_low_f32(a); | ||||
|   a_hi = vget_high_f32(a); | ||||
|   sum = vpadd_f32(a_lo, a_hi); | ||||
|   sum = vpadd_f32(sum, sum); | ||||
|   vst1_f32(s, sum); | ||||
|  | ||||
|   return s[0]; | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f preduxp<Packet4f>(const Packet4f* vecs) | ||||
| { | ||||
|   float32x4x2_t vtrn1, vtrn2, res1, res2; | ||||
|   Packet4f sum1, sum2, sum; | ||||
|  | ||||
|   // NEON zip performs interleaving of the supplied vectors. | ||||
|   // We perform two interleaves in a row to acquire the transposed vector | ||||
|   vtrn1 = vzipq_f32(vecs[0], vecs[2]); | ||||
|   vtrn2 = vzipq_f32(vecs[1], vecs[3]); | ||||
|   res1 = vzipq_f32(vtrn1.val[0], vtrn2.val[0]); | ||||
|   res2 = vzipq_f32(vtrn1.val[1], vtrn2.val[1]); | ||||
|  | ||||
|   // Do the addition of the resulting vectors | ||||
|   sum1 = vaddq_f32(res1.val[0], res1.val[1]); | ||||
|   sum2 = vaddq_f32(res2.val[0], res2.val[1]); | ||||
|   sum = vaddq_f32(sum1, sum2); | ||||
|  | ||||
|   return sum; | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE int predux<Packet4i>(const Packet4i& a) | ||||
| { | ||||
|   int32x2_t a_lo, a_hi, sum; | ||||
|   int32_t s[2]; | ||||
|  | ||||
|   a_lo = vget_low_s32(a); | ||||
|   a_hi = vget_high_s32(a); | ||||
|   sum = vpadd_s32(a_lo, a_hi); | ||||
|   sum = vpadd_s32(sum, sum); | ||||
|   vst1_s32(s, sum); | ||||
|  | ||||
|   return s[0]; | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4i preduxp<Packet4i>(const Packet4i* vecs) | ||||
| { | ||||
|   int32x4x2_t vtrn1, vtrn2, res1, res2; | ||||
|   Packet4i sum1, sum2, sum; | ||||
|  | ||||
|   // NEON zip performs interleaving of the supplied vectors. | ||||
|   // We perform two interleaves in a row to acquire the transposed vector | ||||
|   vtrn1 = vzipq_s32(vecs[0], vecs[2]); | ||||
|   vtrn2 = vzipq_s32(vecs[1], vecs[3]); | ||||
|   res1 = vzipq_s32(vtrn1.val[0], vtrn2.val[0]); | ||||
|   res2 = vzipq_s32(vtrn1.val[1], vtrn2.val[1]); | ||||
|  | ||||
|   // Do the addition of the resulting vectors | ||||
|   sum1 = vaddq_s32(res1.val[0], res1.val[1]); | ||||
|   sum2 = vaddq_s32(res2.val[0], res2.val[1]); | ||||
|   sum = vaddq_s32(sum1, sum2); | ||||
|  | ||||
|   return sum; | ||||
| } | ||||
|  | ||||
| // Other reduction functions: | ||||
| // mul | ||||
| template<> EIGEN_STRONG_INLINE float predux_mul<Packet4f>(const Packet4f& a) | ||||
| { | ||||
|   float32x2_t a_lo, a_hi, prod; | ||||
|   float s[2]; | ||||
|  | ||||
|   // Get a_lo = |a1|a2| and a_hi = |a3|a4| | ||||
|   a_lo = vget_low_f32(a); | ||||
|   a_hi = vget_high_f32(a); | ||||
|   // Get the product of a_lo * a_hi -> |a1*a3|a2*a4| | ||||
|   prod = vmul_f32(a_lo, a_hi); | ||||
|   // Multiply prod with its swapped value |a2*a4|a1*a3| | ||||
|   prod = vmul_f32(prod, vrev64_f32(prod)); | ||||
|   vst1_f32(s, prod); | ||||
|  | ||||
|   return s[0]; | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE int predux_mul<Packet4i>(const Packet4i& a) | ||||
| { | ||||
|   int32x2_t a_lo, a_hi, prod; | ||||
|   int32_t s[2]; | ||||
|  | ||||
|   // Get a_lo = |a1|a2| and a_hi = |a3|a4| | ||||
|   a_lo = vget_low_s32(a); | ||||
|   a_hi = vget_high_s32(a); | ||||
|   // Get the product of a_lo * a_hi -> |a1*a3|a2*a4| | ||||
|   prod = vmul_s32(a_lo, a_hi); | ||||
|   // Multiply prod with its swapped value |a2*a4|a1*a3| | ||||
|   prod = vmul_s32(prod, vrev64_s32(prod)); | ||||
|   vst1_s32(s, prod); | ||||
|  | ||||
|   return s[0]; | ||||
| } | ||||
|  | ||||
| // min | ||||
| template<> EIGEN_STRONG_INLINE float predux_min<Packet4f>(const Packet4f& a) | ||||
| { | ||||
|   float32x2_t a_lo, a_hi, min; | ||||
|   float s[2]; | ||||
|  | ||||
|   a_lo = vget_low_f32(a); | ||||
|   a_hi = vget_high_f32(a); | ||||
|   min = vpmin_f32(a_lo, a_hi); | ||||
|   min = vpmin_f32(min, min); | ||||
|   vst1_f32(s, min); | ||||
|  | ||||
|   return s[0]; | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE int predux_min<Packet4i>(const Packet4i& a) | ||||
| { | ||||
|   int32x2_t a_lo, a_hi, min; | ||||
|   int32_t s[2]; | ||||
|  | ||||
|   a_lo = vget_low_s32(a); | ||||
|   a_hi = vget_high_s32(a); | ||||
|   min = vpmin_s32(a_lo, a_hi); | ||||
|   min = vpmin_s32(min, min); | ||||
|   vst1_s32(s, min); | ||||
|  | ||||
|   return s[0]; | ||||
| } | ||||
|  | ||||
| // max | ||||
| template<> EIGEN_STRONG_INLINE float predux_max<Packet4f>(const Packet4f& a) | ||||
| { | ||||
|   float32x2_t a_lo, a_hi, max; | ||||
|   float s[2]; | ||||
|  | ||||
|   a_lo = vget_low_f32(a); | ||||
|   a_hi = vget_high_f32(a); | ||||
|   max = vpmax_f32(a_lo, a_hi); | ||||
|   max = vpmax_f32(max, max); | ||||
|   vst1_f32(s, max); | ||||
|  | ||||
|   return s[0]; | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE int predux_max<Packet4i>(const Packet4i& a) | ||||
| { | ||||
|   int32x2_t a_lo, a_hi, max; | ||||
|   int32_t s[2]; | ||||
|  | ||||
|   a_lo = vget_low_s32(a); | ||||
|   a_hi = vget_high_s32(a); | ||||
|   max = vpmax_s32(a_lo, a_hi); | ||||
|   max = vpmax_s32(max, max); | ||||
|   vst1_s32(s, max); | ||||
|  | ||||
|   return s[0]; | ||||
| } | ||||
|  | ||||
| // 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);\ | ||||
|     }\ | ||||
| };\ | ||||
|  | ||||
| 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 | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_PACKET_MATH_NEON_H | ||||
							
								
								
									
										436
									
								
								latan/Eigen/src/Core/arch/SSE/Complex.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										436
									
								
								latan/Eigen/src/Core/arch/SSE/Complex.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,436 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_COMPLEX_SSE_H | ||||
| #define EIGEN_COMPLEX_SSE_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| //---------- float ---------- | ||||
| struct Packet2cf | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet2cf() {} | ||||
|   EIGEN_STRONG_INLINE explicit Packet2cf(const __m128& a) : v(a) {} | ||||
|   __m128  v; | ||||
| }; | ||||
|  | ||||
| template<> struct packet_traits<std::complex<float> >  : default_packet_traits | ||||
| { | ||||
|   typedef Packet2cf type; | ||||
|   enum { | ||||
|     Vectorizable = 1, | ||||
|     AlignedOnScalar = 1, | ||||
|     size = 2, | ||||
|  | ||||
|     HasAdd    = 1, | ||||
|     HasSub    = 1, | ||||
|     HasMul    = 1, | ||||
|     HasDiv    = 1, | ||||
|     HasNegate = 1, | ||||
|     HasAbs    = 0, | ||||
|     HasAbs2   = 0, | ||||
|     HasMin    = 0, | ||||
|     HasMax    = 0, | ||||
|     HasSetLinear = 0 | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| template<> struct unpacket_traits<Packet2cf> { typedef std::complex<float> type; enum {size=2}; }; | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf padd<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_add_ps(a.v,b.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf psub<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_sub_ps(a.v,b.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pnegate(const Packet2cf& a) | ||||
| { | ||||
|   const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0x80000000,0x80000000,0x80000000,0x80000000)); | ||||
|   return Packet2cf(_mm_xor_ps(a.v,mask)); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pconj(const Packet2cf& a) | ||||
| { | ||||
|   const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0x00000000,0x80000000,0x00000000,0x80000000)); | ||||
|   return Packet2cf(_mm_xor_ps(a.v,mask)); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pmul<Packet2cf>(const Packet2cf& a, const Packet2cf& b) | ||||
| { | ||||
|   // TODO optimize it for SSE3 and 4 | ||||
|   #ifdef EIGEN_VECTORIZE_SSE3 | ||||
|   return Packet2cf(_mm_addsub_ps(_mm_mul_ps(_mm_moveldup_ps(a.v), b.v), | ||||
|                                  _mm_mul_ps(_mm_movehdup_ps(a.v), | ||||
|                                             vec4f_swizzle1(b.v, 1, 0, 3, 2)))); | ||||
| //   return Packet2cf(_mm_addsub_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 0, 0, 2, 2), b.v), | ||||
| //                                  _mm_mul_ps(vec4f_swizzle1(a.v, 1, 1, 3, 3), | ||||
| //                                             vec4f_swizzle1(b.v, 1, 0, 3, 2)))); | ||||
|   #else | ||||
|   const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0x80000000,0x00000000,0x80000000,0x00000000)); | ||||
|   return Packet2cf(_mm_add_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 0, 0, 2, 2), b.v), | ||||
|                               _mm_xor_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 1, 1, 3, 3), | ||||
|                                                     vec4f_swizzle1(b.v, 1, 0, 3, 2)), mask))); | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pand   <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_and_ps(a.v,b.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf por    <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_or_ps(a.v,b.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pxor   <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_xor_ps(a.v,b.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pandnot<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_andnot_ps(a.v,b.v)); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pload <Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload<Packet4f>(&real_ref(*from))); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf ploadu<Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu<Packet4f>(&real_ref(*from))); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<float>&  from) | ||||
| { | ||||
|   Packet2cf res; | ||||
|   #if EIGEN_GNUC_AT_MOST(4,2) | ||||
|   // workaround annoying "may be used uninitialized in this function" warning with gcc 4.2 | ||||
|   res.v = _mm_loadl_pi(_mm_set1_ps(0.0f), reinterpret_cast<const __m64*>(&from)); | ||||
|   #else | ||||
|   res.v = _mm_loadl_pi(res.v, (const __m64*)&from); | ||||
|   #endif | ||||
|   return Packet2cf(_mm_movelh_ps(res.v,res.v)); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf ploaddup<Packet2cf>(const std::complex<float>* from) { return pset1<Packet2cf>(*from); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE void pstore <std::complex<float> >(std::complex<float> *   to, const Packet2cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore(&real_ref(*to), from.v); } | ||||
| template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float> *   to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu(&real_ref(*to), from.v); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE void prefetch<std::complex<float> >(const std::complex<float> *   addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE std::complex<float>  pfirst<Packet2cf>(const Packet2cf& a) | ||||
| { | ||||
|   #if EIGEN_GNUC_AT_MOST(4,3) | ||||
|   // Workaround gcc 4.2 ICE - this is not performance wise ideal, but who cares... | ||||
|   // This workaround also fix invalid code generation with gcc 4.3 | ||||
|   EIGEN_ALIGN16 std::complex<float> res[2]; | ||||
|   _mm_store_ps((float*)res, a.v); | ||||
|   return res[0]; | ||||
|   #else | ||||
|   std::complex<float> res; | ||||
|   _mm_storel_pi((__m64*)&res, a.v); | ||||
|   return res; | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf preverse(const Packet2cf& a) { return Packet2cf(_mm_castpd_ps(preverse(_mm_castps_pd(a.v)))); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE std::complex<float> predux<Packet2cf>(const Packet2cf& a) | ||||
| { | ||||
|   return pfirst(Packet2cf(_mm_add_ps(a.v, _mm_movehl_ps(a.v,a.v)))); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf preduxp<Packet2cf>(const Packet2cf* vecs) | ||||
| { | ||||
|   return Packet2cf(_mm_add_ps(_mm_movelh_ps(vecs[0].v,vecs[1].v), _mm_movehl_ps(vecs[1].v,vecs[0].v))); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE std::complex<float> predux_mul<Packet2cf>(const Packet2cf& a) | ||||
| { | ||||
|   return pfirst(pmul(a, Packet2cf(_mm_movehl_ps(a.v,a.v)))); | ||||
| } | ||||
|  | ||||
| template<int Offset> | ||||
| struct palign_impl<Offset,Packet2cf> | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Packet2cf& first, const Packet2cf& second) | ||||
|   { | ||||
|     if (Offset==1) | ||||
|     { | ||||
|       first.v = _mm_movehl_ps(first.v, first.v); | ||||
|       first.v = _mm_movelh_ps(first.v, second.v); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct conj_helper<Packet2cf, Packet2cf, false,true> | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const | ||||
|   { return padd(pmul(x,y),c); } | ||||
|  | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const | ||||
|   { | ||||
|     #ifdef EIGEN_VECTORIZE_SSE3 | ||||
|     return internal::pmul(a, pconj(b)); | ||||
|     #else | ||||
|     const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0x00000000,0x80000000,0x00000000,0x80000000)); | ||||
|     return Packet2cf(_mm_add_ps(_mm_xor_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 0, 0, 2, 2), b.v), mask), | ||||
|                                 _mm_mul_ps(vec4f_swizzle1(a.v, 1, 1, 3, 3), | ||||
|                                            vec4f_swizzle1(b.v, 1, 0, 3, 2)))); | ||||
|     #endif | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct conj_helper<Packet2cf, Packet2cf, true,false> | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const | ||||
|   { return padd(pmul(x,y),c); } | ||||
|  | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const | ||||
|   { | ||||
|     #ifdef EIGEN_VECTORIZE_SSE3 | ||||
|     return internal::pmul(pconj(a), b); | ||||
|     #else | ||||
|     const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0x00000000,0x80000000,0x00000000,0x80000000)); | ||||
|     return Packet2cf(_mm_add_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 0, 0, 2, 2), b.v), | ||||
|                                 _mm_xor_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 1, 1, 3, 3), | ||||
|                                                       vec4f_swizzle1(b.v, 1, 0, 3, 2)), mask))); | ||||
|     #endif | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct conj_helper<Packet2cf, Packet2cf, true,true> | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const | ||||
|   { return padd(pmul(x,y),c); } | ||||
|  | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const | ||||
|   { | ||||
|     #ifdef EIGEN_VECTORIZE_SSE3 | ||||
|     return pconj(internal::pmul(a, b)); | ||||
|     #else | ||||
|     const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0x00000000,0x80000000,0x00000000,0x80000000)); | ||||
|     return Packet2cf(_mm_sub_ps(_mm_xor_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 0, 0, 2, 2), b.v), mask), | ||||
|                                 _mm_mul_ps(vec4f_swizzle1(a.v, 1, 1, 3, 3), | ||||
|                                            vec4f_swizzle1(b.v, 1, 0, 3, 2)))); | ||||
|     #endif | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct conj_helper<Packet4f, Packet2cf, false,false> | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet4f& x, const Packet2cf& y, const Packet2cf& c) const | ||||
|   { return padd(c, pmul(x,y)); } | ||||
|  | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmul(const Packet4f& x, const Packet2cf& y) const | ||||
|   { return Packet2cf(Eigen::internal::pmul(x, y.v)); } | ||||
| }; | ||||
|  | ||||
| template<> struct conj_helper<Packet2cf, Packet4f, false,false> | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet4f& y, const Packet2cf& c) const | ||||
|   { return padd(c, pmul(x,y)); } | ||||
|  | ||||
|   EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& x, const Packet4f& y) const | ||||
|   { return Packet2cf(Eigen::internal::pmul(x.v, y)); } | ||||
| }; | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, const Packet2cf& b) | ||||
| { | ||||
|   // TODO optimize it for SSE3 and 4 | ||||
|   Packet2cf res = conj_helper<Packet2cf,Packet2cf,false,true>().pmul(a,b); | ||||
|   __m128 s = _mm_mul_ps(b.v,b.v); | ||||
|   return Packet2cf(_mm_div_ps(res.v,_mm_add_ps(s,_mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(s), 0xb1))))); | ||||
| } | ||||
|  | ||||
| EIGEN_STRONG_INLINE Packet2cf pcplxflip/*<Packet2cf>*/(const Packet2cf& x) | ||||
| { | ||||
|   return Packet2cf(vec4f_swizzle1(x.v, 1, 0, 3, 2)); | ||||
| } | ||||
|  | ||||
|  | ||||
| //---------- double ---------- | ||||
| struct Packet1cd | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet1cd() {} | ||||
|   EIGEN_STRONG_INLINE explicit Packet1cd(const __m128d& a) : v(a) {} | ||||
|   __m128d  v; | ||||
| }; | ||||
|  | ||||
| template<> struct packet_traits<std::complex<double> >  : default_packet_traits | ||||
| { | ||||
|   typedef Packet1cd type; | ||||
|   enum { | ||||
|     Vectorizable = 1, | ||||
|     AlignedOnScalar = 0, | ||||
|     size = 1, | ||||
|  | ||||
|     HasAdd    = 1, | ||||
|     HasSub    = 1, | ||||
|     HasMul    = 1, | ||||
|     HasDiv    = 1, | ||||
|     HasNegate = 1, | ||||
|     HasAbs    = 0, | ||||
|     HasAbs2   = 0, | ||||
|     HasMin    = 0, | ||||
|     HasMax    = 0, | ||||
|     HasSetLinear = 0 | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| template<> struct unpacket_traits<Packet1cd> { typedef std::complex<double> type; enum {size=1}; }; | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet1cd padd<Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(_mm_add_pd(a.v,b.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet1cd psub<Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(_mm_sub_pd(a.v,b.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet1cd pnegate(const Packet1cd& a) { return Packet1cd(pnegate(a.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet1cd pconj(const Packet1cd& a) | ||||
| { | ||||
|   const __m128d mask = _mm_castsi128_pd(_mm_set_epi32(0x80000000,0x0,0x0,0x0)); | ||||
|   return Packet1cd(_mm_xor_pd(a.v,mask)); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet1cd pmul<Packet1cd>(const Packet1cd& a, const Packet1cd& b) | ||||
| { | ||||
|   // TODO optimize it for SSE3 and 4 | ||||
|   #ifdef EIGEN_VECTORIZE_SSE3 | ||||
|   return Packet1cd(_mm_addsub_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 0, 0), b.v), | ||||
|                                  _mm_mul_pd(vec2d_swizzle1(a.v, 1, 1), | ||||
|                                             vec2d_swizzle1(b.v, 1, 0)))); | ||||
|   #else | ||||
|   const __m128d mask = _mm_castsi128_pd(_mm_set_epi32(0x0,0x0,0x80000000,0x0)); | ||||
|   return Packet1cd(_mm_add_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 0, 0), b.v), | ||||
|                               _mm_xor_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 1, 1), | ||||
|                                                     vec2d_swizzle1(b.v, 1, 0)), mask))); | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet1cd pand   <Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(_mm_and_pd(a.v,b.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet1cd por    <Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(_mm_or_pd(a.v,b.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet1cd pxor   <Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(_mm_xor_pd(a.v,b.v)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet1cd pandnot<Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(_mm_andnot_pd(a.v,b.v)); } | ||||
|  | ||||
| // FIXME force unaligned load, this is a temporary fix | ||||
| template<> EIGEN_STRONG_INLINE Packet1cd pload <Packet1cd>(const std::complex<double>* from) | ||||
| { EIGEN_DEBUG_ALIGNED_LOAD return Packet1cd(pload<Packet2d>((const double*)from)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet1cd ploadu<Packet1cd>(const std::complex<double>* from) | ||||
| { EIGEN_DEBUG_UNALIGNED_LOAD return Packet1cd(ploadu<Packet2d>((const double*)from)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet1cd pset1<Packet1cd>(const std::complex<double>&  from) | ||||
| { /* here we really have to use unaligned loads :( */ return ploadu<Packet1cd>(&from); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet1cd ploaddup<Packet1cd>(const std::complex<double>* from) { return pset1<Packet1cd>(*from); } | ||||
|  | ||||
| // FIXME force unaligned store, this is a temporary fix | ||||
| template<> EIGEN_STRONG_INLINE void pstore <std::complex<double> >(std::complex<double> *   to, const Packet1cd& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((double*)to, from.v); } | ||||
| template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<double> >(std::complex<double> *   to, const Packet1cd& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, from.v); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE void prefetch<std::complex<double> >(const std::complex<double> *   addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE std::complex<double>  pfirst<Packet1cd>(const Packet1cd& a) | ||||
| { | ||||
|   EIGEN_ALIGN16 double res[2]; | ||||
|   _mm_store_pd(res, a.v); | ||||
|   return std::complex<double>(res[0],res[1]); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet1cd preverse(const Packet1cd& a) { return a; } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE std::complex<double> predux<Packet1cd>(const Packet1cd& a) | ||||
| { | ||||
|   return pfirst(a); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet1cd preduxp<Packet1cd>(const Packet1cd* vecs) | ||||
| { | ||||
|   return vecs[0]; | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE std::complex<double> predux_mul<Packet1cd>(const Packet1cd& a) | ||||
| { | ||||
|   return pfirst(a); | ||||
| } | ||||
|  | ||||
| template<int Offset> | ||||
| struct palign_impl<Offset,Packet1cd> | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Packet1cd& /*first*/, const Packet1cd& /*second*/) | ||||
|   { | ||||
|     // FIXME is it sure we never have to align a Packet1cd? | ||||
|     // Even though a std::complex<double> has 16 bytes, it is not necessarily aligned on a 16 bytes boundary... | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct conj_helper<Packet1cd, Packet1cd, false,true> | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet1cd& y, const Packet1cd& c) const | ||||
|   { return padd(pmul(x,y),c); } | ||||
|  | ||||
|   EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& a, const Packet1cd& b) const | ||||
|   { | ||||
|     #ifdef EIGEN_VECTORIZE_SSE3 | ||||
|     return internal::pmul(a, pconj(b)); | ||||
|     #else | ||||
|     const __m128d mask = _mm_castsi128_pd(_mm_set_epi32(0x80000000,0x0,0x0,0x0)); | ||||
|     return Packet1cd(_mm_add_pd(_mm_xor_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 0, 0), b.v), mask), | ||||
|                                 _mm_mul_pd(vec2d_swizzle1(a.v, 1, 1), | ||||
|                                            vec2d_swizzle1(b.v, 1, 0)))); | ||||
|     #endif | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct conj_helper<Packet1cd, Packet1cd, true,false> | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet1cd& y, const Packet1cd& c) const | ||||
|   { return padd(pmul(x,y),c); } | ||||
|  | ||||
|   EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& a, const Packet1cd& b) const | ||||
|   { | ||||
|     #ifdef EIGEN_VECTORIZE_SSE3 | ||||
|     return internal::pmul(pconj(a), b); | ||||
|     #else | ||||
|     const __m128d mask = _mm_castsi128_pd(_mm_set_epi32(0x80000000,0x0,0x0,0x0)); | ||||
|     return Packet1cd(_mm_add_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 0, 0), b.v), | ||||
|                                 _mm_xor_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 1, 1), | ||||
|                                                       vec2d_swizzle1(b.v, 1, 0)), mask))); | ||||
|     #endif | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct conj_helper<Packet1cd, Packet1cd, true,true> | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet1cd& y, const Packet1cd& c) const | ||||
|   { return padd(pmul(x,y),c); } | ||||
|  | ||||
|   EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& a, const Packet1cd& b) const | ||||
|   { | ||||
|     #ifdef EIGEN_VECTORIZE_SSE3 | ||||
|     return pconj(internal::pmul(a, b)); | ||||
|     #else | ||||
|     const __m128d mask = _mm_castsi128_pd(_mm_set_epi32(0x80000000,0x0,0x0,0x0)); | ||||
|     return Packet1cd(_mm_sub_pd(_mm_xor_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 0, 0), b.v), mask), | ||||
|                                 _mm_mul_pd(vec2d_swizzle1(a.v, 1, 1), | ||||
|                                            vec2d_swizzle1(b.v, 1, 0)))); | ||||
|     #endif | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<> struct conj_helper<Packet2d, Packet1cd, false,false> | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet2d& x, const Packet1cd& y, const Packet1cd& c) const | ||||
|   { return padd(c, pmul(x,y)); } | ||||
|  | ||||
|   EIGEN_STRONG_INLINE Packet1cd pmul(const Packet2d& x, const Packet1cd& y) const | ||||
|   { return Packet1cd(Eigen::internal::pmul(x, y.v)); } | ||||
| }; | ||||
|  | ||||
| template<> struct conj_helper<Packet1cd, Packet2d, false,false> | ||||
| { | ||||
|   EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet2d& y, const Packet1cd& c) const | ||||
|   { return padd(c, pmul(x,y)); } | ||||
|  | ||||
|   EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& x, const Packet2d& y) const | ||||
|   { return Packet1cd(Eigen::internal::pmul(x.v, y)); } | ||||
| }; | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet1cd pdiv<Packet1cd>(const Packet1cd& a, const Packet1cd& b) | ||||
| { | ||||
|   // TODO optimize it for SSE3 and 4 | ||||
|   Packet1cd res = conj_helper<Packet1cd,Packet1cd,false,true>().pmul(a,b); | ||||
|   __m128d s = _mm_mul_pd(b.v,b.v); | ||||
|   return Packet1cd(_mm_div_pd(res.v, _mm_add_pd(s,_mm_shuffle_pd(s, s, 0x1)))); | ||||
| } | ||||
|  | ||||
| EIGEN_STRONG_INLINE Packet1cd pcplxflip/*<Packet1cd>*/(const Packet1cd& x) | ||||
| { | ||||
|   return Packet1cd(preverse(x.v)); | ||||
| } | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_COMPLEX_SSE_H | ||||
							
								
								
									
										388
									
								
								latan/Eigen/src/Core/arch/SSE/MathFunctions.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										388
									
								
								latan/Eigen/src/Core/arch/SSE/MathFunctions.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,388 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2007 Julien Pommier | ||||
| // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| /* The sin, cos, exp, and log functions of this file come from | ||||
|  * Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/ | ||||
|  */ | ||||
|  | ||||
| #ifndef EIGEN_MATH_FUNCTIONS_SSE_H | ||||
| #define EIGEN_MATH_FUNCTIONS_SSE_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED | ||||
| Packet4f plog<Packet4f>(const Packet4f& _x) | ||||
| { | ||||
|   Packet4f x = _x; | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(1 , 1.0f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(half, 0.5f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4i(0x7f, 0x7f); | ||||
|  | ||||
|   _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(inv_mant_mask, ~0x7f800000); | ||||
|  | ||||
|   /* the smallest non denormalized float number */ | ||||
|   _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(min_norm_pos,  0x00800000); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(minus_inf,     0xff800000);//-1.f/0.f); | ||||
|    | ||||
|   /* natural logarithm computed for 4 simultaneous float | ||||
|     return NaN for x <= 0 | ||||
|   */ | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_SQRTHF, 0.707106781186547524f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p0, 7.0376836292E-2f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p1, - 1.1514610310E-1f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p2, 1.1676998740E-1f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p3, - 1.2420140846E-1f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p4, + 1.4249322787E-1f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p5, - 1.6668057665E-1f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p6, + 2.0000714765E-1f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p7, - 2.4999993993E-1f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p8, + 3.3333331174E-1f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_log_q1, -2.12194440e-4f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_log_q2, 0.693359375f); | ||||
|  | ||||
|  | ||||
|   Packet4i emm0; | ||||
|  | ||||
|   Packet4f invalid_mask = _mm_cmplt_ps(x, _mm_setzero_ps()); | ||||
|   Packet4f iszero_mask = _mm_cmpeq_ps(x, _mm_setzero_ps()); | ||||
|  | ||||
|   x = pmax(x, p4f_min_norm_pos);  /* cut off denormalized stuff */ | ||||
|   emm0 = _mm_srli_epi32(_mm_castps_si128(x), 23); | ||||
|  | ||||
|   /* keep only the fractional part */ | ||||
|   x = _mm_and_ps(x, p4f_inv_mant_mask); | ||||
|   x = _mm_or_ps(x, p4f_half); | ||||
|  | ||||
|   emm0 = _mm_sub_epi32(emm0, p4i_0x7f); | ||||
|   Packet4f e = padd(_mm_cvtepi32_ps(emm0), p4f_1); | ||||
|  | ||||
|   /* part2: | ||||
|      if( x < SQRTHF ) { | ||||
|        e -= 1; | ||||
|        x = x + x - 1.0; | ||||
|      } else { x = x - 1.0; } | ||||
|   */ | ||||
|   Packet4f mask = _mm_cmplt_ps(x, p4f_cephes_SQRTHF); | ||||
|   Packet4f tmp = _mm_and_ps(x, mask); | ||||
|   x = psub(x, p4f_1); | ||||
|   e = psub(e, _mm_and_ps(p4f_1, mask)); | ||||
|   x = padd(x, tmp); | ||||
|  | ||||
|   Packet4f x2 = pmul(x,x); | ||||
|   Packet4f x3 = pmul(x2,x); | ||||
|  | ||||
|   Packet4f y, y1, y2; | ||||
|   y  = pmadd(p4f_cephes_log_p0, x, p4f_cephes_log_p1); | ||||
|   y1 = pmadd(p4f_cephes_log_p3, x, p4f_cephes_log_p4); | ||||
|   y2 = pmadd(p4f_cephes_log_p6, x, p4f_cephes_log_p7); | ||||
|   y  = pmadd(y , x, p4f_cephes_log_p2); | ||||
|   y1 = pmadd(y1, x, p4f_cephes_log_p5); | ||||
|   y2 = pmadd(y2, x, p4f_cephes_log_p8); | ||||
|   y = pmadd(y, x3, y1); | ||||
|   y = pmadd(y, x3, y2); | ||||
|   y = pmul(y, x3); | ||||
|  | ||||
|   y1 = pmul(e, p4f_cephes_log_q1); | ||||
|   tmp = pmul(x2, p4f_half); | ||||
|   y = padd(y, y1); | ||||
|   x = psub(x, tmp); | ||||
|   y2 = pmul(e, p4f_cephes_log_q2); | ||||
|   x = padd(x, y); | ||||
|   x = padd(x, y2); | ||||
|   // negative arg will be NAN, 0 will be -INF | ||||
|   return _mm_or_ps(_mm_andnot_ps(iszero_mask, _mm_or_ps(x, invalid_mask)), | ||||
|                    _mm_and_ps(iszero_mask, p4f_minus_inf)); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED | ||||
| Packet4f pexp<Packet4f>(const Packet4f& _x) | ||||
| { | ||||
|   Packet4f x = _x; | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(1 , 1.0f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(half, 0.5f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4i(0x7f, 0x7f); | ||||
|  | ||||
|  | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(exp_hi,  88.3762626647950f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(exp_lo, -88.3762626647949f); | ||||
|  | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_LOG2EF, 1.44269504088896341f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_C1, 0.693359375f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_C2, -2.12194440e-4f); | ||||
|  | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p0, 1.9875691500E-4f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p1, 1.3981999507E-3f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p2, 8.3334519073E-3f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p3, 4.1665795894E-2f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p4, 1.6666665459E-1f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p5, 5.0000001201E-1f); | ||||
|  | ||||
|   Packet4f tmp = _mm_setzero_ps(), fx; | ||||
|   Packet4i emm0; | ||||
|  | ||||
|   // clamp x | ||||
|   x = pmax(pmin(x, p4f_exp_hi), p4f_exp_lo); | ||||
|  | ||||
|   /* express exp(x) as exp(g + n*log(2)) */ | ||||
|   fx = pmadd(x, p4f_cephes_LOG2EF, p4f_half); | ||||
|  | ||||
|   /* how to perform a floorf with SSE: just below */ | ||||
|   emm0 = _mm_cvttps_epi32(fx); | ||||
|   tmp  = _mm_cvtepi32_ps(emm0); | ||||
|   /* if greater, substract 1 */ | ||||
|   Packet4f mask = _mm_cmpgt_ps(tmp, fx); | ||||
|   mask = _mm_and_ps(mask, p4f_1); | ||||
|   fx = psub(tmp, mask); | ||||
|  | ||||
|   tmp = pmul(fx, p4f_cephes_exp_C1); | ||||
|   Packet4f z = pmul(fx, p4f_cephes_exp_C2); | ||||
|   x = psub(x, tmp); | ||||
|   x = psub(x, z); | ||||
|  | ||||
|   z = pmul(x,x); | ||||
|  | ||||
|   Packet4f y = p4f_cephes_exp_p0; | ||||
|   y = pmadd(y, x, p4f_cephes_exp_p1); | ||||
|   y = pmadd(y, x, p4f_cephes_exp_p2); | ||||
|   y = pmadd(y, x, p4f_cephes_exp_p3); | ||||
|   y = pmadd(y, x, p4f_cephes_exp_p4); | ||||
|   y = pmadd(y, x, p4f_cephes_exp_p5); | ||||
|   y = pmadd(y, z, x); | ||||
|   y = padd(y, p4f_1); | ||||
|  | ||||
|   // build 2^n | ||||
|   emm0 = _mm_cvttps_epi32(fx); | ||||
|   emm0 = _mm_add_epi32(emm0, p4i_0x7f); | ||||
|   emm0 = _mm_slli_epi32(emm0, 23); | ||||
|   return pmul(y, _mm_castsi128_ps(emm0)); | ||||
| } | ||||
|  | ||||
| /* evaluation of 4 sines at onces, using SSE2 intrinsics. | ||||
|  | ||||
|    The code is the exact rewriting of the cephes sinf function. | ||||
|    Precision is excellent as long as x < 8192 (I did not bother to | ||||
|    take into account the special handling they have for greater values | ||||
|    -- it does not return garbage for arguments over 8192, though, but | ||||
|    the extra precision is missing). | ||||
|  | ||||
|    Note that it is such that sinf((float)M_PI) = 8.74e-8, which is the | ||||
|    surprising but correct result. | ||||
| */ | ||||
|  | ||||
| template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED | ||||
| Packet4f psin<Packet4f>(const Packet4f& _x) | ||||
| { | ||||
|   Packet4f x = _x; | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(1 , 1.0f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(half, 0.5f); | ||||
|  | ||||
|   _EIGEN_DECLARE_CONST_Packet4i(1, 1); | ||||
|   _EIGEN_DECLARE_CONST_Packet4i(not1, ~1); | ||||
|   _EIGEN_DECLARE_CONST_Packet4i(2, 2); | ||||
|   _EIGEN_DECLARE_CONST_Packet4i(4, 4); | ||||
|  | ||||
|   _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(sign_mask, 0x80000000); | ||||
|  | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(minus_cephes_DP1,-0.78515625f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(minus_cephes_DP2, -2.4187564849853515625e-4f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(minus_cephes_DP3, -3.77489497744594108e-8f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(sincof_p0, -1.9515295891E-4f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(sincof_p1,  8.3321608736E-3f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(sincof_p2, -1.6666654611E-1f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(coscof_p0,  2.443315711809948E-005f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(coscof_p1, -1.388731625493765E-003f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(coscof_p2,  4.166664568298827E-002f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_FOPI, 1.27323954473516f); // 4 / M_PI | ||||
|  | ||||
|   Packet4f xmm1, xmm2 = _mm_setzero_ps(), xmm3, sign_bit, y; | ||||
|  | ||||
|   Packet4i emm0, emm2; | ||||
|   sign_bit = x; | ||||
|   /* take the absolute value */ | ||||
|   x = pabs(x); | ||||
|  | ||||
|   /* take the modulo */ | ||||
|  | ||||
|   /* extract the sign bit (upper one) */ | ||||
|   sign_bit = _mm_and_ps(sign_bit, p4f_sign_mask); | ||||
|  | ||||
|   /* scale by 4/Pi */ | ||||
|   y = pmul(x, p4f_cephes_FOPI); | ||||
|  | ||||
|   /* store the integer part of y in mm0 */ | ||||
|   emm2 = _mm_cvttps_epi32(y); | ||||
|   /* j=(j+1) & (~1) (see the cephes sources) */ | ||||
|   emm2 = _mm_add_epi32(emm2, p4i_1); | ||||
|   emm2 = _mm_and_si128(emm2, p4i_not1); | ||||
|   y = _mm_cvtepi32_ps(emm2); | ||||
|   /* get the swap sign flag */ | ||||
|   emm0 = _mm_and_si128(emm2, p4i_4); | ||||
|   emm0 = _mm_slli_epi32(emm0, 29); | ||||
|   /* get the polynom selection mask | ||||
|      there is one polynom for 0 <= x <= Pi/4 | ||||
|      and another one for Pi/4<x<=Pi/2 | ||||
|  | ||||
|      Both branches will be computed. | ||||
|   */ | ||||
|   emm2 = _mm_and_si128(emm2, p4i_2); | ||||
|   emm2 = _mm_cmpeq_epi32(emm2, _mm_setzero_si128()); | ||||
|  | ||||
|   Packet4f swap_sign_bit = _mm_castsi128_ps(emm0); | ||||
|   Packet4f poly_mask = _mm_castsi128_ps(emm2); | ||||
|   sign_bit = _mm_xor_ps(sign_bit, swap_sign_bit); | ||||
|  | ||||
|   /* The magic pass: "Extended precision modular arithmetic" | ||||
|      x = ((x - y * DP1) - y * DP2) - y * DP3; */ | ||||
|   xmm1 = pmul(y, p4f_minus_cephes_DP1); | ||||
|   xmm2 = pmul(y, p4f_minus_cephes_DP2); | ||||
|   xmm3 = pmul(y, p4f_minus_cephes_DP3); | ||||
|   x = padd(x, xmm1); | ||||
|   x = padd(x, xmm2); | ||||
|   x = padd(x, xmm3); | ||||
|  | ||||
|   /* Evaluate the first polynom  (0 <= x <= Pi/4) */ | ||||
|   y = p4f_coscof_p0; | ||||
|   Packet4f z = _mm_mul_ps(x,x); | ||||
|  | ||||
|   y = pmadd(y, z, p4f_coscof_p1); | ||||
|   y = pmadd(y, z, p4f_coscof_p2); | ||||
|   y = pmul(y, z); | ||||
|   y = pmul(y, z); | ||||
|   Packet4f tmp = pmul(z, p4f_half); | ||||
|   y = psub(y, tmp); | ||||
|   y = padd(y, p4f_1); | ||||
|  | ||||
|   /* Evaluate the second polynom  (Pi/4 <= x <= 0) */ | ||||
|  | ||||
|   Packet4f y2 = p4f_sincof_p0; | ||||
|   y2 = pmadd(y2, z, p4f_sincof_p1); | ||||
|   y2 = pmadd(y2, z, p4f_sincof_p2); | ||||
|   y2 = pmul(y2, z); | ||||
|   y2 = pmul(y2, x); | ||||
|   y2 = padd(y2, x); | ||||
|  | ||||
|   /* select the correct result from the two polynoms */ | ||||
|   y2 = _mm_and_ps(poly_mask, y2); | ||||
|   y = _mm_andnot_ps(poly_mask, y); | ||||
|   y = _mm_or_ps(y,y2); | ||||
|   /* update the sign */ | ||||
|   return _mm_xor_ps(y, sign_bit); | ||||
| } | ||||
|  | ||||
| /* almost the same as psin */ | ||||
| template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED | ||||
| Packet4f pcos<Packet4f>(const Packet4f& _x) | ||||
| { | ||||
|   Packet4f x = _x; | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(1 , 1.0f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(half, 0.5f); | ||||
|  | ||||
|   _EIGEN_DECLARE_CONST_Packet4i(1, 1); | ||||
|   _EIGEN_DECLARE_CONST_Packet4i(not1, ~1); | ||||
|   _EIGEN_DECLARE_CONST_Packet4i(2, 2); | ||||
|   _EIGEN_DECLARE_CONST_Packet4i(4, 4); | ||||
|  | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(minus_cephes_DP1,-0.78515625f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(minus_cephes_DP2, -2.4187564849853515625e-4f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(minus_cephes_DP3, -3.77489497744594108e-8f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(sincof_p0, -1.9515295891E-4f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(sincof_p1,  8.3321608736E-3f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(sincof_p2, -1.6666654611E-1f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(coscof_p0,  2.443315711809948E-005f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(coscof_p1, -1.388731625493765E-003f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(coscof_p2,  4.166664568298827E-002f); | ||||
|   _EIGEN_DECLARE_CONST_Packet4f(cephes_FOPI, 1.27323954473516f); // 4 / M_PI | ||||
|  | ||||
|   Packet4f xmm1, xmm2 = _mm_setzero_ps(), xmm3, y; | ||||
|   Packet4i emm0, emm2; | ||||
|  | ||||
|   x = pabs(x); | ||||
|  | ||||
|   /* scale by 4/Pi */ | ||||
|   y = pmul(x, p4f_cephes_FOPI); | ||||
|  | ||||
|   /* get the integer part of y */ | ||||
|   emm2 = _mm_cvttps_epi32(y); | ||||
|   /* j=(j+1) & (~1) (see the cephes sources) */ | ||||
|   emm2 = _mm_add_epi32(emm2, p4i_1); | ||||
|   emm2 = _mm_and_si128(emm2, p4i_not1); | ||||
|   y = _mm_cvtepi32_ps(emm2); | ||||
|  | ||||
|   emm2 = _mm_sub_epi32(emm2, p4i_2); | ||||
|  | ||||
|   /* get the swap sign flag */ | ||||
|   emm0 = _mm_andnot_si128(emm2, p4i_4); | ||||
|   emm0 = _mm_slli_epi32(emm0, 29); | ||||
|   /* get the polynom selection mask */ | ||||
|   emm2 = _mm_and_si128(emm2, p4i_2); | ||||
|   emm2 = _mm_cmpeq_epi32(emm2, _mm_setzero_si128()); | ||||
|  | ||||
|   Packet4f sign_bit = _mm_castsi128_ps(emm0); | ||||
|   Packet4f poly_mask = _mm_castsi128_ps(emm2); | ||||
|  | ||||
|   /* The magic pass: "Extended precision modular arithmetic" | ||||
|      x = ((x - y * DP1) - y * DP2) - y * DP3; */ | ||||
|   xmm1 = pmul(y, p4f_minus_cephes_DP1); | ||||
|   xmm2 = pmul(y, p4f_minus_cephes_DP2); | ||||
|   xmm3 = pmul(y, p4f_minus_cephes_DP3); | ||||
|   x = padd(x, xmm1); | ||||
|   x = padd(x, xmm2); | ||||
|   x = padd(x, xmm3); | ||||
|  | ||||
|   /* Evaluate the first polynom  (0 <= x <= Pi/4) */ | ||||
|   y = p4f_coscof_p0; | ||||
|   Packet4f z = pmul(x,x); | ||||
|  | ||||
|   y = pmadd(y,z,p4f_coscof_p1); | ||||
|   y = pmadd(y,z,p4f_coscof_p2); | ||||
|   y = pmul(y, z); | ||||
|   y = pmul(y, z); | ||||
|   Packet4f tmp = _mm_mul_ps(z, p4f_half); | ||||
|   y = psub(y, tmp); | ||||
|   y = padd(y, p4f_1); | ||||
|  | ||||
|   /* Evaluate the second polynom  (Pi/4 <= x <= 0) */ | ||||
|   Packet4f y2 = p4f_sincof_p0; | ||||
|   y2 = pmadd(y2, z, p4f_sincof_p1); | ||||
|   y2 = pmadd(y2, z, p4f_sincof_p2); | ||||
|   y2 = pmul(y2, z); | ||||
|   y2 = pmadd(y2, x, x); | ||||
|  | ||||
|   /* select the correct result from the two polynoms */ | ||||
|   y2 = _mm_and_ps(poly_mask, y2); | ||||
|   y  = _mm_andnot_ps(poly_mask, y); | ||||
|   y  = _mm_or_ps(y,y2); | ||||
|  | ||||
|   /* update the sign */ | ||||
|   return _mm_xor_ps(y, sign_bit); | ||||
| } | ||||
|  | ||||
| // This is based on Quake3's fast inverse square root. | ||||
| // For detail see here: http://www.beyond3d.com/content/articles/8/ | ||||
| template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED | ||||
| Packet4f psqrt<Packet4f>(const Packet4f& _x) | ||||
| { | ||||
|   Packet4f half = pmul(_x, pset1<Packet4f>(.5f)); | ||||
|  | ||||
|   /* select only the inverse sqrt of non-zero inputs */ | ||||
|   Packet4f non_zero_mask = _mm_cmpgt_ps(_x, pset1<Packet4f>(std::numeric_limits<float>::epsilon())); | ||||
|   Packet4f x = _mm_and_ps(non_zero_mask, _mm_rsqrt_ps(_x)); | ||||
|  | ||||
|   x = pmul(x, psub(pset1<Packet4f>(1.5f), pmul(half, pmul(x,x)))); | ||||
|   return pmul(_x,x); | ||||
| } | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_MATH_FUNCTIONS_SSE_H | ||||
							
								
								
									
										632
									
								
								latan/Eigen/src/Core/arch/SSE/PacketMath.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										632
									
								
								latan/Eigen/src/Core/arch/SSE/PacketMath.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,632 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_PACKET_MATH_SSE_H | ||||
| #define EIGEN_PACKET_MATH_SSE_H | ||||
|  | ||||
| namespace Eigen { | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| #ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD | ||||
| #define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 8 | ||||
| #endif | ||||
|  | ||||
| #ifndef EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS | ||||
| #define EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS (2*sizeof(void*)) | ||||
| #endif | ||||
|  | ||||
| typedef __m128  Packet4f; | ||||
| typedef __m128i Packet4i; | ||||
| typedef __m128d Packet2d; | ||||
|  | ||||
| template<> struct is_arithmetic<__m128>  { enum { value = true }; }; | ||||
| template<> struct is_arithmetic<__m128i> { enum { value = true }; }; | ||||
| template<> struct is_arithmetic<__m128d> { enum { value = true }; }; | ||||
|  | ||||
| #define vec4f_swizzle1(v,p,q,r,s) \ | ||||
|   (_mm_castsi128_ps(_mm_shuffle_epi32( _mm_castps_si128(v), ((s)<<6|(r)<<4|(q)<<2|(p))))) | ||||
|  | ||||
| #define vec4i_swizzle1(v,p,q,r,s) \ | ||||
|   (_mm_shuffle_epi32( v, ((s)<<6|(r)<<4|(q)<<2|(p)))) | ||||
|  | ||||
| #define vec2d_swizzle1(v,p,q) \ | ||||
|   (_mm_castsi128_pd(_mm_shuffle_epi32( _mm_castpd_si128(v), ((q*2+1)<<6|(q*2)<<4|(p*2+1)<<2|(p*2))))) | ||||
|    | ||||
| #define vec4f_swizzle2(a,b,p,q,r,s) \ | ||||
|   (_mm_shuffle_ps( (a), (b), ((s)<<6|(r)<<4|(q)<<2|(p)))) | ||||
|  | ||||
| #define vec4i_swizzle2(a,b,p,q,r,s) \ | ||||
|   (_mm_castps_si128( (_mm_shuffle_ps( _mm_castsi128_ps(a), _mm_castsi128_ps(b), ((s)<<6|(r)<<4|(q)<<2|(p)))))) | ||||
|  | ||||
| #define _EIGEN_DECLARE_CONST_Packet4f(NAME,X) \ | ||||
|   const Packet4f p4f_##NAME = pset1<Packet4f>(X) | ||||
|  | ||||
| #define _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(NAME,X) \ | ||||
|   const Packet4f p4f_##NAME = _mm_castsi128_ps(pset1<Packet4i>(X)) | ||||
|  | ||||
| #define _EIGEN_DECLARE_CONST_Packet4i(NAME,X) \ | ||||
|   const Packet4i p4i_##NAME = pset1<Packet4i>(X) | ||||
|  | ||||
|  | ||||
| template<> struct packet_traits<float>  : default_packet_traits | ||||
| { | ||||
|   typedef Packet4f type; | ||||
|   enum { | ||||
|     Vectorizable = 1, | ||||
|     AlignedOnScalar = 1, | ||||
|     size=4, | ||||
|  | ||||
|     HasDiv    = 1, | ||||
|     HasSin  = EIGEN_FAST_MATH, | ||||
|     HasCos  = EIGEN_FAST_MATH, | ||||
|     HasLog  = 1, | ||||
|     HasExp  = 1, | ||||
|     HasSqrt = 1 | ||||
|   }; | ||||
| }; | ||||
| template<> struct packet_traits<double> : default_packet_traits | ||||
| { | ||||
|   typedef Packet2d type; | ||||
|   enum { | ||||
|     Vectorizable = 1, | ||||
|     AlignedOnScalar = 1, | ||||
|     size=2, | ||||
|  | ||||
|     HasDiv    = 1 | ||||
|   }; | ||||
| }; | ||||
| template<> struct packet_traits<int>    : default_packet_traits | ||||
| { | ||||
|   typedef Packet4i type; | ||||
|   enum { | ||||
|     // FIXME check the Has* | ||||
|     Vectorizable = 1, | ||||
|     AlignedOnScalar = 1, | ||||
|     size=4 | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| template<> struct unpacket_traits<Packet4f> { typedef float  type; enum {size=4}; }; | ||||
| template<> struct unpacket_traits<Packet2d> { typedef double type; enum {size=2}; }; | ||||
| template<> struct unpacket_traits<Packet4i> { typedef int    type; enum {size=4}; }; | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER==1500) | ||||
| // Workaround MSVC 9 internal compiler error. | ||||
| // TODO: It has been detected with win64 builds (amd64), so let's check whether it also happens in 32bits+SSE mode | ||||
| // TODO: let's check whether there does not exist a better fix, like adding a pset0() function. (it crashed on pset1(0)). | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pset1<Packet4f>(const float&  from) { return _mm_set_ps(from,from,from,from); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d pset1<Packet2d>(const double& from) { return _mm_set_pd(from,from); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pset1<Packet4i>(const int&    from) { return _mm_set_epi32(from,from,from,from); } | ||||
| #else | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pset1<Packet4f>(const float&  from) { return _mm_set1_ps(from); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d pset1<Packet2d>(const double& from) { return _mm_set1_pd(from); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pset1<Packet4i>(const int&    from) { return _mm_set1_epi32(from); } | ||||
| #endif | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f plset<float>(const float& a) { return _mm_add_ps(pset1<Packet4f>(a), _mm_set_ps(3,2,1,0)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d plset<double>(const double& a) { return _mm_add_pd(pset1<Packet2d>(a),_mm_set_pd(1,0)); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i plset<int>(const int& a) { return _mm_add_epi32(pset1<Packet4i>(a),_mm_set_epi32(3,2,1,0)); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f padd<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_add_ps(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d padd<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_add_pd(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i padd<Packet4i>(const Packet4i& a, const Packet4i& b) { return _mm_add_epi32(a,b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f psub<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_sub_ps(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d psub<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_sub_pd(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i psub<Packet4i>(const Packet4i& a, const Packet4i& b) { return _mm_sub_epi32(a,b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pnegate(const Packet4f& a) | ||||
| { | ||||
|   const Packet4f mask = _mm_castsi128_ps(_mm_setr_epi32(0x80000000,0x80000000,0x80000000,0x80000000)); | ||||
|   return _mm_xor_ps(a,mask); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d pnegate(const Packet2d& a) | ||||
| { | ||||
|   const Packet2d mask = _mm_castsi128_pd(_mm_setr_epi32(0x0,0x80000000,0x0,0x80000000)); | ||||
|   return _mm_xor_pd(a,mask); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pnegate(const Packet4i& a) | ||||
| { | ||||
|   return psub(_mm_setr_epi32(0,0,0,0), a); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pmul<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_mul_ps(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d pmul<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_mul_pd(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pmul<Packet4i>(const Packet4i& a, const Packet4i& b) | ||||
| { | ||||
| #ifdef EIGEN_VECTORIZE_SSE4_1 | ||||
|   return _mm_mullo_epi32(a,b); | ||||
| #else | ||||
|   // this version is slightly faster than 4 scalar products | ||||
|   return vec4i_swizzle1( | ||||
|             vec4i_swizzle2( | ||||
|               _mm_mul_epu32(a,b), | ||||
|               _mm_mul_epu32(vec4i_swizzle1(a,1,0,3,2), | ||||
|                             vec4i_swizzle1(b,1,0,3,2)), | ||||
|               0,2,0,2), | ||||
|             0,2,1,3); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pdiv<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_div_ps(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d pdiv<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_div_pd(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pdiv<Packet4i>(const Packet4i& /*a*/, const Packet4i& /*b*/) | ||||
| { eigen_assert(false && "packet integer division are not supported by SSE"); | ||||
|   return pset1<Packet4i>(0); | ||||
| } | ||||
|  | ||||
| // for some weird raisons, it has to be overloaded for packet of integers | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pmadd(const Packet4i& a, const Packet4i& b, const Packet4i& c) { return padd(pmul(a,b), c); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pmin<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_min_ps(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d pmin<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_min_pd(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pmin<Packet4i>(const Packet4i& a, const Packet4i& b) | ||||
| { | ||||
|   // after some bench, this version *is* faster than a scalar implementation | ||||
|   Packet4i mask = _mm_cmplt_epi32(a,b); | ||||
|   return _mm_or_si128(_mm_and_si128(mask,a),_mm_andnot_si128(mask,b)); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pmax<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_max_ps(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d pmax<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_max_pd(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pmax<Packet4i>(const Packet4i& a, const Packet4i& b) | ||||
| { | ||||
|   // after some bench, this version *is* faster than a scalar implementation | ||||
|   Packet4i mask = _mm_cmpgt_epi32(a,b); | ||||
|   return _mm_or_si128(_mm_and_si128(mask,a),_mm_andnot_si128(mask,b)); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pand<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_and_ps(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d pand<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_and_pd(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pand<Packet4i>(const Packet4i& a, const Packet4i& b) { return _mm_and_si128(a,b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f por<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_or_ps(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d por<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_or_pd(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i por<Packet4i>(const Packet4i& a, const Packet4i& b) { return _mm_or_si128(a,b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pxor<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_xor_ps(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d pxor<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_xor_pd(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pxor<Packet4i>(const Packet4i& a, const Packet4i& b) { return _mm_xor_si128(a,b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pandnot<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_andnot_ps(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d pandnot<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_andnot_pd(a,b); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pandnot<Packet4i>(const Packet4i& a, const Packet4i& b) { return _mm_andnot_si128(a,b); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pload<Packet4f>(const float*   from) { EIGEN_DEBUG_ALIGNED_LOAD return _mm_load_ps(from); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d pload<Packet2d>(const double*  from) { EIGEN_DEBUG_ALIGNED_LOAD return _mm_load_pd(from); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pload<Packet4i>(const int*     from) { EIGEN_DEBUG_ALIGNED_LOAD return _mm_load_si128(reinterpret_cast<const Packet4i*>(from)); } | ||||
|  | ||||
| #if defined(_MSC_VER) | ||||
|   template<> EIGEN_STRONG_INLINE Packet4f ploadu<Packet4f>(const float*  from) { | ||||
|     EIGEN_DEBUG_UNALIGNED_LOAD | ||||
|     #if (_MSC_VER==1600) | ||||
|     // NOTE Some version of MSVC10 generates bad code when using _mm_loadu_ps | ||||
|     // (i.e., it does not generate an unaligned load!! | ||||
|     // TODO On most architectures this version should also be faster than a single _mm_loadu_ps | ||||
|     // so we could also enable it for MSVC08 but first we have to make this later does not generate crap when doing so... | ||||
|     __m128 res = _mm_loadl_pi(_mm_set1_ps(0.0f), (const __m64*)(from)); | ||||
|     res = _mm_loadh_pi(res, (const __m64*)(from+2)); | ||||
|     return res; | ||||
|     #else | ||||
|     return _mm_loadu_ps(from); | ||||
|     #endif | ||||
|   } | ||||
|   template<> EIGEN_STRONG_INLINE Packet2d ploadu<Packet2d>(const double* from) { EIGEN_DEBUG_UNALIGNED_LOAD return _mm_loadu_pd(from); } | ||||
|   template<> EIGEN_STRONG_INLINE Packet4i ploadu<Packet4i>(const int*    from) { EIGEN_DEBUG_UNALIGNED_LOAD return _mm_loadu_si128(reinterpret_cast<const Packet4i*>(from)); } | ||||
| #else | ||||
| // Fast unaligned loads. Note that here we cannot directly use intrinsics: this would | ||||
| // require pointer casting to incompatible pointer types and leads to invalid code | ||||
| // because of the strict aliasing rule. The "dummy" stuff are required to enforce | ||||
| // a correct instruction dependency. | ||||
| // TODO: do the same for MSVC (ICC is compatible) | ||||
| // NOTE: with the code below, MSVC's compiler crashes! | ||||
|  | ||||
| #if defined(__GNUC__) && defined(__i386__) | ||||
|   // bug 195: gcc/i386 emits weird x87 fldl/fstpl instructions for _mm_load_sd | ||||
|   #define EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS 1 | ||||
| #elif defined(__clang__) | ||||
|   // bug 201: Segfaults in __mm_loadh_pd with clang 2.8 | ||||
|   #define EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS 1 | ||||
| #else | ||||
|   #define EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS 0 | ||||
| #endif | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f ploadu<Packet4f>(const float* from) | ||||
| { | ||||
|   EIGEN_DEBUG_UNALIGNED_LOAD | ||||
| #if EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS | ||||
|   return _mm_loadu_ps(from); | ||||
| #else | ||||
|   __m128d res; | ||||
|   res =  _mm_load_sd((const double*)(from)) ; | ||||
|   res =  _mm_loadh_pd(res, (const double*)(from+2)) ; | ||||
|   return _mm_castpd_ps(res); | ||||
| #endif | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d ploadu<Packet2d>(const double* from) | ||||
| { | ||||
|   EIGEN_DEBUG_UNALIGNED_LOAD | ||||
| #if EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS | ||||
|   return _mm_loadu_pd(from); | ||||
| #else | ||||
|   __m128d res; | ||||
|   res = _mm_load_sd(from) ; | ||||
|   res = _mm_loadh_pd(res,from+1); | ||||
|   return res; | ||||
| #endif | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i ploadu<Packet4i>(const int* from) | ||||
| { | ||||
|   EIGEN_DEBUG_UNALIGNED_LOAD | ||||
| #if EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS | ||||
|   return _mm_loadu_si128(reinterpret_cast<const Packet4i*>(from)); | ||||
| #else | ||||
|   __m128d res; | ||||
|   res =  _mm_load_sd((const double*)(from)) ; | ||||
|   res =  _mm_loadh_pd(res, (const double*)(from+2)) ; | ||||
|   return _mm_castpd_si128(res); | ||||
| #endif | ||||
| } | ||||
| #endif | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f ploaddup<Packet4f>(const float*   from) | ||||
| { | ||||
|   return vec4f_swizzle1(_mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(from))), 0, 0, 1, 1); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d ploaddup<Packet2d>(const double*  from) | ||||
| { return pset1<Packet2d>(from[0]); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i ploaddup<Packet4i>(const int*     from) | ||||
| { | ||||
|   Packet4i tmp; | ||||
|   tmp = _mm_loadl_epi64(reinterpret_cast<const Packet4i*>(from)); | ||||
|   return vec4i_swizzle1(tmp, 0, 0, 1, 1); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE void pstore<float>(float*   to, const Packet4f& from) { EIGEN_DEBUG_ALIGNED_STORE _mm_store_ps(to, from); } | ||||
| template<> EIGEN_STRONG_INLINE void pstore<double>(double* to, const Packet2d& from) { EIGEN_DEBUG_ALIGNED_STORE _mm_store_pd(to, from); } | ||||
| template<> EIGEN_STRONG_INLINE void pstore<int>(int*       to, const Packet4i& from) { EIGEN_DEBUG_ALIGNED_STORE _mm_store_si128(reinterpret_cast<Packet4i*>(to), from); } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE void pstoreu<double>(double* to, const Packet2d& from) { | ||||
|   EIGEN_DEBUG_UNALIGNED_STORE | ||||
|   _mm_storel_pd((to), from); | ||||
|   _mm_storeh_pd((to+1), from); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE void pstoreu<float>(float*  to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu(reinterpret_cast<double*>(to), _mm_castps_pd(from)); } | ||||
| template<> EIGEN_STRONG_INLINE void pstoreu<int>(int*      to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu(reinterpret_cast<double*>(to), _mm_castsi128_pd(from)); } | ||||
|  | ||||
| // some compilers might be tempted to perform multiple moves instead of using a vector path. | ||||
| template<> EIGEN_STRONG_INLINE void pstore1<Packet4f>(float* to, const float& a) | ||||
| { | ||||
|   Packet4f pa = _mm_set_ss(a); | ||||
|   pstore(to, vec4f_swizzle1(pa,0,0,0,0)); | ||||
| } | ||||
| // some compilers might be tempted to perform multiple moves instead of using a vector path. | ||||
| template<> EIGEN_STRONG_INLINE void pstore1<Packet2d>(double* to, const double& a) | ||||
| { | ||||
|   Packet2d pa = _mm_set_sd(a); | ||||
|   pstore(to, vec2d_swizzle1(pa,0,0)); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE void prefetch<float>(const float*   addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } | ||||
| template<> EIGEN_STRONG_INLINE void prefetch<double>(const double* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } | ||||
| template<> EIGEN_STRONG_INLINE void prefetch<int>(const int*       addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } | ||||
|  | ||||
| #if defined(_MSC_VER) && defined(_WIN64) && !defined(__INTEL_COMPILER) | ||||
| // The temporary variable fixes an internal compilation error in vs <= 2008 and a wrong-result bug in vs 2010 | ||||
| // Direct of the struct members fixed bug #62. | ||||
| template<> EIGEN_STRONG_INLINE float  pfirst<Packet4f>(const Packet4f& a) { return a.m128_f32[0]; } | ||||
| template<> EIGEN_STRONG_INLINE double pfirst<Packet2d>(const Packet2d& a) { return a.m128d_f64[0]; } | ||||
| template<> EIGEN_STRONG_INLINE int    pfirst<Packet4i>(const Packet4i& a) { int x = _mm_cvtsi128_si32(a); return x; } | ||||
| #elif defined(_MSC_VER) && !defined(__INTEL_COMPILER) | ||||
| // The temporary variable fixes an internal compilation error in vs <= 2008 and a wrong-result bug in vs 2010 | ||||
| template<> EIGEN_STRONG_INLINE float  pfirst<Packet4f>(const Packet4f& a) { float x = _mm_cvtss_f32(a); return x; } | ||||
| template<> EIGEN_STRONG_INLINE double pfirst<Packet2d>(const Packet2d& a) { double x = _mm_cvtsd_f64(a); return x; } | ||||
| template<> EIGEN_STRONG_INLINE int    pfirst<Packet4i>(const Packet4i& a) { int x = _mm_cvtsi128_si32(a); return x; } | ||||
| #else | ||||
| template<> EIGEN_STRONG_INLINE float  pfirst<Packet4f>(const Packet4f& a) { return _mm_cvtss_f32(a); } | ||||
| template<> EIGEN_STRONG_INLINE double pfirst<Packet2d>(const Packet2d& a) { return _mm_cvtsd_f64(a); } | ||||
| template<> EIGEN_STRONG_INLINE int    pfirst<Packet4i>(const Packet4i& a) { return _mm_cvtsi128_si32(a); } | ||||
| #endif | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f preverse(const Packet4f& a) | ||||
| { return _mm_shuffle_ps(a,a,0x1B); } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d preverse(const Packet2d& a) | ||||
| { return _mm_shuffle_pd(a,a,0x1); } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i preverse(const Packet4i& a) | ||||
| { return _mm_shuffle_epi32(a,0x1B); } | ||||
|  | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f pabs(const Packet4f& a) | ||||
| { | ||||
|   const Packet4f mask = _mm_castsi128_ps(_mm_setr_epi32(0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF)); | ||||
|   return _mm_and_ps(a,mask); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d pabs(const Packet2d& a) | ||||
| { | ||||
|   const Packet2d mask = _mm_castsi128_pd(_mm_setr_epi32(0xFFFFFFFF,0x7FFFFFFF,0xFFFFFFFF,0x7FFFFFFF)); | ||||
|   return _mm_and_pd(a,mask); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet4i pabs(const Packet4i& a) | ||||
| { | ||||
|   #ifdef EIGEN_VECTORIZE_SSSE3 | ||||
|   return _mm_abs_epi32(a); | ||||
|   #else | ||||
|   Packet4i aux = _mm_srai_epi32(a,31); | ||||
|   return _mm_sub_epi32(_mm_xor_si128(a,aux),aux); | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| EIGEN_STRONG_INLINE void punpackp(Packet4f* vecs) | ||||
| { | ||||
|   vecs[1] = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(vecs[0]), 0x55)); | ||||
|   vecs[2] = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(vecs[0]), 0xAA)); | ||||
|   vecs[3] = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(vecs[0]), 0xFF)); | ||||
|   vecs[0] = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(vecs[0]), 0x00)); | ||||
| } | ||||
|  | ||||
| #ifdef EIGEN_VECTORIZE_SSE3 | ||||
| // TODO implement SSE2 versions as well as integer versions | ||||
| template<> EIGEN_STRONG_INLINE Packet4f preduxp<Packet4f>(const Packet4f* vecs) | ||||
| { | ||||
|   return _mm_hadd_ps(_mm_hadd_ps(vecs[0], vecs[1]),_mm_hadd_ps(vecs[2], vecs[3])); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE Packet2d preduxp<Packet2d>(const Packet2d* vecs) | ||||
| { | ||||
|   return _mm_hadd_pd(vecs[0], vecs[1]); | ||||
| } | ||||
| // SSSE3 version: | ||||
| // EIGEN_STRONG_INLINE Packet4i preduxp(const Packet4i* vecs) | ||||
| // { | ||||
| //   return _mm_hadd_epi32(_mm_hadd_epi32(vecs[0], vecs[1]),_mm_hadd_epi32(vecs[2], vecs[3])); | ||||
| // } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE float predux<Packet4f>(const Packet4f& a) | ||||
| { | ||||
|   Packet4f tmp0 = _mm_hadd_ps(a,a); | ||||
|   return pfirst(_mm_hadd_ps(tmp0, tmp0)); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE double predux<Packet2d>(const Packet2d& a) { return pfirst(_mm_hadd_pd(a, a)); } | ||||
|  | ||||
| // SSSE3 version: | ||||
| // EIGEN_STRONG_INLINE float predux(const Packet4i& a) | ||||
| // { | ||||
| //   Packet4i tmp0 = _mm_hadd_epi32(a,a); | ||||
| //   return pfirst(_mm_hadd_epi32(tmp0, tmp0)); | ||||
| // } | ||||
| #else | ||||
| // SSE2 versions | ||||
| template<> EIGEN_STRONG_INLINE float predux<Packet4f>(const Packet4f& a) | ||||
| { | ||||
|   Packet4f tmp = _mm_add_ps(a, _mm_movehl_ps(a,a)); | ||||
|   return pfirst(_mm_add_ss(tmp, _mm_shuffle_ps(tmp,tmp, 1))); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE double predux<Packet2d>(const Packet2d& a) | ||||
| { | ||||
|   return pfirst(_mm_add_sd(a, _mm_unpackhi_pd(a,a))); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4f preduxp<Packet4f>(const Packet4f* vecs) | ||||
| { | ||||
|   Packet4f tmp0, tmp1, tmp2; | ||||
|   tmp0 = _mm_unpacklo_ps(vecs[0], vecs[1]); | ||||
|   tmp1 = _mm_unpackhi_ps(vecs[0], vecs[1]); | ||||
|   tmp2 = _mm_unpackhi_ps(vecs[2], vecs[3]); | ||||
|   tmp0 = _mm_add_ps(tmp0, tmp1); | ||||
|   tmp1 = _mm_unpacklo_ps(vecs[2], vecs[3]); | ||||
|   tmp1 = _mm_add_ps(tmp1, tmp2); | ||||
|   tmp2 = _mm_movehl_ps(tmp1, tmp0); | ||||
|   tmp0 = _mm_movelh_ps(tmp0, tmp1); | ||||
|   return _mm_add_ps(tmp0, tmp2); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet2d preduxp<Packet2d>(const Packet2d* vecs) | ||||
| { | ||||
|   return _mm_add_pd(_mm_unpacklo_pd(vecs[0], vecs[1]), _mm_unpackhi_pd(vecs[0], vecs[1])); | ||||
| } | ||||
| #endif  // SSE3 | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE int predux<Packet4i>(const Packet4i& a) | ||||
| { | ||||
|   Packet4i tmp = _mm_add_epi32(a, _mm_unpackhi_epi64(a,a)); | ||||
|   return pfirst(tmp) + pfirst(_mm_shuffle_epi32(tmp, 1)); | ||||
| } | ||||
|  | ||||
| template<> EIGEN_STRONG_INLINE Packet4i preduxp<Packet4i>(const Packet4i* vecs) | ||||
| { | ||||
|   Packet4i tmp0, tmp1, tmp2; | ||||
|   tmp0 = _mm_unpacklo_epi32(vecs[0], vecs[1]); | ||||
|   tmp1 = _mm_unpackhi_epi32(vecs[0], vecs[1]); | ||||
|   tmp2 = _mm_unpackhi_epi32(vecs[2], vecs[3]); | ||||
|   tmp0 = _mm_add_epi32(tmp0, tmp1); | ||||
|   tmp1 = _mm_unpacklo_epi32(vecs[2], vecs[3]); | ||||
|   tmp1 = _mm_add_epi32(tmp1, tmp2); | ||||
|   tmp2 = _mm_unpacklo_epi64(tmp0, tmp1); | ||||
|   tmp0 = _mm_unpackhi_epi64(tmp0, tmp1); | ||||
|   return _mm_add_epi32(tmp0, tmp2); | ||||
| } | ||||
|  | ||||
| // Other reduction functions: | ||||
|  | ||||
| // mul | ||||
| template<> EIGEN_STRONG_INLINE float predux_mul<Packet4f>(const Packet4f& a) | ||||
| { | ||||
|   Packet4f tmp = _mm_mul_ps(a, _mm_movehl_ps(a,a)); | ||||
|   return pfirst(_mm_mul_ss(tmp, _mm_shuffle_ps(tmp,tmp, 1))); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE double predux_mul<Packet2d>(const Packet2d& a) | ||||
| { | ||||
|   return pfirst(_mm_mul_sd(a, _mm_unpackhi_pd(a,a))); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE int predux_mul<Packet4i>(const Packet4i& a) | ||||
| { | ||||
|   // after some experiments, it is seems this is the fastest way to implement it | ||||
|   // for GCC (eg., reusing pmul is very slow !) | ||||
|   // TODO try to call _mm_mul_epu32 directly | ||||
|   EIGEN_ALIGN16 int aux[4]; | ||||
|   pstore(aux, a); | ||||
|   return  (aux[0] * aux[1]) * (aux[2] * aux[3]);; | ||||
| } | ||||
|  | ||||
| // min | ||||
| template<> EIGEN_STRONG_INLINE float predux_min<Packet4f>(const Packet4f& a) | ||||
| { | ||||
|   Packet4f tmp = _mm_min_ps(a, _mm_movehl_ps(a,a)); | ||||
|   return pfirst(_mm_min_ss(tmp, _mm_shuffle_ps(tmp,tmp, 1))); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE double predux_min<Packet2d>(const Packet2d& a) | ||||
| { | ||||
|   return pfirst(_mm_min_sd(a, _mm_unpackhi_pd(a,a))); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE int predux_min<Packet4i>(const Packet4i& a) | ||||
| { | ||||
|   // after some experiments, it is seems this is the fastest way to implement it | ||||
|   // for GCC (eg., it does not like using std::min after the pstore !!) | ||||
|   EIGEN_ALIGN16 int aux[4]; | ||||
|   pstore(aux, a); | ||||
|   register int aux0 = aux[0]<aux[1] ? aux[0] : aux[1]; | ||||
|   register int aux2 = aux[2]<aux[3] ? aux[2] : aux[3]; | ||||
|   return aux0<aux2 ? aux0 : aux2; | ||||
| } | ||||
|  | ||||
| // max | ||||
| template<> EIGEN_STRONG_INLINE float predux_max<Packet4f>(const Packet4f& a) | ||||
| { | ||||
|   Packet4f tmp = _mm_max_ps(a, _mm_movehl_ps(a,a)); | ||||
|   return pfirst(_mm_max_ss(tmp, _mm_shuffle_ps(tmp,tmp, 1))); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE double predux_max<Packet2d>(const Packet2d& a) | ||||
| { | ||||
|   return pfirst(_mm_max_sd(a, _mm_unpackhi_pd(a,a))); | ||||
| } | ||||
| template<> EIGEN_STRONG_INLINE int predux_max<Packet4i>(const Packet4i& a) | ||||
| { | ||||
|   // after some experiments, it is seems this is the fastest way to implement it | ||||
|   // for GCC (eg., it does not like using std::min after the pstore !!) | ||||
|   EIGEN_ALIGN16 int aux[4]; | ||||
|   pstore(aux, a); | ||||
|   register int aux0 = aux[0]>aux[1] ? aux[0] : aux[1]; | ||||
|   register int aux2 = aux[2]>aux[3] ? aux[2] : aux[3]; | ||||
|   return aux0>aux2 ? aux0 : aux2; | ||||
| } | ||||
|  | ||||
| #if (defined __GNUC__) | ||||
| // template <> EIGEN_STRONG_INLINE Packet4f pmadd(const Packet4f&  a, const Packet4f&  b, const Packet4f&  c) | ||||
| // { | ||||
| //   Packet4f res = b; | ||||
| //   asm("mulps %[a], %[b] \n\taddps %[c], %[b]" : [b] "+x" (res) : [a] "x" (a), [c] "x" (c)); | ||||
| //   return res; | ||||
| // } | ||||
| // EIGEN_STRONG_INLINE Packet4i _mm_alignr_epi8(const Packet4i&  a, const Packet4i&  b, const int i) | ||||
| // { | ||||
| //   Packet4i res = a; | ||||
| //   asm("palignr %[i], %[a], %[b] " : [b] "+x" (res) : [a] "x" (a), [i] "i" (i)); | ||||
| //   return res; | ||||
| // } | ||||
| #endif | ||||
|  | ||||
| #ifdef EIGEN_VECTORIZE_SSSE3 | ||||
| // SSSE3 versions | ||||
| template<int Offset> | ||||
| struct palign_impl<Offset,Packet4f> | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Packet4f& first, const Packet4f& second) | ||||
|   { | ||||
|     if (Offset!=0) | ||||
|       first = _mm_castsi128_ps(_mm_alignr_epi8(_mm_castps_si128(second), _mm_castps_si128(first), Offset*4)); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<int Offset> | ||||
| struct palign_impl<Offset,Packet4i> | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Packet4i& first, const Packet4i& second) | ||||
|   { | ||||
|     if (Offset!=0) | ||||
|       first = _mm_alignr_epi8(second,first, Offset*4); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<int Offset> | ||||
| struct palign_impl<Offset,Packet2d> | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Packet2d& first, const Packet2d& second) | ||||
|   { | ||||
|     if (Offset==1) | ||||
|       first = _mm_castsi128_pd(_mm_alignr_epi8(_mm_castpd_si128(second), _mm_castpd_si128(first), 8)); | ||||
|   } | ||||
| }; | ||||
| #else | ||||
| // SSE2 versions | ||||
| template<int Offset> | ||||
| struct palign_impl<Offset,Packet4f> | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Packet4f& first, const Packet4f& second) | ||||
|   { | ||||
|     if (Offset==1) | ||||
|     { | ||||
|       first = _mm_move_ss(first,second); | ||||
|       first = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(first),0x39)); | ||||
|     } | ||||
|     else if (Offset==2) | ||||
|     { | ||||
|       first = _mm_movehl_ps(first,first); | ||||
|       first = _mm_movelh_ps(first,second); | ||||
|     } | ||||
|     else if (Offset==3) | ||||
|     { | ||||
|       first = _mm_move_ss(first,second); | ||||
|       first = _mm_shuffle_ps(first,second,0x93); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<int Offset> | ||||
| struct palign_impl<Offset,Packet4i> | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Packet4i& first, const Packet4i& second) | ||||
|   { | ||||
|     if (Offset==1) | ||||
|     { | ||||
|       first = _mm_castps_si128(_mm_move_ss(_mm_castsi128_ps(first),_mm_castsi128_ps(second))); | ||||
|       first = _mm_shuffle_epi32(first,0x39); | ||||
|     } | ||||
|     else if (Offset==2) | ||||
|     { | ||||
|       first = _mm_castps_si128(_mm_movehl_ps(_mm_castsi128_ps(first),_mm_castsi128_ps(first))); | ||||
|       first = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(first),_mm_castsi128_ps(second))); | ||||
|     } | ||||
|     else if (Offset==3) | ||||
|     { | ||||
|       first = _mm_castps_si128(_mm_move_ss(_mm_castsi128_ps(first),_mm_castsi128_ps(second))); | ||||
|       first = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(first),_mm_castsi128_ps(second),0x93)); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<int Offset> | ||||
| struct palign_impl<Offset,Packet2d> | ||||
| { | ||||
|   static EIGEN_STRONG_INLINE void run(Packet2d& first, const Packet2d& second) | ||||
|   { | ||||
|     if (Offset==1) | ||||
|     { | ||||
|       first = _mm_castps_pd(_mm_movehl_ps(_mm_castpd_ps(first),_mm_castpd_ps(first))); | ||||
|       first = _mm_castps_pd(_mm_movelh_ps(_mm_castpd_ps(first),_mm_castpd_ps(second))); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_PACKET_MATH_SSE_H | ||||
							
								
								
									
										441
									
								
								latan/Eigen/src/Core/products/CoeffBasedProduct.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										441
									
								
								latan/Eigen/src/Core/products/CoeffBasedProduct.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,441 @@ | ||||
| // This file is part of Eigen, a lightweight C++ template library | ||||
| // for linear algebra. | ||||
| // | ||||
| // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> | ||||
| // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | ||||
| // | ||||
| // This Source Code Form is subject to the terms of the Mozilla | ||||
| // Public License v. 2.0. If a copy of the MPL was not distributed | ||||
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  | ||||
| #ifndef EIGEN_COEFFBASED_PRODUCT_H | ||||
| #define EIGEN_COEFFBASED_PRODUCT_H | ||||
|  | ||||
| namespace Eigen {  | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| /********************************************************************************* | ||||
| *  Coefficient based product implementation. | ||||
| *  It is designed for the following use cases: | ||||
| *  - small fixed sizes | ||||
| *  - lazy products | ||||
| *********************************************************************************/ | ||||
|  | ||||
| /* Since the all the dimensions of the product are small, here we can rely | ||||
|  * on the generic Assign mechanism to evaluate the product per coeff (or packet). | ||||
|  * | ||||
|  * Note that here the inner-loops should always be unrolled. | ||||
|  */ | ||||
|  | ||||
| template<int Traversal, int UnrollingIndex, typename Lhs, typename Rhs, typename RetScalar> | ||||
| struct product_coeff_impl; | ||||
|  | ||||
| template<int StorageOrder, int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode> | ||||
| struct product_packet_impl; | ||||
|  | ||||
| template<typename LhsNested, typename RhsNested, int NestingFlags> | ||||
| struct traits<CoeffBasedProduct<LhsNested,RhsNested,NestingFlags> > | ||||
| { | ||||
|   typedef MatrixXpr XprKind; | ||||
|   typedef typename remove_all<LhsNested>::type _LhsNested; | ||||
|   typedef typename remove_all<RhsNested>::type _RhsNested; | ||||
|   typedef typename scalar_product_traits<typename _LhsNested::Scalar, typename _RhsNested::Scalar>::ReturnType Scalar; | ||||
|   typedef typename promote_storage_type<typename traits<_LhsNested>::StorageKind, | ||||
|                                            typename traits<_RhsNested>::StorageKind>::ret StorageKind; | ||||
|   typedef typename promote_index_type<typename traits<_LhsNested>::Index, | ||||
|                                          typename traits<_RhsNested>::Index>::type Index; | ||||
|  | ||||
|   enum { | ||||
|       LhsCoeffReadCost = _LhsNested::CoeffReadCost, | ||||
|       RhsCoeffReadCost = _RhsNested::CoeffReadCost, | ||||
|       LhsFlags = _LhsNested::Flags, | ||||
|       RhsFlags = _RhsNested::Flags, | ||||
|  | ||||
|       RowsAtCompileTime = _LhsNested::RowsAtCompileTime, | ||||
|       ColsAtCompileTime = _RhsNested::ColsAtCompileTime, | ||||
|       InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime), | ||||
|  | ||||
|       MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime, | ||||
|       MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime, | ||||
|  | ||||
|       LhsRowMajor = LhsFlags & RowMajorBit, | ||||
|       RhsRowMajor = RhsFlags & RowMajorBit, | ||||
|  | ||||
|       SameType = is_same<typename _LhsNested::Scalar,typename _RhsNested::Scalar>::value, | ||||
|  | ||||
|       CanVectorizeRhs = RhsRowMajor && (RhsFlags & PacketAccessBit) | ||||
|                       && (ColsAtCompileTime == Dynamic | ||||
|                           || ( (ColsAtCompileTime % packet_traits<Scalar>::size) == 0 | ||||
|                               && (RhsFlags&AlignedBit) | ||||
|                              ) | ||||
|                          ), | ||||
|  | ||||
|       CanVectorizeLhs = (!LhsRowMajor) && (LhsFlags & PacketAccessBit) | ||||
|                       && (RowsAtCompileTime == Dynamic | ||||
|                           || ( (RowsAtCompileTime % packet_traits<Scalar>::size) == 0 | ||||
|                               && (LhsFlags&AlignedBit) | ||||
|                              ) | ||||
|                          ), | ||||
|  | ||||
|       EvalToRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1 | ||||
|                      : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0 | ||||
|                      : (RhsRowMajor && !CanVectorizeLhs), | ||||
|  | ||||
|       Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & ~RowMajorBit) | ||||
|             | (EvalToRowMajor ? RowMajorBit : 0) | ||||
|             | NestingFlags | ||||
|             | (LhsFlags & RhsFlags & AlignedBit) | ||||
|             // TODO enable vectorization for mixed types | ||||
|             | (SameType && (CanVectorizeLhs || CanVectorizeRhs) ? PacketAccessBit : 0), | ||||
|  | ||||
|       CoeffReadCost = InnerSize == Dynamic ? Dynamic | ||||
|                     : InnerSize * (NumTraits<Scalar>::MulCost + LhsCoeffReadCost + RhsCoeffReadCost) | ||||
|                       + (InnerSize - 1) * NumTraits<Scalar>::AddCost, | ||||
|  | ||||
|       /* CanVectorizeInner deserves special explanation. It does not affect the product flags. It is not used outside | ||||
|       * of Product. If the Product itself is not a packet-access expression, there is still a chance that the inner | ||||
|       * loop of the product might be vectorized. This is the meaning of CanVectorizeInner. Since it doesn't affect | ||||
|       * the Flags, it is safe to make this value depend on ActualPacketAccessBit, that doesn't affect the ABI. | ||||
|       */ | ||||
|       CanVectorizeInner =    SameType | ||||
|                           && LhsRowMajor | ||||
|                           && (!RhsRowMajor) | ||||
|                           && (LhsFlags & RhsFlags & ActualPacketAccessBit) | ||||
|                           && (LhsFlags & RhsFlags & AlignedBit) | ||||
|                           && (InnerSize % packet_traits<Scalar>::size == 0) | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| template<typename LhsNested, typename RhsNested, int NestingFlags> | ||||
| class CoeffBasedProduct | ||||
|   : internal::no_assignment_operator, | ||||
|     public MatrixBase<CoeffBasedProduct<LhsNested, RhsNested, NestingFlags> > | ||||
| { | ||||
|   public: | ||||
|  | ||||
|     typedef MatrixBase<CoeffBasedProduct> Base; | ||||
|     EIGEN_DENSE_PUBLIC_INTERFACE(CoeffBasedProduct) | ||||
|     typedef typename Base::PlainObject PlainObject; | ||||
|  | ||||
|   private: | ||||
|  | ||||
|     typedef typename internal::traits<CoeffBasedProduct>::_LhsNested _LhsNested; | ||||
|     typedef typename internal::traits<CoeffBasedProduct>::_RhsNested _RhsNested; | ||||
|  | ||||
|     enum { | ||||
|       PacketSize = internal::packet_traits<Scalar>::size, | ||||
|       InnerSize  = internal::traits<CoeffBasedProduct>::InnerSize, | ||||
|       Unroll = CoeffReadCost != Dynamic && CoeffReadCost <= EIGEN_UNROLLING_LIMIT, | ||||
|       CanVectorizeInner = internal::traits<CoeffBasedProduct>::CanVectorizeInner | ||||
|     }; | ||||
|  | ||||
|     typedef internal::product_coeff_impl<CanVectorizeInner ? InnerVectorizedTraversal : DefaultTraversal, | ||||
|                                    Unroll ? InnerSize-1 : Dynamic, | ||||
|                                    _LhsNested, _RhsNested, Scalar> ScalarCoeffImpl; | ||||
|  | ||||
|     typedef CoeffBasedProduct<LhsNested,RhsNested,NestByRefBit> LazyCoeffBasedProductType; | ||||
|  | ||||
|   public: | ||||
|  | ||||
|     inline CoeffBasedProduct(const CoeffBasedProduct& other) | ||||
|       : Base(), m_lhs(other.m_lhs), m_rhs(other.m_rhs) | ||||
|     {} | ||||
|  | ||||
|     template<typename Lhs, typename Rhs> | ||||
|     inline CoeffBasedProduct(const Lhs& lhs, const Rhs& rhs) | ||||
|       : m_lhs(lhs), m_rhs(rhs) | ||||
|     { | ||||
|       // we don't allow taking products of matrices of different real types, as that wouldn't be vectorizable. | ||||
|       // We still allow to mix T and complex<T>. | ||||
|       EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::RealScalar, typename Rhs::RealScalar>::value), | ||||
|         YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) | ||||
|       eigen_assert(lhs.cols() == rhs.rows() | ||||
|         && "invalid matrix product" | ||||
|         && "if you wanted a coeff-wise or a dot product use the respective explicit functions"); | ||||
|     } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); } | ||||
|     EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); } | ||||
|  | ||||
|     EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const | ||||
|     { | ||||
|       Scalar res; | ||||
|       ScalarCoeffImpl::run(row, col, m_lhs, m_rhs, res); | ||||
|       return res; | ||||
|     } | ||||
|  | ||||
|     /* Allow index-based non-packet access. It is impossible though to allow index-based packed access, | ||||
|      * which is why we don't set the LinearAccessBit. | ||||
|      */ | ||||
|     EIGEN_STRONG_INLINE const Scalar coeff(Index index) const | ||||
|     { | ||||
|       Scalar res; | ||||
|       const Index row = RowsAtCompileTime == 1 ? 0 : index; | ||||
|       const Index col = RowsAtCompileTime == 1 ? index : 0; | ||||
|       ScalarCoeffImpl::run(row, col, m_lhs, m_rhs, res); | ||||
|       return res; | ||||
|     } | ||||
|  | ||||
|     template<int LoadMode> | ||||
|     EIGEN_STRONG_INLINE const PacketScalar packet(Index row, Index col) const | ||||
|     { | ||||
|       PacketScalar res; | ||||
|       internal::product_packet_impl<Flags&RowMajorBit ? RowMajor : ColMajor, | ||||
|                               Unroll ? InnerSize-1 : Dynamic, | ||||
|                               _LhsNested, _RhsNested, PacketScalar, LoadMode> | ||||
|         ::run(row, col, m_lhs, m_rhs, res); | ||||
|       return res; | ||||
|     } | ||||
|  | ||||
|     // Implicit conversion to the nested type (trigger the evaluation of the product) | ||||
|     EIGEN_STRONG_INLINE operator const PlainObject& () const | ||||
|     { | ||||
|       m_result.lazyAssign(*this); | ||||
|       return m_result; | ||||
|     } | ||||
|  | ||||
|     const _LhsNested& lhs() const { return m_lhs; } | ||||
|     const _RhsNested& rhs() const { return m_rhs; } | ||||
|  | ||||
|     const Diagonal<const LazyCoeffBasedProductType,0> diagonal() const | ||||
|     { return reinterpret_cast<const LazyCoeffBasedProductType&>(*this); } | ||||
|  | ||||
|     template<int DiagonalIndex> | ||||
|     const Diagonal<const LazyCoeffBasedProductType,DiagonalIndex> diagonal() const | ||||
|     { return reinterpret_cast<const LazyCoeffBasedProductType&>(*this); } | ||||
|  | ||||
|     const Diagonal<const LazyCoeffBasedProductType,Dynamic> diagonal(Index index) const | ||||
|     { return reinterpret_cast<const LazyCoeffBasedProductType&>(*this).diagonal(index); } | ||||
|  | ||||
|   protected: | ||||
|     typename internal::add_const_on_value_type<LhsNested>::type m_lhs; | ||||
|     typename internal::add_const_on_value_type<RhsNested>::type m_rhs; | ||||
|  | ||||
|     mutable PlainObject m_result; | ||||
| }; | ||||
|  | ||||
| namespace internal { | ||||
|  | ||||
| // here we need to overload the nested rule for products | ||||
| // such that the nested type is a const reference to a plain matrix | ||||
| template<typename Lhs, typename Rhs, int N, typename PlainObject> | ||||
| struct nested<CoeffBasedProduct<Lhs,Rhs,EvalBeforeNestingBit|EvalBeforeAssigningBit>, N, PlainObject> | ||||
| { | ||||
|   typedef PlainObject const& type; | ||||
| }; | ||||
|  | ||||
| /*************************************************************************** | ||||
| * Normal product .coeff() implementation (with meta-unrolling) | ||||
| ***************************************************************************/ | ||||
|  | ||||
| /************************************** | ||||
| *** Scalar path  - no vectorization *** | ||||
| **************************************/ | ||||
|  | ||||
| template<int UnrollingIndex, typename Lhs, typename Rhs, typename RetScalar> | ||||
| struct product_coeff_impl<DefaultTraversal, UnrollingIndex, Lhs, Rhs, RetScalar> | ||||
| { | ||||
|   typedef typename Lhs::Index Index; | ||||
|   static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) | ||||
|   { | ||||
|     product_coeff_impl<DefaultTraversal, UnrollingIndex-1, Lhs, Rhs, RetScalar>::run(row, col, lhs, rhs, res); | ||||
|     res += lhs.coeff(row, UnrollingIndex) * rhs.coeff(UnrollingIndex, col); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Lhs, typename Rhs, typename RetScalar> | ||||
| struct product_coeff_impl<DefaultTraversal, 0, Lhs, Rhs, RetScalar> | ||||
| { | ||||
|   typedef typename Lhs::Index Index; | ||||
|   static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) | ||||
|   { | ||||
|     res = lhs.coeff(row, 0) * rhs.coeff(0, col); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Lhs, typename Rhs, typename RetScalar> | ||||
| struct product_coeff_impl<DefaultTraversal, Dynamic, Lhs, Rhs, RetScalar> | ||||
| { | ||||
|   typedef typename Lhs::Index Index; | ||||
|   static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar& res) | ||||
|   { | ||||
|     eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix"); | ||||
|     res = lhs.coeff(row, 0) * rhs.coeff(0, col); | ||||
|       for(Index i = 1; i < lhs.cols(); ++i) | ||||
|         res += lhs.coeff(row, i) * rhs.coeff(i, col); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /******************************************* | ||||
| *** Scalar path with inner vectorization *** | ||||
| *******************************************/ | ||||
|  | ||||
| template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet> | ||||
| struct product_coeff_vectorized_unroller | ||||
| { | ||||
|   typedef typename Lhs::Index Index; | ||||
|   enum { PacketSize = packet_traits<typename Lhs::Scalar>::size }; | ||||
|   static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres) | ||||
|   { | ||||
|     product_coeff_vectorized_unroller<UnrollingIndex-PacketSize, Lhs, Rhs, Packet>::run(row, col, lhs, rhs, pres); | ||||
|     pres = padd(pres, pmul( lhs.template packet<Aligned>(row, UnrollingIndex) , rhs.template packet<Aligned>(UnrollingIndex, col) )); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Lhs, typename Rhs, typename Packet> | ||||
| struct product_coeff_vectorized_unroller<0, Lhs, Rhs, Packet> | ||||
| { | ||||
|   typedef typename Lhs::Index Index; | ||||
|   static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres) | ||||
|   { | ||||
|     pres = pmul(lhs.template packet<Aligned>(row, 0) , rhs.template packet<Aligned>(0, col)); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<int UnrollingIndex, typename Lhs, typename Rhs, typename RetScalar> | ||||
| struct product_coeff_impl<InnerVectorizedTraversal, UnrollingIndex, Lhs, Rhs, RetScalar> | ||||
| { | ||||
|   typedef typename Lhs::PacketScalar Packet; | ||||
|   typedef typename Lhs::Index Index; | ||||
|   enum { PacketSize = packet_traits<typename Lhs::Scalar>::size }; | ||||
|   static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) | ||||
|   { | ||||
|     Packet pres; | ||||
|     product_coeff_vectorized_unroller<UnrollingIndex+1-PacketSize, Lhs, Rhs, Packet>::run(row, col, lhs, rhs, pres); | ||||
|     product_coeff_impl<DefaultTraversal,UnrollingIndex,Lhs,Rhs,RetScalar>::run(row, col, lhs, rhs, res); | ||||
|     res = predux(pres); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Lhs, typename Rhs, int LhsRows = Lhs::RowsAtCompileTime, int RhsCols = Rhs::ColsAtCompileTime> | ||||
| struct product_coeff_vectorized_dyn_selector | ||||
| { | ||||
|   typedef typename Lhs::Index Index; | ||||
|   static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) | ||||
|   { | ||||
|     res = lhs.row(row).transpose().cwiseProduct(rhs.col(col)).sum(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // NOTE the 3 following specializations are because taking .col(0) on a vector is a bit slower | ||||
| // NOTE maybe they are now useless since we have a specialization for Block<Matrix> | ||||
| template<typename Lhs, typename Rhs, int RhsCols> | ||||
| struct product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,RhsCols> | ||||
| { | ||||
|   typedef typename Lhs::Index Index; | ||||
|   static EIGEN_STRONG_INLINE void run(Index /*row*/, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) | ||||
|   { | ||||
|     res = lhs.transpose().cwiseProduct(rhs.col(col)).sum(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Lhs, typename Rhs, int LhsRows> | ||||
| struct product_coeff_vectorized_dyn_selector<Lhs,Rhs,LhsRows,1> | ||||
| { | ||||
|   typedef typename Lhs::Index Index; | ||||
|   static EIGEN_STRONG_INLINE void run(Index row, Index /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) | ||||
|   { | ||||
|     res = lhs.row(row).transpose().cwiseProduct(rhs).sum(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Lhs, typename Rhs> | ||||
| struct product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,1> | ||||
| { | ||||
|   typedef typename Lhs::Index Index; | ||||
|   static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) | ||||
|   { | ||||
|     res = lhs.transpose().cwiseProduct(rhs).sum(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Lhs, typename Rhs, typename RetScalar> | ||||
| struct product_coeff_impl<InnerVectorizedTraversal, Dynamic, Lhs, Rhs, RetScalar> | ||||
| { | ||||
|   typedef typename Lhs::Index Index; | ||||
|   static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) | ||||
|   { | ||||
|     product_coeff_vectorized_dyn_selector<Lhs,Rhs>::run(row, col, lhs, rhs, res); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /******************* | ||||
| *** Packet path  *** | ||||
| *******************/ | ||||
|  | ||||
| template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode> | ||||
| struct product_packet_impl<RowMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode> | ||||
| { | ||||
|   typedef typename Lhs::Index Index; | ||||
|   static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) | ||||
|   { | ||||
|     product_packet_impl<RowMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, res); | ||||
|     res =  pmadd(pset1<Packet>(lhs.coeff(row, UnrollingIndex)), rhs.template packet<LoadMode>(UnrollingIndex, col), res); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode> | ||||
| struct product_packet_impl<ColMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode> | ||||
| { | ||||
|   typedef typename Lhs::Index Index; | ||||
|   static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) | ||||
|   { | ||||
|     product_packet_impl<ColMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, res); | ||||
|     res =  pmadd(lhs.template packet<LoadMode>(row, UnrollingIndex), pset1<Packet>(rhs.coeff(UnrollingIndex, col)), res); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Lhs, typename Rhs, typename Packet, int LoadMode> | ||||
| struct product_packet_impl<RowMajor, 0, Lhs, Rhs, Packet, LoadMode> | ||||
| { | ||||
|   typedef typename Lhs::Index Index; | ||||
|   static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) | ||||
|   { | ||||
|     res = pmul(pset1<Packet>(lhs.coeff(row, 0)),rhs.template packet<LoadMode>(0, col)); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Lhs, typename Rhs, typename Packet, int LoadMode> | ||||
| struct product_packet_impl<ColMajor, 0, Lhs, Rhs, Packet, LoadMode> | ||||
| { | ||||
|   typedef typename Lhs::Index Index; | ||||
|   static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) | ||||
|   { | ||||
|     res = pmul(lhs.template packet<LoadMode>(row, 0), pset1<Packet>(rhs.coeff(0, col))); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Lhs, typename Rhs, typename Packet, int LoadMode> | ||||
| struct product_packet_impl<RowMajor, Dynamic, Lhs, Rhs, Packet, LoadMode> | ||||
| { | ||||
|   typedef typename Lhs::Index Index; | ||||
|   static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res) | ||||
|   { | ||||
|     eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix"); | ||||
|     res = pmul(pset1<Packet>(lhs.coeff(row, 0)),rhs.template packet<LoadMode>(0, col)); | ||||
|       for(Index i = 1; i < lhs.cols(); ++i) | ||||
|         res =  pmadd(pset1<Packet>(lhs.coeff(row, i)), rhs.template packet<LoadMode>(i, col), res); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename Lhs, typename Rhs, typename Packet, int LoadMode> | ||||
| struct product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, Packet, LoadMode> | ||||
| { | ||||
|   typedef typename Lhs::Index Index; | ||||
|   static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res) | ||||
|   { | ||||
|     eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix"); | ||||
|     res = pmul(lhs.template packet<LoadMode>(row, 0), pset1<Packet>(rhs.coeff(0, col))); | ||||
|       for(Index i = 1; i < lhs.cols(); ++i) | ||||
|         res =  pmadd(lhs.template packet<LoadMode>(row, i), pset1<Packet>(rhs.coeff(i, col)), res); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| } // end namespace internal | ||||
|  | ||||
| } // end namespace Eigen | ||||
|  | ||||
| #endif // EIGEN_COEFFBASED_PRODUCT_H | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user