Compare commits

...

2811 Commits

Author SHA1 Message Date
Benoit Jacob
77fc6a9914 bump 2011-02-28 00:55:52 -05:00
Benoit Jacob
eef03525b8 fix bug #203: revert to using _mm_set1_p[sd] 2011-02-28 00:04:05 -05:00
Benoit Jacob
31621ff0ef relax condition in matrix_exponential test for clang 2011-02-27 23:25:14 -05:00
Benoit Jacob
0b44893b4e fix umeyama test 2011-02-27 23:20:45 -05:00
Benoit Jacob
8cad73072e fix stable_norm test: the |small| value was 0 on clang with complex<float>. 2011-02-27 22:35:49 -05:00
Benoit Jacob
9be2712bf7 remove now-useless comments 2011-02-27 22:35:17 -05:00
Benoit Jacob
0612768c1c fix bug #201: Clang too has intrinsics bugs preventing us to use custom unaligned loads 2011-02-27 21:59:07 -05:00
Benoit Jacob
32025a2510 disable BVH test on Clang++. Looks like there's a good reason why BVH is unsupported. It seems to have a very weird usage pattern, relying on an externally defined bounding_box function in a naive way. 2011-02-27 21:37:34 -05:00
Benoit Jacob
771e64200f fix compilation of unit tests with clang 2011-02-27 20:33:58 -05:00
Benoit Jacob
4846c76d9d shut up a stupid clang 2.8 warning 2011-02-27 20:18:03 -05:00
Benoit Jacob
afc9efca15 fix compilation with clang 2.8 2011-02-27 20:17:47 -05:00
Benoit Jacob
ea7d872181 documentation fixes 2011-02-27 17:43:10 -05:00
Benoit Jacob
b6299c974f add option to build in 32bit mode 2011-02-27 17:27:23 -05:00
Benoit Jacob
b3544ce2ae bug #195 - fix this once and for all: just never use _mm_load_sd on gcc/i386, it generates redundant x87 ops 2011-02-27 17:26:59 -05:00
Jitse Niesen
a8f5ef9388 Document (non)sorting of eigenvalues.
Also, update docs for (Generalized)SelfAdjointEigenSolver to reflect that these
two classes were split apart.
2011-02-27 14:06:55 +00:00
Jitse Niesen
58abf0eb98 Use absolute error to test sum in which cancellation may occur. 2011-02-25 08:56:37 +00:00
Gael Guennebaud
ef73265987 to ease debugging let's catch invalid template options in Transform 2011-02-25 09:03:24 +01:00
Gael Guennebaud
4fbd78d993 fix compilation with gcc 3.4 2011-02-25 09:02:15 +01:00
Benoit Jacob
5dfae4524b fix bug #195: fast unaligned load for integer using _mm_load_sd failed when the value interpreted as a NaN 2011-02-24 10:31:57 -05:00
Hauke Heibel
2064c59878 Improved docs of PlainObjectBase::conservativeResize methods. 2011-02-24 15:48:41 +01:00
Gael Guennebaud
bb9a465c5a fix AltiVec ploaddup 2011-02-24 00:23:50 +03:00
Gael Guennebaud
28d17c5390 bounds the range of random integers for AltiVec 2011-02-24 00:22:53 +03:00
Gael Guennebaud
4bfe38eda2 extend testing of ploaddup 2011-02-24 00:22:10 +03:00
Gael Guennebaud
23aae0d63e fix pset1 for complex 2011-02-23 21:24:47 +03:00
Gael Guennebaud
0dfea7fce4 improve packetmath unit test 2011-02-23 21:24:26 +03:00
Gael Guennebaud
c121e6f390 implement ploaddup for complex and SSE/NEON even though they are not used in practice 2011-02-23 16:31:42 +01:00
Gael Guennebaud
955c099eb5 implement ploaddup for altivec and add respective unit test 2011-02-23 18:20:55 +03:00
Gael Guennebaud
a00aaf7f7e fix overflow in packetmath unit test 2011-02-23 17:57:18 +03:00
Gael Guennebaud
6e01780541 fix a couple of issues with pcplxflip 2011-02-23 17:51:40 +03:00
Gael Guennebaud
939f0327b6 mention reverse and replicate in the quick ref 2011-02-23 15:31:16 +01:00
Gael Guennebaud
78e1a62c54 implement pcplxflip for altivec 2011-02-23 14:20:58 +01:00
Gael Guennebaud
59eeb67187 add unit test for pcplxflip 2011-02-23 14:20:33 +01:00
Gael Guennebaud
b8374aec00 implement workarounds for MSVC IDEs and the Experimental target 2011-02-23 11:53:20 +01:00
Gael Guennebaud
7dc18b20bb same for neon 2011-02-23 09:41:55 +01:00
Gael Guennebaud
32e7dae776 Altivec: fix infinite loop (ei_ -> internal:: change) 2011-02-23 09:41:02 +01:00
Gael Guennebaud
9ab503903e suppress unused warning 2011-02-23 09:32:55 +01:00
Gael Guennebaud
14b164b00e do not try to use Eigen's blas/lapack if they cannot be compiled 2011-02-23 09:25:32 +01:00
Gael Guennebaud
c78b5fd9aa fix no newline warning 2011-02-23 09:23:11 +01:00
Gael Guennebaud
2fb5567e08 add missing AlignedOnScalar 2011-02-22 21:25:47 +01:00
Benoit Jacob
3df134dec2 fix icc warning #68 2011-02-22 10:11:03 -05:00
Benoit Jacob
c58a2ff03a add EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS non-default option. Use it in our own CMakeLists. also add a include-guard-like mechanism to prevent doing unmatched #pragma warning push/pop. 2011-02-22 10:05:41 -05:00
Benoit Jacob
9e1127619c merge 2011-02-22 09:33:01 -05:00
Benoit Jacob
720767ae40 ICC 12 / linux only defined __INTEL_COMPILER, not __intel_compiler 2011-02-22 09:32:39 -05:00
Benoit Jacob
d8e97aee89 shut up stupid ICC warnings 2011-02-22 09:31:22 -05:00
Benoit Jacob
625814464e fix legitimate ICC 12 warning 2011-02-22 09:30:54 -05:00
Gael Guennebaud
39b27fb656 altivec compilation fix 2011-02-22 15:26:28 +01:00
Benoit Jacob
25579df2d4 'fix' a couple of clang -Wconstant-logical-operand warnings (still not convinced about the pertinence of that warning) 2011-02-22 08:54:55 -05:00
Benoit Jacob
3884308da7 __attribute__((flatten)) seems to be recognized by neither clang nor icc despite these compilers defining __GNUC__. 2011-02-22 08:40:37 -05:00
Gael Guennebaud
68631e28d4 also test non_projective_only with row major transformations 2011-02-22 14:26:32 +01:00
Benoit Jacob
39d3bc2394 fix bug #190: directly pass Transform Options to Matrix, allowing to use RowMajor. Fix issues in Transform with non-default Options. 2011-02-22 08:14:38 -05:00
Gael Guennebaud
659c97ee49 gcc 4.4 also defines float32_t as a special type 2011-02-22 10:04:09 +01:00
Gael Guennebaud
769eeac35e disable output compression since this feature seems to be broken 2011-02-21 21:19:38 +01:00
Gael Guennebaud
51da67f211 more compilation fixes for altivec 2011-02-21 20:36:20 +01:00
Gael Guennebaud
05545d0197 fix compilation 2011-02-21 17:47:31 +01:00
Gael Guennebaud
8bee573a78 workaround ICC aggressive optimization 2011-02-21 16:17:58 +01:00
Gael Guennebaud
fb1a29fed5 fix ICE and warning with gcc 4.2.4 2011-02-21 16:11:18 +01:00
Gael Guennebaud
e129e985c3 link to blas/lapack only when needed, and use the static versions to hopefully workaround weird linking issues to gfortranbegin (see jitse dashboard) 2011-02-21 15:48:37 +01:00
Gael Guennebaud
2d5ea82807 fix bug #176 (workaround a too aggressive optimization made by ICC) 2011-02-21 11:00:07 +01:00
Gael Guennebaud
3c00e3da03 enable some tests that have been commented out 2011-02-18 18:08:58 +01:00
Gael Guennebaud
434817164e fix umfpack with complexes 2011-02-18 18:07:59 +01:00
Gael Guennebaud
2c1ac23c62 remove unused code 2011-02-18 17:54:48 +01:00
Gael Guennebaud
a0e5b00280 forgot that one, again 2011-02-18 17:50:36 +01:00
Gael Guennebaud
6456b74a89 merge 2011-02-18 17:40:31 +01:00
Gael Guennebaud
86ca05b324 remove largeEps in adjoint unit test and use a more accurate test_isApproxWithRef test. 2011-02-18 17:39:04 +01:00
Gael Guennebaud
8f8c67b8bd fix bug #186 (in 32 bits mode, gcc 4.3 messed up with pfirst for complex<float>) 2011-02-18 15:47:17 +01:00
Benoit Jacob
aa966ca319 fix bug #187: stable norm test was quite broken 2011-02-18 09:46:49 -05:00
Gael Guennebaud
f7cd63b964 fix bug #189 (issue with fortran concentions to return COMPLEX values) 2011-02-18 15:11:31 +01:00
Gael Guennebaud
69cecc45e5 extend mapstride unit test to test unaligned configurations 2011-02-18 14:41:40 +01:00
Gael Guennebaud
abce49ea21 fix a segfault in "slice vectorization" when the destination might not be aligned on a scalar (complex<double>) 2011-02-18 14:20:36 +01:00
Gael Guennebaud
d271ad38ce back to brute force linking to sparse libraries (fix cmake when these libs are not found) 2011-02-18 11:35:45 +01:00
Gael Guennebaud
3e2314dd67 forgot to include this file in previous commit (needed for lapack) 2011-02-18 11:32:39 +01:00
Gael Guennebaud
444c1bc55b now cholmod, umfpack, and superlu uses our own BLAS and LAPACK libs 2011-02-18 11:26:31 +01:00
Gael Guennebaud
390724b4b6 add lapack interface to real symmetric eigenvalue dec and enable building of the lapack shared library 2011-02-18 11:25:04 +01:00
Gael Guennebaud
d8ca948148 it is now up to user of these Find* module to find and link to BLAS and/or LAPACK 2011-02-18 11:23:27 +01:00
Gael Guennebaud
3345ea0ddd clean a bit SuperLU declarations 2011-02-18 10:23:32 +01:00
Gael Guennebaud
9195a224f3 fix division by zero if the matrix is exactly zero 2011-02-17 19:39:57 +01:00
Gael Guennebaud
b8ef48c46d for consistency forward declare tan, asin, acos functors 2011-02-17 18:23:04 +01:00
Gael Guennebaud
a53a7d6e6a use C linkage for umfpack (might fix some linking issues) 2011-02-17 18:19:28 +01:00
Gael Guennebaud
eda59ffc1b mention std::ptr_fun in the quickref guide 2011-02-17 18:07:21 +01:00
Gael Guennebaud
6f86c12339 typo 2011-02-17 17:48:16 +01:00
Gael Guennebaud
aea630a98a factorize implementation of standard real unary math functions, and add acos, asin 2011-02-17 17:37:11 +01:00
Gael Guennebaud
2ba55e90db make check no test everything - also rm the EigenTesting cmake sub-project 2011-02-17 16:58:18 +01:00
Benoit Jacob
d0b8ce8f2a fix unused var warning 2011-02-17 09:41:17 -05:00
Gael Guennebaud
1c4e85ac7e forgot to include this file in one pretty old commit (missing EXCLUDE_FROM_ALL) 2011-02-17 15:33:35 +01:00
Jitse Niesen
78fa34e8ff Add blas tests for buildtests target. 2011-02-17 13:53:20 +00:00
Benoit Jacob
8fb27fad36 remove #include <iostream> at the wrong place 2011-02-17 07:47:05 -05:00
Jitse Niesen
be224d93f4 Include necessary header files when working around bug #89.
Fixes bug #188.
2011-02-17 11:51:48 +00:00
Benoit Jacob
11402edfd3 with old gcc (bug #89), only include iostream in debug mode 2011-02-16 12:01:47 -05:00
Gael Guennebaud
fe8a710a21 properly report OpenGL as a disabled backend 2011-02-16 18:01:06 +01:00
Gael Guennebaud
03d86ea736 fix intallation of unsupported modules 2011-02-16 17:59:35 +01:00
Benoit Jacob
13a5582835 undo debugging change 2011-02-16 09:18:48 -05:00
Benoit Jacob
59596efdf7 Fix bug #89: on GCC <= 4.3, use a custom assert implementation to work around a compiler bug 2011-02-16 08:50:19 -05:00
Jitse Niesen
6db8fa7d04 Replace unset() by set() with no value specified; this does the same.
unset() was introduced in CMake 2.6.3 but we require only 2.6.2.
2011-02-16 10:16:47 +00:00
Gael Guennebaud
2f15f74218 CTEST_CUSTOM_* parameter have to be put in a CTestCustum.cmake file which itself has to be in the build directory 2011-02-15 12:39:45 +01:00
Gael Guennebaud
578d6f7ced now ctest does compile the test even though they are not in the "all" target 2011-02-15 11:40:43 +01:00
Gael Guennebaud
a1d7e9051e fix bug #184 (warning) 2011-02-14 15:41:00 +01:00
Gael Guennebaud
8e0a42350d fix stupid warning (bug #185) 2011-02-14 15:33:26 +01:00
Hauke Heibel
ac465a0891 Improve the Transform interface in order to prevent T.rotation() = R from compiling. 2011-02-14 12:00:47 +01:00
Jitse Niesen
211e1f8044 Improve documentation of plugins. 2011-02-13 22:50:57 +00:00
Benoit Jacob
d09b94e2ad Added tag 3.0-beta3 for changeset 58986ac832 2011-02-12 18:57:10 -05:00
Benoit Jacob
58986ac832 bump 2011-02-12 18:57:04 -05:00
Jitse Niesen
8bca23bbec Mention comma initializer can be used to concatenate vectors
(inspired by a question on IRC)
2011-02-12 23:17:31 +00:00
Hauke Heibel
1a6597b8e4 MSVC does not like using uninitialized SSE variables, so we have to pass all zeros. 2011-02-12 21:29:16 +01:00
Hauke Heibel
509ca63543 Merge 2011-02-12 18:50:53 +01:00
Hauke Heibel
beb03032b7 Disabled warning regarding the use of uninitialized variables on MSVC. 2011-02-12 18:48:57 +01:00
Jitse Niesen
9ac68e40a0 Write topic page for storage orders. 2011-02-12 17:43:29 +00:00
Hauke Heibel
7015aa00a9 Added configuration file for the 'eol' extension. 2011-02-12 18:38:56 +01:00
Gael Guennebaud
9d2bf35a05 implement optimized ploadu for MSVC10: this also fix bad code generation in gebp_kernel :) 2011-02-12 16:40:09 +01:00
Gael Guennebaud
ec7409b16e since gebp_kernel handled the scaling by alpha it used too many packets, this patch fix that. 2011-02-12 14:17:52 +01:00
Benoit Jacob
f7e4602a40 doc fixes 2011-02-11 09:55:54 -05:00
Hauke Heibel
bf79a3199c Reduced error traces when mixing matrices with different scalar types. 2011-02-11 09:41:48 +01:00
Gael Guennebaud
fe70113fab fix Transform documention regarding Mode 2011-02-10 18:58:37 +01:00
Benoit Jacob
f3b81302cd fix typo 2011-02-10 11:06:01 -05:00
Benoit Jacob
57b22204db document the eigen2 support stages 2011-02-10 10:55:22 -05:00
Benoit Jacob
6a5a13e394 The pfirst hack is needed also on msvc 2010 as it gets completely nuts, even though it doesnt segfault as msvc 2008 did 2011-02-09 15:13:23 -05:00
Benoit Jacob
63626bb966 remove debug #error 2011-02-09 14:37:52 -05:00
Benoit Jacob
85f9fab003 back out changeset efdf2e4056
. It turns out that the SSE3 header is always included, even without any SSE enabled, so it was making us wrongly use SSE3 paths. Backing this out fixes msvc related crashes, at least bug #165.
2011-02-09 14:01:26 -05:00
Gael Guennebaud
d6c4ca4845 fix redundancy 2011-02-09 13:44:05 +01:00
Gael Guennebaud
c0d5131435 workaround gcc 4.2.1 ICE (fix bug #145) 2011-02-09 13:04:35 +01:00
Gael Guennebaud
40526e24b4 fix memory leak (when conservatively resizing vectors of dynamically allocated scalar types such as bugnums) 2011-02-07 19:52:16 +01:00
Benoit Jacob
ba9f6a2c3b now random<integer types> spans over 0..RAND_MAX, or -RAND_MAX/2..RAND_MAX/2 for signed types, or the most significant bits for smaller integer types. 2011-02-07 10:55:41 -05:00
Benoit Jacob
3386a946f8 fix unit tests for integer types in preparation for next changeset making random<int> span over a much bigger range 2011-02-07 10:54:50 -05:00
Benoit Jacob
68a2e04a96 fix fuzzy compares for integer types, using a selector 2011-02-07 10:53:17 -05:00
Gael Guennebaud
c5c8efa575 workaround gcc 4.2 and 4.3 compilation issue with NEON 2011-02-07 16:41:21 +01:00
Benoit Jacob
9105e62d0a introduce EIGEN_MAKING_DOCS to tell whether we're compiling the docs examples 2011-02-06 12:51:42 -05:00
Benoit Jacob
02ee26a3a5 fix build of class Block examples 2011-02-06 12:43:01 -05:00
Benoit Jacob
182ed9ba6c merge 2011-02-06 11:57:31 -05:00
Benoit Jacob
bc6625ab87 fix const correctness in Diagonal::coeffRef (fix found by failtests) 2011-02-06 11:57:04 -05:00
Benoit Jacob
dab4e583cb fix EIGEN_STATIC_ASSERT_LVALUE (fix found by failtests) 2011-02-06 11:56:33 -05:00
Benoit Jacob
80500b693c add more failtests 2011-02-06 11:55:51 -05:00
Hauke Heibel
d975b82105 Removed internal::as_argument. This fixes the alignment issues of bug #165. 2011-02-06 17:33:04 +01:00
Hauke Heibel
7ea6ac79a3 Exposed failtetst publicly. 2011-02-06 13:43:08 +01:00
Gael Guennebaud
ea99880760 fix under- and overflow 2011-02-06 08:23:10 +01:00
Benoit Jacob
9ce08b352f add more failtests 2011-02-06 01:44:51 -05:00
Benoit Jacob
9b13e9aece failtest: a new cmake-based test suite for testing stuff that should fail to build. This first batch imports some const correctness checks from bug #54. 2011-02-05 18:57:29 -05:00
Hauke Heibel
8aee724274 Made MatrixBase::BasisReturnType const. 2011-02-05 15:53:17 +01:00
Hauke Heibel
6c3dc0d243 Fix Diagonal related const correctness issues. 2011-02-05 14:19:53 +01:00
Hauke Heibel
e20f1a44bb Fixed hidden const correctness issue. 2011-02-05 13:52:18 +01:00
Jitse Niesen
e2d46eac42 Remove all references to EIGEN_TUNE_CPU_CACHE_SIZE.
This macro is no longer used as of revision 0212eec23f
.
2011-02-04 22:33:53 +01:00
Thomas Capricelli
0b555a4a3d fix misc warnings 2011-02-04 13:55:12 +01:00
Thomas Capricelli
0ed604583f turnaround for a compiler bug in gcc 3.4.6 2011-02-04 12:09:30 +01:00
Gael Guennebaud
aee4e950d3 extend ctest script for SSSE3 and above 2011-02-03 18:04:43 +01:00
Gael Guennebaud
5887a086cf fix SSE3 issue (infinite loop after the ei_ => internal change) - this fix bug #174 2011-02-03 17:55:24 +01:00
Gael Guennebaud
1526de96a0 fix compilation with MSVC 2011-02-03 17:23:33 +01:00
Benoit Jacob
4489c56c9e add Map static methods taking Strides, add test checking for compilation errors 2011-02-03 10:05:45 -05:00
Gael Guennebaud
2e2614b0fd fix MSVC8 compilation 2011-02-03 15:40:48 +01:00
Gael Guennebaud
2f71277105 add global tan function 2011-02-03 14:45:21 +01:00
Jason Newton
d028262e06 add tan function in Array world 2011-02-03 14:34:40 +01:00
Gael Guennebaud
1eae6d0fb9 an even more stable procedure 2011-02-03 11:25:34 +01:00
Gael Guennebaud
5beb2f4f0d slightly more stable eigen vector computation 2011-02-03 10:31:45 +01:00
Gael Guennebaud
a617d7f2ad fix compilation with MSVC2005 (strange, stupid fixes for MSVC9 confuse MSVC8....) 2011-02-02 17:47:48 +01:00
Gael Guennebaud
52e0a44034 implement GBMV 2011-02-02 11:39:13 +01:00
Gael Guennebaud
d5f6819761 split BandMatrix to a base and a wrapper class 2011-02-02 11:38:08 +01:00
Gael Guennebaud
8915d5bd22 fix 168 : now TriangularView::solve returns by value making TriangularView::solveInPlace less important.
Also fix the very outdated documentation of this function.
2011-02-01 17:21:20 +01:00
Gael Guennebaud
59af20b390 extend nomalloc test 2011-02-01 16:46:35 +01:00
Gael Guennebaud
ffc8386fdb mark the packet access methods as internal 2011-02-01 16:14:53 +01:00
Gael Guennebaud
a486d5590a implement optimized path for selfadjoint rank 1 update (safe regarding dynamic alloc) 2011-02-01 15:49:10 +01:00
Benoit Jacob
3eb74cf9fc forgot hg add 2011-02-01 07:51:55 -05:00
Gael Guennebaud
fa32ce0fc5 fix alignment issue 2011-02-01 13:51:56 +01:00
Benoit Jacob
2d09b11a97 relax Matrix/Array(Index) ctors to allow size 0, add test. 2011-02-01 07:46:02 -05:00
Gael Guennebaud
faa1284c12 fix compilation of snippets 2011-02-01 13:28:14 +01:00
Gael Guennebaud
4cb9d0f943 notify the creation of manual temporaries 2011-02-01 11:41:52 +01:00
Gael Guennebaud
c60818fca8 fix trmv regarding strided vectors and static allocation of temporaries 2011-02-01 11:38:46 +01:00
Gael Guennebaud
0fdd01fe24 operator(int) and the likes are not only fine for linear storage 2011-02-01 11:09:02 +01:00
Gael Guennebaud
f4a7679904 fix packing criterion 2011-02-01 10:41:12 +01:00
Gael Guennebaud
f46ace61d3 fix dynamic allocation for fixed size objects in matrix-vector product 2011-01-31 21:30:27 +01:00
Benoit Jacob
5ca407de54 update .hgignore 2011-01-31 09:21:31 -05:00
Benoit Jacob
dc22ae101f kill stage 15, it's useless 2011-01-31 09:18:49 -05:00
Benoit Jacob
df06f0be31 eigen2 support: pass remaining 2 tests 2011-01-31 08:55:38 -05:00
Benoit Jacob
7032ec80ae eigen2support: disable sparse tests, and do not require to define YES_I_KNOW_NOT_STABLE 2011-01-31 08:44:49 -05:00
Benoit Jacob
374deaed5f make eigen2 eigensolver test pass 2011-01-31 08:36:14 -05:00
Gael Guennebaud
e2642ed620 clean the script to generate the plots 2011-01-31 12:45:18 +01:00
Gael Guennebaud
3874e6a72b include cblas.h header file to ease configuration 2011-01-31 11:02:59 +01:00
Gael Guennebaud
476cb4c65c fix name collision 2011-01-31 10:54:21 +01:00
Gael Guennebaud
9a73bfeb85 add GOTO2 and clean a bit the cmake macros 2011-01-31 10:45:03 +01:00
Gael Guennebaud
6e67d15795 now gemv supports strides 2011-01-30 08:17:46 +01:00
Hauke Heibel
157a5040d5 Added the /bigobj flag in order to enable compilation with MSVC when EIGEN_SPLIT_LARGE_TESTS is not set. 2011-01-29 14:35:24 +01:00
Benoit Jacob
a1f5ea8954 make eigen2 cholesky test pass 2011-01-28 13:04:23 -05:00
Benoit Jacob
e001db2a15 fix bug in triangular matrix-vector produce found by eigen2 tests! 2011-01-28 13:04:11 -05:00
Gael Guennebaud
852077fbc9 still test fftw even if the binary for long double is not available 2011-01-28 16:54:01 +01:00
Gael Guennebaud
c478e0039e disable broken determinant for complexes and SuperLU 2011-01-28 16:30:21 +01:00
Benoit Jacob
6f2ba1f52b typo reported by Don Lorenzo 2011-01-28 10:00:34 -05:00
Gael Guennebaud
817d86cbaf really fix permute_symm_to_symm for sparse complex matrix 2011-01-28 15:51:55 +01:00
Gael Guennebaud
6ec660ca7e fix crash in autodiff 2011-01-28 15:30:33 +01:00
Gael Guennebaud
af712e80e6 fix bug #73: weird compilation error in HouseholderSequence where double and float were mixed. Hopefuly this also solve bug #91... 2011-01-28 12:35:32 +01:00
Gael Guennebaud
d76ed18a9f rm useless ctor 2011-01-28 11:25:11 +01:00
Gael Guennebaud
1731a432e7 fix BTL cholesky action and output errors if the factorization failed 2011-01-28 11:24:18 +01:00
Gael Guennebaud
837f1ae59c fix compilation with old gcc 2011-01-28 11:23:02 +01:00
Gael Guennebaud
ddfd288dc9 start nighlty builds at 00:00:00 UTC 2011-01-28 10:33:02 +01:00
Gael Guennebaud
42d512d33c fix compilation with gcc 4.2 and older 2011-01-28 10:26:05 +01:00
Gael Guennebaud
97801e5e0e Eigen/Eigen should not include Sparse until it is API stable 2011-01-28 10:04:02 +01:00
Gael Guennebaud
736d00ab87 typo 2011-01-28 09:57:35 +01:00
Gael Guennebaud
162d29e696 fix compilation of sparse module with ICC 2011-01-28 09:55:32 +01:00
Thomas Capricelli
22db1a6e82 fix fftw test 2011-01-27 18:25:41 +01:00
Benoit Jacob
b2b8c6a89c dot() now always uses eigen3 convention, even in eigen2 support mode, even stage 10. Didn't have a choice as lots of eigen code is using it. 2011-01-27 12:04:26 -05:00
Gael Guennebaud
e761ba68f7 merge 2011-01-27 18:03:13 +01:00
Gael Guennebaud
3d8e179aa2 fix MaxCols in ComplexEigenSolver which was causing memory allocation instead of static allocation in the nomalloc test. Uncomment commenetd parts of the nomalloc test since now matrix-matrix products are safe. 2011-01-27 18:02:49 +01:00
Gael Guennebaud
32124bc64a EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET must be defined to use Eigen/Sparse 2011-01-27 17:36:58 +01:00
Benoit Jacob
52fed69baa add test for geometry with eigen2_ prefixes. fix that stuff. 2011-01-27 11:21:38 -05:00
Gael Guennebaud
955e096277 add an Options template parameter to Hyperplane and ParametrizedLine 2011-01-27 17:17:06 +01:00
Hauke Heibel
d5e81d866a Added regression tests for bug #148. 2011-01-27 16:37:06 +01:00
Benoit Jacob
fd400ffffb reverse order of testing for eigen2 support stages. Higher stages now have priority. So if your whole project builds with say stage 10, you can manually enable stage 20 for selected files. 2011-01-27 10:34:44 -05:00
Benoit Jacob
b69b6a9db2 add Threshold API to FullPivHouseholderQR 2011-01-27 10:17:52 -05:00
Gael Guennebaud
a954a0fbd5 Add an Options template paramter to Transform to enable/disable alignment 2011-01-27 16:07:33 +01:00
Jakob Schwendner
e3306953ef test case for unaligned quaternion 2011-01-27 09:14:30 -05:00
Christoph Hertzberg
0aa752fc4f add quaternion Options, add unaligned possibility 2011-01-27 09:14:22 -05:00
Gael Guennebaud
9ccd16609c fix twisted selfadjoint to selfadjoint (conjugation issue) 2011-01-27 14:39:01 +01:00
Gael Guennebaud
f5d0f115b4 EigenSolver is now in the Eigenvalues modules, not QR !
: Enter commit message.  Lines beginning with 'HG:' are removed.
2011-01-27 13:56:03 +01:00
Gael Guennebaud
255f2a1379 fix various compilations issues 2011-01-27 13:51:39 +01:00
Gael Guennebaud
999678c3f0 fix mixingtypes unit test 2011-01-27 13:51:17 +01:00
Eamon Nerbonne
40998f5e86 fix const-related compiler error on MSC. 2011-01-27 07:43:07 -05:00
Gael Guennebaud
5f03cbd44f fix many missing const in return types 2011-01-27 12:12:24 +01:00
Gael Guennebaud
e8d6a5ca87 fix cross product for complexes and add support for mixed real-complex cross products 2011-01-27 11:33:37 +01:00
Gael Guennebaud
0bfb78c824 allow mixed complex-real and real-complex dot products 2011-01-27 09:59:19 +01:00
Benoit Jacob
fe3bb545e0 allow matrix[index] in EIGEN2_SUPPORT 2011-01-26 20:22:33 -05:00
Gael Guennebaud
c90d0c363b improve automatic handling of gotoblas and atlas 2011-01-26 19:39:10 +01:00
Gael Guennebaud
0e8a532f87 always link to gfortran for gotoblas, it seems to be harmless for 1.x but needed for 2.x 2011-01-26 19:16:06 +01:00
Gael Guennebaud
240bfdd142 finish the move to Eigen3 in BTL, and let's use our own FindEigen3.cmake script 2011-01-26 19:12:35 +01:00
Gael Guennebaud
86acb46518 pass to eigen3 ;) 2011-01-26 18:41:06 +01:00
Gael Guennebaud
faeae169dd fix compilation 2011-01-26 17:58:17 +01:00
Gael Guennebaud
210a280daf update FindMKL to match the default installation behavior of MKL 11 2011-01-26 17:58:01 +01:00
Gael Guennebaud
1eb85b4cf1 allow the possibility to automatically call or not the ctors on a per scalar type basis, and disable automatic initialization of std::complex<> 2011-01-26 17:56:49 +01:00
Gael Guennebaud
4783748953 do not include reference lapack files if they are not there 2011-01-26 17:10:05 +01:00
Benoit Jacob
162cb8ff42 import back LeastSquares into eigen2support. Pass most of eigen2's 'regression' test, except for regression_4 which is about complex numbers. 2011-01-26 11:05:41 -05:00
Gael Guennebaud
98285ba81c merge 2011-01-26 16:36:07 +01:00
Gael Guennebaud
7ef9d82b39 add a minimalistict lapack wrapper 2011-01-26 16:34:45 +01:00
Gael Guennebaud
15ef62ca43 extend PermutationMatrix and Transpositions to support arbitrary interger types and to support the Map/Wrapper model via base and derived classes 2011-01-26 16:33:23 +01:00
Benoit Jacob
76c630d185 eigen2 support: import SVD back, pass SVD tests 2011-01-26 10:33:03 -05:00
Benoit Jacob
313eea8f10 fix the remainder of bug #159 2011-01-26 10:01:18 -05:00
Benoit Jacob
f88ca0ac79 fix the eigen3 part of bug #159 - build issue with selfadjointview 2011-01-26 09:49:06 -05:00
Benoit Jacob
9a5ded3e1d fix bug #160 - forgot hg add 2011-01-25 21:31:27 -05:00
Benoit Jacob
c350f6f12c fix bug #161 2011-01-25 21:28:20 -05:00
Benoit Jacob
39536d44da fix build 2011-01-25 21:24:31 -05:00
Benoit Jacob
1d98cc5e5d eigen2 support: implement part<SelfAdjoint>, mimic eigen2 behavior braindeadness-for-braindeadness 2011-01-25 21:22:04 -05:00
Benoit Jacob
4fbadfd230 merge 2011-01-25 11:19:54 -05:00
Benoit Jacob
07e3ef4f38 eigen2: pass QR decomposition and hyperplane tests 2011-01-25 11:19:26 -05:00
Gael Guennebaud
6896cab5b9 one more const missing 2011-01-25 16:52:40 +01:00
Gael Guennebaud
28d6e84150 fix compilation after recent const change in return types 2011-01-25 16:33:02 +01:00
Benoit Jacob
b1d6a9945c eigen2: pass the inverse test 2011-01-25 10:05:29 -05:00
Benoit Jacob
09d1923f61 eigen2: pass lu test 2011-01-25 10:02:36 -05:00
Benoit Jacob
3e2469f951 eigen2: split tests 2011-01-25 09:02:59 -05:00
Benoit Jacob
b04591fbb4 disable eigen2_first_aligned test, it's completely internal stuff 2011-01-25 08:38:22 -05:00
Benoit Jacob
acd2c82655 fix eigen2_bug_132 test 2011-01-25 08:37:32 -05:00
Benoit Jacob
8acd43bbdb let eigen2 tests use the same ei_add_test macro, which required to prefix them with eigen2_ ; rename buildtests_eigen2 to eigen2_buildtests, etc. 2011-01-25 08:37:18 -05:00
Benoit Jacob
dcfb58f529 eigen2: fix USING_PART_OF_NAMESPACE_EIGEN 2011-01-25 08:03:12 -05:00
Gael Guennebaud
84448b058c fix USING_PART_OF_NAMESPACE_EIGEN to export ei_ prefixed math functions 2011-01-25 09:35:49 +01:00
Gael Guennebaud
7dd4aaba9f fix missing const qualifier in cwiseEqual 2011-01-24 18:49:18 +01:00
Benoit Jacob
bd12ac4ffc import eigen2 Geometry module into Eigen2Support.
fix build of geometry tests
2011-01-24 11:21:58 -05:00
Benoit Jacob
5bfde30e48 fix compilation of array tests 2011-01-24 09:38:50 -05:00
Benoit Jacob
9089488210 fix compilation of Eigen/Geometry with EIGEN2_SUPPORT: was including non-existent header 2011-01-24 08:59:47 -05:00
Benoit Jacob
c3a4f6b5c5 const-qualify template parameters representing const arguments to expressions.
needed to fix docs compile issue.
2011-01-24 08:27:06 -05:00
Benoit Jacob
5331fa3033 fix compilation of LU class example 2011-01-24 07:41:47 -05:00
Benoit Jacob
1dabd133cc pass eigen2's triangular test 2011-01-23 21:53:28 -05:00
Benoit Jacob
5c82fd7f40 Move part() to EIGEN2_SUPPORT (had been deprecated for a long time) 2011-01-23 18:49:36 -05:00
Benoit Jacob
1cf4996d3c make eigen2 visitor test pass 2011-01-23 18:34:30 -05:00
Benoit Jacob
8df5bca979 rename build stages to multiples of 10; old stage 2 becomes stage 15, while stage 20 generates errors (instead of warnings) on conflicting API. 2011-01-23 18:22:18 -05:00
Benoit Jacob
cc1f70abc3 make eigen2 dynalloc test pass (add to eigen2 support some internal stuff that some users may have been relying on) 2011-01-21 10:47:31 -05:00
Benoit Jacob
30de1651d3 relax Map const correctness in eigen2 support stages <= 3
introduce new 'strict' stage 4
2011-01-21 10:42:19 -05:00
Benoit Jacob
54dfcdf86e remove eigen2 vectorization_logic test, it's not an API test 2011-01-21 10:29:43 -05:00
Benoit Jacob
5be269db88 make eigen2 submatrices test pass 2011-01-21 10:24:59 -05:00
Benoit Jacob
cc2b7a5397 introduce the 3 stages of eigen2 support, writing to the mailing list about that in Eigen2 to Eigen3 Migration Path thread 2011-01-21 09:51:03 -05:00
Benoit Jacob
34d93686db lots more EIGEN2_SUPPORT fixes. Now several of the most important core tests build and succeed. 2011-01-20 10:36:32 -05:00
Benoit Jacob
66a2ffa9bd Completely disable Eigen/Array in Eigen3; completely enable in EIGEN2_SUPPORT. 2011-01-20 08:12:24 -05:00
Benoit Jacob
96f08213f7 big eigen2support fix, aimed at users who relied on internal eigen2 stuff: now we dont need customizations in test/eigen2/main.h anymore.
These tests already build:
eigen2_basicstuff
eigen2_adjoint
eigen2_linearstructure
eigen2_prec_inverse_4x4
2011-01-19 11:01:07 -05:00
Benoit Jacob
bf0cffa897 restore the behavior of defaulting to Release build type 2011-01-19 10:15:36 -05:00
Benoit Jacob
1f6bd2915d import eigen2 test suite. enable by defining EIGEN_TEST_EIGEN2
only test_prec_inverse4x4 is fixed at the moment. now need to go over all those tests.
2011-01-19 10:10:54 -05:00
Benoit Jacob
604afc9aca fix bug #155, const-related compilation error 2011-01-18 09:14:14 -05:00
Hauke Heibel
9b2546fea8 Added remaining const coeffRef accessors to Array- and MatrixWrapper. 2011-01-18 13:19:13 +01:00
Benoit Jacob
c7eaca50a0 __cpuidex is not (always) present in VS 2008 + SP1, it seems 2011-01-17 11:17:45 -05:00
hamelin.philippe
5e28f34005 Replace CMAKE_SOURCE_DIR with PROJECT_SOURCE_DIR to allow the cmake project to be included by a root project. 2011-01-17 09:59:40 -05:00
Gael Guennebaud
5010033d88 do not stop the factorization if one pivot is exactly 0, and return the
index of the first zero pivot if any
2011-01-17 11:11:22 +01:00
Gael Guennebaud
ef3e690a0c return the index of the first non positive diagonal entry (more useful than simply true or false) 2011-01-17 11:09:03 +01:00
Gael Guennebaud
8b6c1caa3e fix compilation of rowmajor sparse time diagonal 2011-01-14 20:29:55 +01:00
Thomas Capricelli
dcbf091e60 fix EIGEN_TEST_NOQT (reported by Philippe Hamelin) 2011-01-14 14:30:06 +01:00
Jose Luis Blanco
cbfab7204f Update of CPUID macros to fix segfaults in amd64 code. 2011-01-05 02:43:43 +01:00
Benoit Jacob
98f0274305 third pass of const-correctness fixes (bug #54), hopefully the last one... 2011-01-07 05:16:01 -05:00
Gael Guennebaud
c7baf07a3e add plugin mechanism to sparse objects 2011-01-07 15:53:02 +01:00
Jitse Niesen
9111d73017 Fix compilation error in HouseholderSequence introduced in my previous commit. 2011-01-07 13:46:23 +00:00
Romain Bossart
4abb772b52 Fix bug #38
* address of temporaries were passed to umfpack_zi_* functions. It is ok with g++-4.4 or 4.5, but not with the -std=c++0x in both versions. This patch makes it work for c++98 and c++0x versions
2011-01-07 10:27:22 +01:00
Jitse Niesen
2cc75f4922 Make HouseholderSequence::setTrans() protected (cf. bug #50).
Users can call .transpose() instead.
2011-01-06 11:30:19 +00:00
Manuel Yguel
934720c4ba Decrease the degree of the polynomials being tested to reduce time spent during the tests. 2011-01-05 19:49:13 +01:00
Hauke Heibel
4ba0ec5e0e Fixed #148 where a const-accessor for coefficients was missing in the MatrixWrapper. 2011-01-04 15:35:50 +01:00
Gael Guennebaud
d7e1eeaece fix compilation when defaulting to row major 2011-01-04 14:40:06 +01:00
Gael Guennebaud
3a4d56171d fix openglsupport unit test when defaulting to row major 2011-01-04 14:34:17 +01:00
Gael Guennebaud
64356a622d fix vectorization_logic unit test when defaulting to row major 2011-01-04 14:18:07 +01:00
Jitse Niesen
004488a31d Fix bug in symmetric rank-2 update for row-major matrices (bug #144). 2011-01-04 10:35:39 +00:00
Jitse Niesen
fb023b871f Const-correctness fix for gemv_selector<OnTheRight,ColMajor,true> (bug #144). 2011-01-04 10:35:10 +00:00
Benoit Jacob
fd4e366d7e fix severe perf bug: coeff-based matrix products were not considered aligned, typically preventing vectorization.
added unit test.
2011-01-02 12:07:39 -05:00
Jitse Niesen
47a9d2ed54 Document HouseholderSequence.
Incomplete: I did not explain the difference between OnTheLeft and OnTheRight,
and there is only one example.
2011-01-02 16:59:44 +00:00
Gael Guennebaud
583f963517 make the table fit within 80 characters 2011-01-01 12:02:55 +01:00
Gael Guennebaud
e7318148b5 an attempt to fix a compilation issue with -std=c++0x 2011-01-01 11:40:30 +01:00
Jose Luis Blanco
7feb644620 Switched "MESSAGE(" -> "MESSAGE(STATUS " in CMake script, since otherwise they may look like errors to the user. 2010-12-29 22:02:01 +01:00
Gael Guennebaud
902af035d3 merge 2010-12-31 17:26:48 +01:00
Gael Guennebaud
25efcdd042 fix sparse time dense product with a rowmajor lhs 2010-12-31 17:11:17 +01:00
David J. Luitz
11e253bc10 [Sparse] Added regression tests for the two bugfixes, the code passes all sparse_product tests 2010-12-30 15:16:23 +01:00
Benoit Jacob
13867c15cc fix compilation of code using e.g. Transpose<const Foo>::data() non-const-qualified. Same problem existed for coeffRef() and also in MapBase.h. 2010-12-30 07:47:51 -05:00
Benoit Jacob
26c2afd55a fix compile errors in Tridiagonalization and in doc examples 2010-12-30 04:52:20 -05:00
Benoit Jacob
dbd9c5fd50 fix HouseholderSequence API, bug #50:
* remove ctors taking more than 2 ints
 * rename actualVectors to length
 * add length/shift/trans accessors/mutators
2010-12-30 04:18:40 -05:00
Trevor Irons
e112ad8124 In QuickRefPage LinSpaced is improperly documented. 2010-12-29 10:08:41 -07:00
Jitse Niesen
d6a5ba5a08 Rename EIGEN_DENSESTORAGEBASE_PLUGIN to EIGEN_PLAINOBJECTBASE_PLUGIN. 2010-12-29 19:12:39 +00:00
Jose Luis Blanco
3ca31a8b74 fixed msvc9 build errors. 2010-12-29 19:42:01 +01:00
Jitse Niesen
d84b135ed3 Enable GSL tests (reverts part of changeset 6628534eb5
).
2010-12-29 17:45:18 +00:00
Jose Luis Blanco
97c54ad220 fix MSVC warnings, bug #143 2010-12-29 06:15:41 -05:00
Thomas Capricelli
7a29ae0b5c fix preprocessor checks for availability of cpuid 2010-12-28 13:46:39 +01:00
Jitse Niesen
657013c974 Mention ptr_fun in docs for .unaryExpr() 2010-12-27 16:35:25 +00:00
Jitse Niesen
265e1ef4ef Extend doc page on preprocessor directives. 2010-12-27 16:34:58 +00:00
Jitse Niesen
8db9acbc16 Move doxygen comments for EIGEN_NO_DEBUG from source to I14.
This reverts changeset 76fbe94279
. Benoit and I agree that my
approach there (to use doxygen comments) pollutes the code too much.
2010-12-27 15:07:11 +00:00
Jitse Niesen
840c4e1ab5 Move section on preprocessor directives from I00 to its own page. 2010-12-27 15:07:07 +00:00
Jitse Niesen
42a050dc68 Finish doc page on aliasing. 2010-12-27 15:06:55 +00:00
Benoit Jacob
dc3618a557 move BandMatrix and TridiagonalMatrix to the internal:: namespace 2010-12-25 17:17:10 -05:00
Benoit Jacob
8d2a10c5c1 more renaming to make this file matrix-or-array-agnostic 2010-12-25 17:04:36 -05:00
Benoit Jacob
e8768251db rename macro 2010-12-25 17:01:01 -05:00
Benoit Jacob
86d3711fb7 remove EIGEN_REF_TO_TEMPORARY, clarify docs 2010-12-25 16:45:25 -05:00
Benoit Jacob
75b7d98665 bug #54 - really fix const correctness except in Sparse 2010-12-22 17:45:37 -05:00
Hauke Heibel
3b6d97b51a Re-enabled the BLAS compilation on non-MSVC systems. 2010-12-17 10:52:57 +01:00
Hauke Heibel
5e46f7a499 Switched back to the old behaviour where EIGEN_SPLIT_LARGE_TESTS was ON per default on MSVC systems.
Without splitting these tests, some do not compile
2010-12-17 09:42:17 +01:00
Gael Guennebaud
a21d56b766 disable blas if C++ compiler is MSVC 2010-12-16 20:51:44 +01:00
Hauke Heibel
efdf2e4056 Added automatic SSE3/4.1/4.2 support for MSVC. 2010-12-16 20:08:22 +01:00
Hauke Heibel
b31e1246e1 Re-enabled the missing tests, again... 2010-12-16 19:07:23 +01:00
Hauke Heibel
83e3c4582f Improved the array unit test - internal::isApprox needs to use the same precision as VERIFY_IS_NOT_APPROX.
Removed debug code from test_isApprox.
2010-12-16 18:53:02 +01:00
Hauke Heibel
2d0dfe5d60 Uups - re-enabled subtests 1 to 5. 2010-12-16 17:36:10 +01:00
Hauke Heibel
f578dc7aff Fixed compound subtraction in ArrayBase where the assignment needs to be carried out on the derived type.
Added unit tests for map based component wise arithmetic.
2010-12-16 17:34:13 +01:00
Hauke Heibel
dbfb53e8ef Added unit test for matrix creation from const raw data. 2010-12-15 15:28:43 +01:00
Hauke Heibel
6f5c45ceff Fixed ctor from const raw data for Matrices and added the missing implementation for Arrays.
Fixed a warning regarding the conversion from int to bool in MapBase.
2010-12-15 15:19:51 +01:00
Gael Guennebaud
6a9a6bbc78 fix warning 2010-12-13 10:18:33 +01:00
Gael Guennebaud
68fe80861c Fix bug #133: remove the EIGEN_RESTRICT which was useless here anyway 2010-12-13 09:56:13 +01:00
Jitse Niesen
f2c18f2e37 merge 2010-12-12 21:24:24 +00:00
Jitse Niesen
4a5ebcd1ce Fix compilation of Tridiagonalization_diagonal example.
After changeset 0d63212257
, matrixT() is a real matrix even if the matrix
which is decomposed is complex.
2010-12-12 13:53:42 +00:00
Gael Guennebaud
c7f01157dd enforce compilation of blas unit tests when running ctest 2010-12-12 13:10:00 +01:00
Jitse Niesen
9cd4f67e7f Specify root namespace for fftw_plan from FFTW3 library.
After changeset 4716040703
 (the ei_ --> internal:: change), there are two symbols
called fftw_plan, one from the FFTW3 library and one from Eigen.
2010-12-12 11:44:30 +00:00
Konstantinos Margaritis
e05c79cbd8 Fixed NEON compilation errors, changed float-abi back to softfp (which is the most used right now).
Some complex tests appear to segfault, needs a more careful look.
2010-12-10 20:27:46 +02:00
Benoit Jacob
b11343e15c fix intermittend failure of schur_real test: there only is an iterative process if size>2 2010-12-10 02:10:03 -05:00
Benoit Jacob
74cc42b22f bug #54 - The big Map const-correctness changes 2010-12-10 02:09:58 -05:00
Gael Guennebaud
e736df3edd suppress stupid warning 2010-12-10 15:53:13 +01:00
Gael Guennebaud
79cc86f701 fix compilation 2010-12-10 13:52:47 +01:00
Gael Guennebaud
67c28570e3 fix compilation with ICC (template keyword on a non template method) 2010-12-10 10:05:52 +01:00
Gael Guennebaud
5bc21c25c5 fix ICE with gcc 3.4 and 4.0.1 2010-12-10 09:59:44 +01:00
Gael Guennebaud
bacd531862 fix bug #128 : tridiagonalization failed for 1x1 matrices 2010-12-09 19:56:20 +01:00
Gael Guennebaud
17de59278b simplification 2010-12-09 19:47:02 +01:00
Gael Guennebaud
147a63c4b5 compilation fix 2010-12-09 19:46:26 +01:00
Gael Guennebaud
0b32c5bdda fix compilation of sparse_basic for DynamicSparseMatrix 2010-12-09 19:39:15 +01:00
Benoit Jacob
aec0782719 fix the build of eigensolver_complex test.
it was calling the .value() method on an inner product, and that was blocked in bad zero-sized case.

fixed by adding the .value() method to DenseBase for all 1x1 expressions, and allowing coeff accessors in ProductBase for 1x1 expressions.
2010-12-09 03:47:35 -05:00
Benoit Jacob
1be6449f2e fix bug #127. our product selection logic was flawed in that it used the Max-sized to determine whether the size is 1.
+ test.
2010-12-09 02:38:07 -05:00
Benoit Jacob
819bcbed19 fix comment 2010-12-07 02:17:15 -05:00
Eamon Nerbonne
7a7ca99a31 [mq]: Mingw32 fix
intrin.h is not required nor supported by mingw32.  It is present (and supported) on mingw-w64 builds, even those for 32-bit systems, but here too it's not required on 32-bit systems.  So if we're on mingw, and it's 64-bit, then and only then is the intrin.h inclusion necessary.
2010-12-03 23:24:06 +01:00
Gael Guennebaud
c49c013c47 add main ei_* functions into Eigen2Support 2010-12-03 11:22:35 +01:00
Gael Guennebaud
14208eb478 add a word about the ei_ prefix change in Eigen2 -> Eigen3 doc page. 2010-12-03 10:54:16 +01:00
Hauke Heibel
a289065c73 Applied a fix to our std::vector specialization which prevents the usage of workaround_msvc_stl_support when T is not a class. 2010-12-02 12:33:15 +01:00
Benoit Jacob
59b944cb50 add is_const 2010-12-01 09:22:54 -05:00
Benoit Jacob
46387cc180 remove makeconst_return_type 2010-12-01 09:22:50 -05:00
Hauke Heibel
f0ba513f41 Fixed compilation of tridiagonalization related unit tests. 2010-11-27 15:41:46 +01:00
Hauke Heibel
3899857e08 Removed remove_const_on_value_type since the meaning is unclear and it is in fact unused.
Extened the meta unit tests.
2010-11-26 18:06:08 +01:00
Hauke Heibel
60a544c879 Added STL like (add|remove)_const. Fixed add_const_on_value_type for "const T* const". 2010-11-26 16:56:03 +01:00
Hauke Heibel
bf9d25ce58 Postfixed add_const and remove_const by _on_value_type to express the differences to the STL. 2010-11-26 16:30:45 +01:00
Benoit Jacob
139392488d dos2unix 2010-11-26 10:10:26 -05:00
Jitse Niesen
e868b6736a Merge. 2010-11-26 14:37:58 +00:00
Gael Guennebaud
d551e99644 make HessenbergDecompositionMatrixHReturnType internal 2010-11-26 15:39:01 +01:00
Gael Guennebaud
e06c6553e0 make TridiagonalizationMatrixTReturnType internal and only export a public MatrixTReturnType typedef 2010-11-26 15:36:29 +01:00
Gael Guennebaud
0d63212257 add a TridiagonalizationMatrixTReturnType class to make Tridiagonalization::matrixT() more efficient and future proof. 2010-11-26 15:31:47 +01:00
Jitse Niesen
9bad7c7edb Compilation fix in case EIGEN_DEBUG_ASSERTS is defined. 2010-11-26 14:21:57 +00:00
Gael Guennebaud
421b2b5ff7 fix a couple of issues with TridiagonalMatrix 2010-11-26 13:04:20 +01:00
Gael Guennebaud
d8b26cfeec s/id/p to avoid name clash 2010-11-26 08:36:16 +01:00
Gael Guennebaud
156a31b0e9 fully implement scalar_fuzzy_impl<bool> as, e.g., the missing isMuchSmallerThan is convenient to filter out false values. 2010-11-25 18:00:30 +01:00
Jitse Niesen
010ed9510b Remove parentheses for compatibility with cmake 2.6.2 2010-11-24 22:26:13 +00:00
Benoit Jacob
cd1225ef14 make example compile 2010-11-24 09:18:49 -05:00
Benoit Jacob
f84cbba52a minor fixes 2010-11-24 09:16:30 -05:00
Benoit Jacob
07f2406dc1 some dox tweaks 2010-11-24 08:23:17 -05:00
Gael Guennebaud
f1690fb9fa fix bug #122 : rank 2 update test and scalar multiple extraction were both wrong 2010-11-23 19:19:04 +01:00
Benoit Jacob
0ab9a0a2f7 make UpperBidiagonalization internal: don't want to support it, it's not used.
Keeping it because it tests BandMatrix.
2010-11-23 11:12:42 -05:00
Benoit Jacob
ee38dbf1e6 Rework nested<> to be cleaner, see bug #76. 2010-11-23 11:11:40 -05:00
Frederic Gosselin
4c5932f8f5 Improves the filter for hidden files in "Eigen" and "Eigen/src".
This generic solution prevent cmake from having an error .svn folders when the source folder is under subversion.
2010-11-22 10:47:07 -05:00
Gael Guennebaud
5a65d7970a now the full blas folder requires a fortran compiler 2010-11-22 19:07:29 +01:00
Gael Guennebaud
3976a66889 fix bug #120 : compilation issue of trsolve unit test 2010-11-22 18:59:56 +01:00
Gael Guennebaud
f5f288b741 split level 1 and 2 implementation files into smaller ones and fix a couple of numerical and tricky issues discovered by the lapack test suite 2010-11-22 18:49:12 +01:00
Gael Guennebaud
a6f483e86b import reference BLAS routines which are not already implemented in Eigen : modified givens rotations, and packed and banded storages 2010-11-22 18:05:09 +01:00
Gael Guennebaud
7213dd1e6b this product still badly read the imaginary part on the diagonal 2010-11-22 18:00:47 +01:00
Benoit Jacob
a3f214ade9 holy crap, i had disabled all static asserts in 71f023de3e 2010-11-22 08:21:30 -05:00
Gael Guennebaud
d8396a8da0 fix compilation of product_mmtr 2010-11-21 10:23:06 +01:00
Gael Guennebaud
fb6d9ca951 add missing non const data() method to MapBase 2010-11-21 10:17:25 +01:00
Gael Guennebaud
0020ea544a implement HEMV level2 blas routine 2010-11-21 10:09:33 +01:00
Gael Guennebaud
12bfe5e718 make sure our internal selfadjoint*vector product does not use the imaginary part of the diagonal entries 2010-11-21 10:08:48 +01:00
Gael Guennebaud
e88901daf4 implement SYMV level2 blas routines 2010-11-21 09:34:41 +01:00
Gael Guennebaud
1ac9124fac implements TRMV level 2 blas routine 2010-11-20 23:29:20 +01:00
Gael Guennebaud
d72a8f1e50 make trmv uses direct access 2010-11-20 22:42:24 +01:00
Gael Guennebaud
437dff80ee fix issue 114: workaround cmake enable_language bug 2010-11-20 12:01:17 +01:00
Gael Guennebaud
86474115f5 IBM XL C compiler supports __attribute__((aligned(n))) syntax 2010-11-19 17:33:51 +01:00
Gael Guennebaud
8ad1f64e0a some cleaning in blas level 2 2010-11-19 17:22:43 +01:00
Thomas Capricelli
94f59a92cb fix typo 2010-11-19 17:16:28 +01:00
Gael Guennebaud
ed1ecb24d2 implement GERC and GERU blas routines 2010-11-19 17:05:24 +01:00
Gael Guennebaud
458637f097 implement GER blas routine 2010-11-19 17:02:24 +01:00
Gael Guennebaud
68f8519327 implement HER and HER2 blas routines 2010-11-19 16:51:52 +01:00
Gael Guennebaud
5ce199b1dd update rank 2 update doc 2010-11-19 16:50:49 +01:00
Gael Guennebaud
f369b5a711 makes rank 2 update function conformant to BLAS HER2 2010-11-19 16:50:15 +01:00
Gael Guennebaud
e14f14642d implement SYR and SYR2 2010-11-19 16:09:25 +01:00
Gael Guennebaud
661ef6c127 add regression unit test 2010-11-19 15:38:37 +01:00
Gael Guennebaud
3f24dbf6f5 fix compilation of transform * scaling 2010-11-19 14:45:45 +01:00
Gael Guennebaud
3e99356b59 clean a bit AMD and SimplicialCholesky and add support for partly stored selfadjoint matrices 2010-11-18 10:30:52 +01:00
Gael Guennebaud
1618df55df Add support for sparse symmetric permutations 2010-11-18 10:28:39 +01:00
Gael Guennebaud
fb71b737e4 update blas lib wrt recent change of general_matrix_matrix_triangular_product 2010-11-16 19:19:33 +01:00
Jitse Niesen
e54c8d20cb Docs: aliasing and component-wise operations. 2010-11-16 17:28:59 +00:00
Gael Guennebaud
da05b6af0e fix some remainign issue with ei_ -> internal change 2010-11-16 15:54:48 +01:00
Gael Guennebaud
9a3ec637ff new feature: copy from a sparse selfadjoint view to a full sparse matrix 2010-11-15 14:14:05 +01:00
Gael Guennebaud
5a3a229550 fix return type of rightHouseholderSequence() 2010-11-15 11:11:22 +01:00
Jitse Niesen
cad73d9cdc Correct std::map fix (two commits ago); copy fix to aligned_allocator doc. 2010-11-12 12:06:24 +00:00
Thomas Capricelli
d64e68c8bc fix doc compilation 2010-11-12 11:33:09 +01:00
Jose Luis Blanco
9ba15cd63c Docs: correct declaration of aligned std::map in TopicStlContainers. 2010-11-12 10:05:41 +00:00
Gael Guennebaud
b4fa8261b1 properly use nested types 2010-11-10 19:06:20 +01:00
Gael Guennebaud
05ed9be639 prevent warning 2010-11-10 18:59:16 +01:00
Gael Guennebaud
2577ef90c0 generalize our internal rank K update routine to support more general A*B product while evaluating only one triangular part and make it available via, e.g.:
R.triangularView<Lower>() += s * A * B;
2010-11-10 18:58:55 +01:00
Gael Guennebaud
c810d14d4d add missing specialization 2010-11-09 12:03:20 +01:00
Gael Guennebaud
39477e697a extend unit test to cover previous bug 2010-11-05 14:37:42 +01:00
Gael Guennebaud
572b5585e3 fix Eigen's trsv for complexes 2010-11-05 14:36:34 +01:00
Gael Guennebaud
0e30c4ae3f blas level2: gemv and trsv are green 2010-11-05 14:14:50 +01:00
Gael Guennebaud
3fdea699b8 trsv: simplifications/cleaning 2010-11-05 12:54:32 +01:00
Gael Guennebaud
0e6c1170ab trsv: add support for inner-stride!=1, reduce code instanciation, move implementation to a new products/XX.h file 2010-11-05 12:43:14 +01:00
Gael Guennebaud
fe1353080e fix error handling of level 1 routines 2010-11-04 22:25:59 +01:00
Gael Guennebaud
15e8ad686c add a minimum degree ordering routine based on CSparse (LGPL) and a new built-in sparse cholesky decomposition 2010-11-04 09:58:22 +01:00
Gael Guennebaud
5a4f77716d fix bug #107: SelfAdjointEigenSolver and RowMajor (and add unit test) 2010-11-04 09:33:05 +01:00
Gael Guennebaud
20fcef9656 fixes related to ei_ -> internal change 2010-11-04 08:38:16 +01:00
Gael Guennebaud
62a51184d7 merge 2010-11-04 08:32:52 +01:00
Gael Guennebaud
fd88d721d2 implement proper error handling in level 3 routines 2010-11-03 22:03:12 +01:00
Gael Guennebaud
a8fb6b0ad3 improve detection of erros 2010-11-03 22:02:44 +01:00
Gael Guennebaud
1eea88bff7 fix matrix product bug with OpenMP 2010-11-03 16:12:37 +01:00
Gael Guennebaud
8d27f55eb3 rm auto normalization in favor of clamping 2010-11-03 15:32:40 +01:00
Hauke Heibel
d204ec491d Additional fix to enforce the compiler to use the correct prunning method. 2010-11-02 14:33:33 +01:00
Hauke Heibel
3a3f163e31 Fix bug #65.
In order to prevent compilation errors, the default functor "struct func" must not be defined inside the function scope. I just moved it into a private section of SparseMatrix.
2010-11-02 14:32:41 +01:00
Hauke Heibel
b3007db131 Added a comment on why is_arithmetic is used in DenseCoeffsBase. 2010-11-02 10:11:22 +01:00
Hauke Heibel
96e4a4b59c Fixed compilation due to lacking Transform definitions. 2010-11-01 16:53:39 +01:00
Gael Guennebaud
d2e257cb5d oops (rm commented code) 2010-11-01 09:40:33 +01:00
Gael Guennebaud
c7eda0d866 Let's be safe: enable auto normalization is quaternion to angle-axis code since a slight numerical issue may trigger NaN. The overhead is small and I doubt the perf of this function could be critival for any application ! 2010-10-31 23:26:01 +01:00
Benoit Jacob
006c9a5105 implement VERIFY in a function so it doesn't get compiled thousands of times. 2010-10-29 10:27:20 -04:00
Benoit Jacob
7d441260db on test failure, abort instead of exit, so we can get a stack trace 2010-10-29 10:07:30 -04:00
Benoit Jacob
99ccb26cfe add eigen2support Transform typedefs, add Eigen2To3 section on Transform 2010-10-29 09:00:35 -04:00
Benoit Jacob
bd249d1121 fix bug #92 - we were doing stupid things when passing the list of libraries to link to. 2010-10-28 10:44:20 -04:00
Benoit Jacob
868f753d10 document LvalueBit better 2010-10-28 09:40:20 -04:00
Gael Guennebaud
1d4e80f09d generalize the prune function 2010-10-28 11:39:31 +02:00
Gael Guennebaud
02c8b6af82 fix sparse rankUpdate and triangularView iterator 2010-10-27 15:13:03 +02:00
Gael Guennebaud
241e5ee3e7 add the possibility to solve for sparse rhs with Cholmod 2010-10-27 14:31:23 +02:00
Hauke Heibel
5d4ff3f99c Fixed bug #95 by changing _M_IX64 to _M_X64 as proposed by Jan Schlicht. 2010-10-27 11:07:38 +02:00
Hauke Heibel
3efff8c69e Merge 2010-10-26 16:48:12 +02:00
Gael Guennebaud
f4a6a8e295 rm the useless SparseSolverBase class and provide more compile time traits 2010-10-26 16:47:47 +02:00
Hauke Heibel
c738cd56eb Renamed cleantype to remove_all since it is close to remove_{const|pointer|reference}. 2010-10-26 16:47:01 +02:00
Gael Guennebaud
2fbb9932b0 fix compilation (bad internal:: stuff) 2010-10-26 16:38:51 +02:00
Gael Guennebaud
5e95ee6662 fix compilation and unit test of adolc 2010-10-26 16:26:20 +02:00
Gael Guennebaud
92044fcc2b fix bug #94: add #include src/misc/Solve.h in SparseExtra 2010-10-26 15:51:06 +02:00
Gael Guennebaud
666c16cf63 add new API for Cholmod preserving the legacy one for now 2010-10-26 15:48:33 +02:00
Hauke Heibel
7bc8e3ac09 Initial fixes for bug #85.
Renamed meta_{true|false} to {true|false}_type, meta_if to conditional, is_same_type to is_same, un{ref|pointer|const} to remove_{reference|pointer|const} and makeconst to add_const.
Changed boolean type 'ret' member to 'value'.
Changed 'ret' members refering to types to 'type'.
Adapted all code occurences.
2010-10-25 22:13:49 +02:00
Hauke Heibel
597b2745e1 Allow unset ${CMAKE_BUILD_TYPE} which is required for some targets and corresponding to using default values. 2010-10-25 18:49:39 +02:00
Benoit Jacob
724af13540 make polynomialsolver test compile faster 2010-10-25 10:15:22 -04:00
Benoit Jacob
a94f216487 error out on bad build type 2010-10-25 10:15:22 -04:00
Benoit Jacob
fdaa3f311a adapt mpreal to eigen3 mathfunctions system 2010-10-25 10:15:22 -04:00
Benoit Jacob
4716040703 bug #86 : use internal:: namespace instead of ei_ prefix 2010-10-25 10:15:22 -04:00
Benoit Jacob
ca85a1f6c5 remove build type tweaking 2010-10-23 10:00:43 -04:00
Jitse Niesen
dbdf7ee942 Use 'Release' as default when build type is not specified.
Otherwise, "cmake /path/to/eigen/" in an empty build directory, as specified
on the CMake page on the wiki, yields a fatal error.
2010-10-22 12:23:35 +01:00
Benoit Jacob
bfd46eacad don't change the build type, fatal error if bad build type 2010-10-21 08:55:48 -04:00
Hauke Heibel
969518f99d Improved I13_FunctionsTakingEigenTypes.dox.
Removed the r-value reference part and focused on EIGEN_REF_TO_TEMPORARY only.
2010-10-21 10:14:23 +02:00
Hauke Heibel
ba86d3ef65 Fixed bug #84. 2010-10-21 10:13:17 +02:00
Hauke Heibel
9bbaff6b41 Fixed the unit test splitting for MSVC. 2010-10-21 07:39:06 +02:00
Benoit Jacob
ee60fc2062 fix typo and rephrase sentence 2010-10-20 09:43:16 -04:00
Benoit Jacob
8c17fab8f5 renaming: ei_matrix_storage -> DenseStorage
DenseStorageBase  -> PlainObjectBase
2010-10-20 09:34:13 -04:00
Hauke Heibel
9cf748757e Improved the fixed size array display. 2010-10-20 11:56:29 +02:00
Benoit Jacob
e259f71477 rename PlanarRotation -> JacobiRotation 2010-10-19 21:56:26 -04:00
Benoit Jacob
9044c98cff work around stupid msvc error when constructing at compile time an expression
that involves a division by zero, even if the numeric type has floating point
2010-10-19 21:56:11 -04:00
Gael Guennebaud
e5073746f3 allows blocks of code to be larger than the page body (like tables) 2010-10-19 16:55:49 +02:00
Gael Guennebaud
e19c6b89f5 update the position of the owl 2010-10-19 16:07:04 +02:00
Gael Guennebaud
54814eb05b factorize CSS code, make use of the "manual" class when appropriate, clean the style of the big linear algebra table 2010-10-19 15:25:00 +02:00
Benoit Jacob
70f95ef80d increase css max-width 2010-10-19 09:40:23 -04:00
Benoit Jacob
b1604ea553 merge 2010-10-19 09:32:19 -04:00
Benoit Jacob
b8dfc62f3c specify max-width in em not px 2010-10-19 09:31:22 -04:00
Gael Guennebaud
6d8e7d68e4 factorize CSS code, make use of the "manual" class when appropriate, clean the style of the big linear algebra table 2010-10-19 15:25:00 +02:00
Benoit Jacob
9e3005d552 css update: max-width and margins 2010-10-19 09:18:06 -04:00
Benoit Jacob
9fa54d4cc9 move tables from class "tutorial_code" to "example"
also remove a align="center" in the Aliasing page -- it doesn't make sense to have 1 centered table page when all others are left aligned.
2010-10-19 08:42:49 -04:00
Gael Guennebaud
ca4bd5851c update style of the quick ref guide 2010-10-19 11:59:11 +02:00
Gael Guennebaud
f66fe2663f update CSS to doxygen 1.7.2, new CSS and cleaning of the tutorial 2010-10-19 11:40:49 +02:00
Hauke Heibel
9f8b6ad43e Fixed bug #79. 2010-10-19 09:43:54 +02:00
Benoit Jacob
3481f10e7a re-fix the broken msvc warning in JacobiSVD 2010-10-18 09:46:22 -04:00
Benoit Jacob
3404d5fb14 improvements in pages 5 and 7 of the tutorial. 2010-10-18 09:09:30 -04:00
Benoit Jacob
1c15a6d96f improvements in tutorial page 4 : block operations 2010-10-18 08:44:27 -04:00
Benoit Jacob
4b0fb968ea fixed table html 2010-10-18 07:23:48 -04:00
Benoit Jacob
597bb61c23 fix stupid msvc warning in jacobisvd 2010-10-18 06:54:11 -04:00
Benoit Jacob
6628534eb5 fix bug i just introduced in ei_add_test_internal 2010-10-17 11:47:59 -04:00
Benoit Jacob
19ae4362bd ah ok, we want to build this even without GSL.
so the bug is in FindGSL.cmake.
2010-10-17 11:31:58 -04:00
Benoit Jacob
4e3feb023d more unsupported/ CMake fixes 2010-10-17 11:21:10 -04:00
Benoit Jacob
1e3a035275 Fix general linking issue for tests linking to multiple libs, and explicitly link mpfr_real test to GMP. 2010-10-17 11:04:43 -04:00
Benoit Jacob
8356bc8d06 add jacobiSvd() method, update test & docs 2010-10-17 09:40:52 -04:00
Hauke Heibel
cd3a9d1ccb Fixed bug #74. 2010-10-17 12:33:47 +02:00
Hauke Heibel
c19b965730 Added stddeque unit test dervied from the stdlist test. 2010-10-16 10:45:30 +02:00
Benoit Jacob
6f6400e488 Added tag 3.0-beta2 for changeset 3f79884f03 2010-10-15 09:46:45 -04:00
Benoit Jacob
3f79884f03 bump to 2.92.0 2010-10-15 09:46:20 -04:00
Benoit Jacob
26129229ec doc updates/improvements 2010-10-15 09:44:43 -04:00
Benoit Jacob
fcee1903be update the porting guide 2010-10-15 08:48:44 -04:00
Benoit Jacob
6dc478fd77 doc typo 2010-10-14 10:19:46 -04:00
Benoit Jacob
65c01e2bf7 JacobiSVD doc fix 2010-10-14 10:17:40 -04:00
Benoit Jacob
8f0e80fe30 JacobiSVD:
* fix preallocating constructors, allocate U and V of the right size for computation options
  * complete documentation and internal comments
  * improve unit test, test inf/nan values
2010-10-14 10:14:43 -04:00
Gael Guennebaud
e85a3857f0 import BLAS test suite 2010-10-14 13:46:01 +02:00
Gael Guennebaud
47197065da compilation fix 2010-10-14 10:19:55 +02:00
Benoit Jacob
bcb9068268 fix bug #44: use VERIFY_IS_APPROX instead of exact comparison to please x87 extended precision 2010-10-13 09:40:57 -04:00
Benoit Jacob
c8ecc897c0 add EIGEN_TEST_X87 option 2010-10-13 09:04:59 -04:00
Gael Guennebaud
3a2bb7f782 fix compilation and warnings with fcc 4.0.1 2010-10-13 10:21:28 +02:00
Gael Guennebaud
bf402dd9b8 add the possibility to disable OpenGL testing 2010-10-12 20:23:52 +02:00
Benoit Jacob
8eb0fc1e72 remove SVD class (was bad code taked from elsewhere)
Use JacobiSVD for now.
We do plan to reintroduce a bidiagonalizing SVD asap.
2010-10-12 10:19:59 -04:00
Benoit Jacob
dbedc70012 Jacobi improvements:
* add fixed-size vectorized path
  * add missing restrict keywords
  * use innerStride()
  * allow vectorization even if innerStride()>1, if PacketSize==1
    (think of the case of rows of std::complex<double>)
2010-10-12 09:58:53 -04:00
Benoit Jacob
12a152031d fix the Jacobi bug, expand unit test 2010-10-12 09:43:40 -04:00
Benoit Jacob
75e60121f4 add Jacobi unit test. jacobi_5 fails, exposing bug #39. 2010-10-12 09:12:36 -04:00
Gael Guennebaud
0308f64515 add support for uniform of double 2010-10-12 11:04:19 +02:00
Gael Guennebaud
fb30bb9e59 uncomment commented line for debug 2010-10-12 10:40:42 +02:00
Gael Guennebaud
20be8ad91e add support for uniforms 2010-10-12 10:39:28 +02:00
Benoit Jacob
b8bb804007 set ColPivHouseholderQR as default preconditioner for JacobiSVD 2010-10-11 21:00:42 -04:00
Benoit Jacob
5c3d21693b implement JacobiSVD::solve() and expand the unit test 2010-10-11 15:36:04 -04:00
Gael Guennebaud
0cae73d1eb add the prototype of all level2 functions 2010-10-08 23:31:57 +02:00
Gael Guennebaud
eb105cace8 compilation fix 2010-10-08 22:51:10 +02:00
Benoit Jacob
d229f99ba2 adapt Quaternion to JacobiSVD API changes. 2010-10-08 10:42:41 -04:00
Benoit Jacob
8ba8d90063 add option to compute thin U/V.
By default nothing is computed. You have to ask explicitly for thin/full U/V if you want them.
2010-10-08 10:42:40 -04:00
Benoit Jacob
6fad2eb97b Rework JacobiSVD api / template parameters.
There is now an integer QRPreconditioner template parameter, defaulting to full-piv QR.
Since we have to special-case each QR dec anyway, a template template parameter didn't add much value here.
There is an option NoQRPreconditioner if you know your matrices are already square (auto-detected for fixed-size matrices).
2010-10-08 10:42:32 -04:00
Benoit Jacob
58e0cce0f7 merge backout 2010-10-08 10:42:25 -04:00
Benoit Jacob
4a98cada26 Backed out changeset 2334291157
Sorry Thomas, these doc fixes are no longer relevant with the JacobiSVD API changes, and they are preventing me from applying my patches cleanly.
2010-10-08 10:42:06 -04:00
Gael Guennebaud
a76ce042e6 MSVC for windows mobile does not have the errno.h file 2010-10-07 18:09:15 +02:00
Gael Guennebaud
af22364988 an attempt to fix compilation on windows mobile 2010-10-07 17:54:46 +02:00
Gael Guennebaud
d9c131de5b remove the Taucs backend : Taucs is not maintained anymore and the backend was crap anyway 2010-10-06 17:42:17 +02:00
Gael Guennebaud
423f88aa1e improve FindCholmod 2010-10-06 17:38:02 +02:00
Romain Bossart
c6503e03eb Updates to the Sparse unsupported solvers module.
* change Sparse* specialization's signatures from <..., int Backend> to <..., typename Backend>. Update SparseExtra accordingly to use structs instead of the SparseBackend enum.
* add SparseLDLT Cholmod specialization
* for Cholmod and UmfPack, SparseLU, SparseLLT and SparseLDLT now use ei_solve_retval and have the new solve() method (to be closer to the 3.0 API).

* fix doc
2010-10-04 20:56:54 +02:00
Gael Guennebaud
e3d01f85b2 extend OpenGL support module with true unit tests and support for Transform, Translation, etc. 2010-10-06 13:28:13 +02:00
Gael Guennebaud
b5f32830fd fix geometry tutorial regarding the need to specify the "mode" 2010-10-06 13:27:14 +02:00
Gael Guennebaud
01fad14d78 mark LLT/LDLT solveInPlace func internal and rm their boolean returned value 2010-10-05 15:56:50 +02:00
Thomas Capricelli
2334291157 fix doc 2010-10-04 04:08:32 +02:00
Benoit Jacob
71f023de3e fix compilation on ubuntu 9.04's version of gcc 4.3 (yes, wtf) 2010-09-27 09:57:57 -04:00
Radu Bogdan Rusu
94ea1eed9a fix warning 2010-09-27 09:56:54 -04:00
Hauke Heibel
327ed3d1d3 Added a note to the Gram Schmidt code and improved some formatting. 2010-09-25 14:15:35 +02:00
Hauke Heibel
72d4d45133 Merge. 2010-09-24 17:34:49 +02:00
Hauke Heibel
316dadc8e4 Fixed some SVD issues.
Make the SVD's output unitary.
Improved unit tests.
Added an assert to the SVD ctor to check whether rows>=cols.
2010-09-24 17:32:44 +02:00
Hauke Heibel
053261de88 Make the SVD's output unitary and improved unit tests. 2010-09-24 16:28:20 +02:00
Benoit Jacob
1c54514bfc merge 2010-09-23 09:53:21 -04:00
Benoit Jacob
c253cc3d53 SVD:
* fix unit test for rectangular matrices.
 * enforce that rows >= cols since various places in the code assume that.
2010-09-23 09:51:08 -04:00
Hauke Heibel
947f84633b Fixed bad memory access in the SVD. 2010-09-23 11:15:36 +02:00
Hauke Heibel
62bf04b339 Fixed bad memory access in the SVD. 2010-09-23 11:15:36 +02:00
Gael Guennebaud
82e4a16759 remove superfluous #ifdef 2010-09-15 15:24:21 +02:00
Benoit Jacob
77c943670e add cmakelists for 2 subdirs and make sure all subdirs are installed (GLOB) 2010-09-14 04:11:15 -04:00
Gael Guennebaud
91e9344be9 fix vectorization logic and code of cross3 which was never enabled.. 2010-09-08 14:10:01 +02:00
Gael Guennebaud
f9123df772 fix unitialized quaternion 2010-09-08 12:57:33 +02:00
Gael Guennebaud
d591b0466d add a bench to compare various transformation methods 2010-09-07 18:21:36 +02:00
Gael Guennebaud
9bb75937cc fix += return by value like operations 2010-09-06 11:51:42 +02:00
Gael Guennebaud
62eb4dc99b noalias was wrongly skipping automatic transposition 2010-09-02 19:18:34 +02:00
Gael Guennebaud
4824db6444 add the possibility to extend QuaternionBase 2010-09-02 17:28:07 +02:00
Eamon Nerbonne
d17bb02ccd Fixes mingw32 compile issues 2010-09-02 10:38:23 +02:00
Gael Guennebaud
e0ea25fc21 add missing copyrights 2010-09-01 12:59:38 +02:00
Gael Guennebaud
b49dde01dc fix bad mat * mat * scalar when the implicit conversion operator to a Matrix is used 2010-08-31 09:54:38 +02:00
Hauke Heibel
dd94f10442 Docs: Improved the docs for writing functions taking Eigen types.
- Removed the wrong statement about the MSVC compiler.
- Reformulated "simple functions" usage.
- Reformulated the summary paragraph about writable parameters.
2010-08-27 08:19:09 +02:00
Gael Guennebaud
dcff9ba785 fix bad "using typename" 2010-08-25 13:34:35 +02:00
Gael Guennebaud
cb7a72d5b0 Fix Sun CC parsing of Eigen/Core. In particular,
I moved all the block related methods to a plugin file. This also
significantly reduce code verbosity.
2010-08-25 13:09:56 +02:00
Benoit Jacob
e17d17cea3 didn't want to commit that bench change. 2010-08-24 10:57:22 -04:00
Benoit Jacob
bd8d06033d make a couple of typedefs public so stuff compiles 2010-08-24 10:53:33 -04:00
Gael Guennebaud
a47bbf664c fix 4x4 SSE inversion when storage orders don't match 2010-08-24 13:00:59 +02:00
Gael Guennebaud
548ecc2fe5 update inverse unit test to highlight another bug in SSE 4x4 inversion code 2010-08-24 12:38:20 +02:00
Gael Guennebaud
ad9a7c69bc fix inversion of 4x4 unaligned matrices 2010-08-24 12:28:42 +02:00
Benoit Jacob
6924d4eec5 update this test to build against current eigen.
remove the 'normal' path as it was not compiling anymore and I couldn't see the point of it (?)
2010-08-23 23:21:25 -04:00
Gael Guennebaud
6261f4629f add TriangularMatrix::conjugate to be consistent since we have adjoint 2010-08-23 23:38:35 +02:00
Jitse Niesen
474c2996bd Docs: add section on resolving the aliasing issue. 2010-08-23 17:23:30 +01:00
Jitse Niesen
d1111d625c Docs: Typos in ArrayBase doxygen comments 2010-08-23 11:44:51 +01:00
Jitse Niesen
103b9351fd Docs: Add references to TopicClassHierarchy 2010-08-22 18:28:19 +01:00
Jitse Niesen
a6da803873 Document DenseCoeffsBase 2010-08-22 17:30:31 +01:00
Hauke Heibel
60aad09878 Fixed DiagonalMatrix assignment. 2010-08-21 16:34:46 +02:00
Hauke Heibel
92b1674c79 Fixed typos. 2010-08-19 20:11:06 +02:00
Hauke Heibel
610d79e686 Simplified to product templates to a minimum of template parameters.
Removed the ei_is_any_projective helper and added ei_transform_traits.
2010-08-19 20:02:46 +02:00
Hauke Heibel
a64aabf73c Removed unused code. 2010-08-19 19:33:13 +02:00
Hauke Heibel
55c7848877 Matrix product refactoring (rhs products only).
Added strong inlines required for MSVC for proper inlining.
Added specializations for DiagonalMatrix products to RotationBase.
Added left- and righ-hand-side products with DiagonalMatrix to Transform.
RHS Transform products now return Matrix objects only.
Split the geo_transformations unit test. Some tests were not made for projectivities.
Removed unused variables from main.h that caused warnings.
2010-08-19 19:25:35 +02:00
Gael Guennebaud
d4b664c4cd fix ugly conversion from double[2] to complex 2010-08-19 14:47:58 +02:00
Gael Guennebaud
5354ffbb4f add missing specialization for vector * selfadjoint 2010-08-19 14:05:21 +02:00
Gael Guennebaud
6264755dd3 merge 2010-08-18 15:34:55 +02:00
Gael Guennebaud
ab41c18d60 quickly mention how to solve a sparse problem 2010-08-18 15:33:58 +02:00
Benoit Jacob
216c9125e9 disable NonLinearOptimization test until it's fixed 2010-08-18 09:11:01 -04:00
Gael Guennebaud
ddbbd7065d * disable unalignment detection when vectorization is not enabled
* revert MapBase unalignment detection
2010-08-18 09:35:55 +02:00
Hauke Heibel
85fdcdf055 Fixed Geometry module failures.
Removed default parameter from Transform.
Removed the TransformXX typedefs.
Removed references to TransformXX from unit tests and docs.
Assigning Transforms to a sub-group is now forbidden at compile time.
Products should now properly support the Isometry flag.
Fixed alignment checks in MapBase.
2010-08-17 20:03:50 +02:00
Benoit Jacob
87aafc9169 fix Transform() constructor taking a Transform with other mode.
Not really tested as the geometry tests are currently busted.
2010-08-16 12:30:33 -04:00
Benoit Jacob
19d9c835e0 fix warnings 2010-08-16 11:11:43 -04:00
Gael Guennebaud
b37551f62a further improve compilation error message for array+=matrix 2010-08-16 11:13:02 +02:00
Gael Guennebaud
c625a6a85b improve compilation error message for array+=matrix and the likes 2010-08-16 11:07:17 +02:00
Gael Guennebaud
453d54325e fix declaration of AffineTransformType in Translation 2010-08-16 10:44:27 +02:00
Gael Guennebaud
ba212aeaa9 fix missdetection of GLUT 2010-08-16 09:50:24 +02:00
Gael Guennebaud
aa2b46aa91 allow vectorization of mat44.col() by adding a InnerPanel boolean
template parameter to Block
2010-07-23 16:29:29 +02:00
Gael Guennebaud
853c0e15df slightly generalize the alignment assert in MapBase 2010-08-16 09:41:07 +02:00
Gael Guennebaud
8566ef805b remove the aligned bit flag for non vectorizable types 2010-08-16 09:38:49 +02:00
Benoit Jacob
3a30a2bc3e forgot to remove a #endif 2010-08-13 14:03:38 -04:00
Benoit Jacob
b80d9dd42e fix determination of number of registers on sse:
__i386__ was not defined by MSVC 2010.
fixed as (2*sizeof(void*)).
also move that to SSE/ and let the default for unknown arch's be just 8.
2010-08-13 13:55:28 -04:00
Benoit Jacob
8bbe556e35 merge the backout 2010-08-11 00:06:31 -04:00
Benoit Jacob
97ced33b33 Backed out changeset 40f6e26a24
See thread on mailing list: "InnerPanel change mis-detects alignment?"
2010-08-11 00:04:06 -04:00
Jitse Niesen
76fbe94279 Document EIGEN_NO_DEBUG macro.
I needed some doxygen tricks to get this to work, so it may not be worth it.
2010-08-10 11:37:23 +01:00
Jitse Niesen
530b328769 Aliasing doc: explain that some cases are detected, reverse order examples. 2010-08-08 21:20:14 +01:00
Hauke Heibel
3dd8225862 Added more detailed docs to the QR decompositions classes. 2010-08-05 08:56:19 +02:00
Benoit Jacob
976d7c19e8 some small improvements to the page on functions taking eigen objects.
- make the beginning more precise
 - make the first example be a full selfcontained compiled example, no need for all the others, but having the first one doesn't hurt.
2010-08-04 21:42:32 -04:00
Hauke Heibel
5c7cb3c05c Added more examples to the function writing tutorial including EigenBase, DenseBase, etc. 2010-08-04 17:50:46 +02:00
Hauke Heibel
d558e84f0b Fixed some typos and reformulated a few sentences. 2010-08-04 16:40:33 +02:00
Hauke Heibel
224dd66e10 Added a tutorial on writing functions taking Eigen types. 2010-08-04 12:01:19 +02:00
Benoit Jacob
d90d7a006f fix warnings. The one in Reverse was potentially serious: coeff() methods should return CoeffReturnType, not "Scalar", if the expression is potentially a Lvalue. 2010-08-03 10:38:48 -04:00
Hauke Heibel
cc25edd5de Fixed Affine transform typedef. 2010-08-02 21:33:48 +02:00
Jitse Niesen
508b51cb62 Add page giving an overview of the class hierarchy.
This is mostly copied from the wiki, which in turn copies Benoit's email at
http://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2010/06/msg00576.html
I used ASCII art for the inheritance diagrams for now, but I don't mind
moving to GraphViz/dot as discussed earlier.
2010-08-02 11:36:44 +01:00
Jitse Niesen
a9fe75efc4 Documentation: Start special topic page on aliasing. 2010-07-31 21:37:29 +01:00
Hauke Heibel
7cefa75901 Added static method Identity() to the Translation class. 2010-07-29 17:30:37 +02:00
Hauke Heibel
e92993d7b9 Safeguarded some Transform functions with compile time asserts.
Added missing static Identity() to Rotation2D, AngleAxis.
2010-07-29 16:17:42 +02:00
Hauke Heibel
6b89ee0095 Transform is now per default Projective.
Improved invert() in the Transform class.
RotationBase offers matrix() to be conform with Transform's naming scheme.
Added Translation::translation() to be conform with Transform's naming scheme.
2010-07-29 15:54:32 +02:00
Hauke Heibel
2f0e8904f1 Removed debug outputs. 2010-07-28 10:47:58 +02:00
Kenneth Riddile
b038a4bb71 * added EIGEN_ALIGNED_ALLOCATOR macro to allow specifying a different aligned allocator
* attempted to add support for std::deque by copying and modifying the std::vector implementation...MSVC still fails to compile with the std::deque::resize() "will not be aligned" error...probably missing something simple but I'm not sure how to make it work
2010-07-26 19:06:47 -04:00
Jitse Niesen
1420f8b3a1 Several changes in comments to keep Doxygen happy. 2010-07-25 20:29:07 +01:00
Jitse Niesen
3d9764ee24 Add some more examples for the API documentation.
The only missing examples now are for homogeneous() and hnormalized();
I don't know what they're used for ...
2010-07-24 16:43:07 +01:00
Jitse Niesen
425444428c Add examples for API documentation of block methods in DenseBase. 2010-07-23 22:20:00 +01:00
Jitse Niesen
2b5a0060b4 Add examples for API documentation of MatrixBase::cwiseXxx() methods. 2010-07-23 20:32:33 +01:00
Jitse Niesen
072ee3c07d Set Doxygen config variable INCLUDE_PATH to plugins directory.
This is necessary to get functions like MatrixBase::cwiseAbs() documented;
otherwise doxygen can't find the include file in which they are defined.
2010-07-23 19:57:21 +01:00
Jitse Niesen
ae8425c74c Tutorial page 7: more typical example for .all(), minor copy-editing. 2010-07-23 19:20:10 +01:00
User Martin Senst
145830e067 Add newline at the end of Dense. 2010-07-23 19:00:02 +02:00
Gael Guennebaud
40f6e26a24 allow vectorization of mat44.col() by adding a InnerPanel boolean
template parameter to Block
2010-07-23 16:29:29 +02:00
Jitse Niesen
d0f6b1c21f Tutorial page 6: Fix typo, add table of contents. 2010-07-22 21:52:04 +01:00
Gael Guennebaud
9daa66f262 fix merge conflicts 2010-07-22 17:23:11 +02:00
Gael Guennebaud
5d98fa235d merge with complex branch 2010-07-22 16:57:14 +02:00
Jitse Niesen
403e672587 Extend tutorial page 5: Advanced initialization. 2010-07-22 15:53:21 +01:00
Gael Guennebaud
7020f30da3 sync with default branch 2010-07-22 16:29:35 +02:00
Gael Guennebaud
b9edd6fb85 oops 2010-07-22 16:24:01 +02:00
Gael Guennebaud
96ba7cd655 add an OpenGL module simplifying the way you can pass Eigen's objects to GL 2010-07-22 16:08:58 +02:00
Gael Guennebaud
fa6d36e0f7 fix SparseView: clean the nested matrix type 2010-07-22 15:57:01 +02:00
Hauke Heibel
734469e43f Unified LinSpaced in order to be conform with other setter methods as e.g. Constant. 2010-07-22 14:04:00 +02:00
Gael Guennebaud
c7f40e522e merge 2010-07-22 13:21:06 +02:00
Gael Guennebaud
06250a154c add matlab-like mixed product 2010-07-22 13:19:09 +02:00
Gael Guennebaud
bec3f9bfe4 rename indices to a common scheme 2010-07-22 13:17:39 +02:00
Gael Guennebaud
0916d69ca5 fix inner vectorization logic 2010-07-22 13:17:12 +02:00
Gael Guennebaud
0dfc5b296b fix strict aliasing issue 2010-07-22 13:16:53 +02:00
Gael Guennebaud
8a96b0080d now that we properly support mixing real-complex: clean mixingtypes test 2010-07-22 13:15:49 +02:00
Thomas Capricelli
8e21cef80a fix typo 2010-07-22 13:15:15 +02:00
Gael Guennebaud
4393f20fea fix compilation of quaternion demo 2010-07-21 17:34:32 +02:00
Gael Guennebaud
f1104a3b0f fix mandelbrot compilation, and make it use Array instead of Matrix 2010-07-21 17:13:02 +02:00
Gael Guennebaud
35f0bc70d8 fix a strict aliasing issue with gcc 4.3 2010-07-20 22:43:55 +02:00
Gael Guennebaud
b5f2b7d087 fix storage order request 2010-07-20 22:08:48 +02:00
Gael Guennebaud
7dbbc6ffd1 fix static allocation of workspace 2010-07-20 17:06:14 +02:00
Gael Guennebaud
ced1a45f82 add NEON ploaddup and pcplxflip functions 2010-07-20 14:24:01 +02:00
Gael Guennebaud
193eedbfe2 one more fix for openmp 2010-07-20 14:19:00 +02:00
Gael Guennebaud
d7fa09bf05 improve block-size heuristic 2010-07-20 13:23:50 +02:00
Gael Guennebaud
4824ac1363 fix openmp version 2010-07-20 13:23:19 +02:00
Gael Guennebaud
b551a2d77a fix declaration of pack_lhs in trsm 2010-07-20 12:58:22 +02:00
Gael Guennebaud
10a7668035 uncomment commented code for debug 2010-07-20 12:57:46 +02:00
Gael Guennebaud
7b23fad4c9 report a true assert when not checking for an assertion 2010-07-20 12:54:53 +02:00
Gael Guennebaud
44cb1e4802 it appears only the "on the left" case was tested 2010-07-20 10:32:56 +02:00
Gael Guennebaud
872523844a fix trmm and symm wrt lhs packing 2010-07-20 10:06:41 +02:00
Gael Guennebaud
76eb9c9fd9 fix compilation by including file in correct order 2010-07-19 23:32:13 +02:00
Gael Guennebaud
70b1ce11c6 * fix SelfCwiseBinaryOp traits and handling of mixed types
* improve compilation error in case of type mismatch
2010-07-19 23:31:08 +02:00
Gael Guennebaud
8b0b121c9e explicitely disable vectorization for mixed coeff based products 2010-07-19 23:28:57 +02:00
Gael Guennebaud
08c841eb87 fix lhs packing in the case of real * complex products 2010-07-19 23:16:03 +02:00
Gael Guennebaud
1ed4233fd2 port Jacobi to new ei_pset1/ei_pload API 2010-07-19 16:51:38 +02:00
Gael Guennebaud
c2ee454df4 * fix compilation of mixed scalar product
* optimize mixed scalar products
2010-07-19 16:49:09 +02:00
Gael Guennebaud
6e157dd7c6 * fix a couple of remaining issues with previous commit,
* merge ei_product_blocking_traits into ei_gepb_traits
2010-07-19 15:45:13 +02:00
Gael Guennebaud
f8aae7a908 * _mm_loaddup_pd is slow
* optimize SSE ei_ploaddup<Packet4f>
2010-07-19 15:43:27 +02:00
Gael Guennebaud
cd0e5dca9b wip: extend the gebp kernel to optimize complex and mixed products 2010-07-19 08:50:59 +02:00
Gael Guennebaud
45362f4eae update mixing type test 2010-07-15 08:40:09 +02:00
Gael Guennebaud
3f532edc6d update unit test for new API 2010-07-15 08:38:31 +02:00
Gael Guennebaud
1dc9aaaf36 add support for mixing type in trsv 2010-07-13 16:03:49 +02:00
Gael Guennebaud
36d9b51a44 optimize non fused MADD, and add a flatten attribute macro to enforce
inlining within a function
2010-07-13 15:16:34 +02:00
Gael Guennebaud
b72b7ab76f matrix product: move the alpha factor to gebp instead of the packing,
clean some temporaries, etc.
2010-07-12 16:31:46 +02:00
Gael Guennebaud
f8678272a4 mixing types step 3:
- improve support of colmajor by vector and matrix - matrix
- now all configurations are well handled, but the perf are not always very good
2010-07-11 23:57:23 +02:00
Gael Guennebaud
8e3c4283f5 make colmaj * vector uses pointers only 2010-07-11 16:01:48 +02:00
Gael Guennebaud
ff96c94043 mixing types in product step 2:
* pload* and pset1 are now templated on the packet type
* gemv routines are now embeded into a structure with
  a consistent API with respect to gemm
* some configurations of vector * matrix and matrix * matrix works fine,
  some need more work...
2010-07-11 15:48:30 +02:00
Gael Guennebaud
4161b8be67 sync 2010-07-10 22:58:51 +02:00
Gael Guennebaud
e5bc9526f1 * generalize rowmajor by vector
* fix weird compilation error when constructing a matrix with a row by matrix product
2010-07-10 22:53:27 +02:00
Gael Guennebaud
c4ef69b5bd fix compilation: make the check_coordinates* functions const 2010-07-10 22:37:16 +02:00
Benoit Jacob
6dcd373b9d let ei_pset1 use _mm_loaddup_pd. Not a significant speed improvement, but also not a speed regression, and replaces 3 instructions by 1 single instruction. 2010-07-09 18:51:17 -04:00
Konstantinos Margaritis
6ad3f1ab1f Added NEON/Complex.h, ~3.5x faster than scalar std::complex<float>
minor fix in AltiVec Complex.h
2010-07-10 00:09:29 +03:00
Gael Guennebaud
96f9015807 disable MSVC optimization when the underlying compiler is ICC 2010-07-09 19:33:43 +02:00
Gael Guennebaud
b2effa2b2c move ei_conj_if to a more appropriate file 2010-07-09 18:05:57 +02:00
Konstantinos Margaritis
642cc27eb1 forgot to commit ei_p4f_FORWARD; 2010-07-09 18:08:18 +03:00
Konstantinos Margaritis
f6bd508351 forgot to add the Complex.h include for AltiVec. 2010-07-09 17:56:53 +03:00
Konstantinos Margaritis
d9e134c73c Altivec port of Complex.h.
Note: For some reason g++ 4.4 is >200% slower than g++ 4.3 on altivec code.
The same benchmark (bench_gemm) was tested, on the same hardware/OS (G4/Debian testing),
with same CFLAGS. With some code reorganizing I managed to get some minor gain
on 4.4, but I just could not reach 4.3 speed. This is most likely a bug, but I'm waiting
to see if it's fixed on 4.5. I'll look into this a bit more.
2010-07-09 17:54:41 +03:00
Jitse Niesen
26cfe5a958 Be consistent in how the tutorial pages link together. 2010-07-09 11:59:29 +01:00
Jitse Niesen
2c03ca3325 Small changes to tutorial page 2 (matrix arithmetic):
* slightly more extensive discussion of aliasing
* layout: put example code and output side-by-side
* add some links, etc
2010-07-09 11:46:07 +01:00
Gael Guennebaud
b1a17dbfe4 fix a few weird issues with gcc 4.3 32bits and complex<float> 2010-07-09 08:27:58 +02:00
Thomas Capricelli
551cb9b7b4 bench: use of Eigen/Array is deprecated + fix includes for iostream 2010-07-09 03:59:36 +02:00
Gael Guennebaud
504d3a3586 fix SliceVectorizedTraversal for packetsize==1 2010-07-08 23:31:14 +02:00
Gael Guennebaud
51ec188da0 extend vectorization_logic 2010-07-08 23:30:16 +02:00
Carlos Becker
951da96f14 Added more redux types/examples in tutorial and fixed some display issues 2010-07-08 18:16:39 +01:00
Carlos Becker
cb3aad1d91 Reductions/Broadcasting/Visitor Tutorial added to index 2010-07-08 17:45:25 +01:00
Carlos Becker
9852e7b9cb Reductions/Broadcasting/Visitor Tutorial added 2010-07-08 17:42:23 +01:00
Gael Guennebaud
300a226ffa scalars fitting in a single packet requires more work, step 1
* add a, Alignable trait
* update LinearVectorization assignment
2010-07-08 14:27:47 +02:00
Gael Guennebaud
2a1500915a compilation fix 2010-07-08 14:26:00 +02:00
Gael Guennebaud
2066ed91de enabling aligned loads/store for complex<double> is much more tricky,
so the temporary fix is to always perform unaligned load/store
2010-07-07 22:50:19 +02:00
Gael Guennebaud
d89925e6de an attempt to fix wrong unaligned store 2010-07-07 22:35:06 +02:00
Gael Guennebaud
02fd3acd81 update to support mixin types 2010-07-07 19:49:48 +02:00
Gael Guennebaud
31a36aa9c4 support for real * complex matrix product - step 1 (works for some special cases) 2010-07-07 19:49:09 +02:00
Gael Guennebaud
fc3fd8ab57 mention that array = matrix is fine too 2010-07-07 18:10:11 +02:00
Gael Guennebaud
861962c55f sync 2010-07-07 16:44:05 +02:00
Gael Guennebaud
0f2d480af0 add support for complex 2010-07-07 16:41:29 +02:00
Gael Guennebaud
a2415388ef optimized conjugate products for SSE3 2010-07-07 16:37:20 +02:00
Gael Guennebaud
65257f6b29 optimize for SSE3 => significant speed up !! 2010-07-07 15:34:46 +02:00
Gael Guennebaud
dd18b22f0b optimize pmul for complex<double> 2010-07-07 15:29:04 +02:00
Gael Guennebaud
845994f18f optimize gemv for complex<double> and fix gcc alignment issue in 32bits 2010-07-07 15:28:41 +02:00
Gael Guennebaud
e07c0f6bb5 cleanning 2010-07-07 11:41:29 +02:00
Gael Guennebaud
3a7f16a655 typo 2010-07-07 11:13:30 +02:00
Gael Guennebaud
b0896382a3 s/IsVectorized/Vectorizable 2010-07-07 11:10:46 +02:00
Gael Guennebaud
74cf12cbe0 add a compile time error if someone call packet on Diagonal (instead of infinite runtime loop) 2010-07-07 11:07:12 +02:00
Gael Guennebaud
d5e0efaf69 fix vectorization rule of diagonal-product 2010-07-07 11:06:31 +02:00
Gael Guennebaud
c851044eae fix row cwise-prod column in coeff based products...
I really don't know why this worked so far...
2010-07-07 10:52:59 +02:00
Gael Guennebaud
55495dcbae extend product unit tests 2010-07-07 10:50:40 +02:00
Gael Guennebaud
e38fc9692d add a conj_product functor and optimize dot products 2010-07-07 10:00:08 +02:00
Gael Guennebaud
f8d3b4c060 fix mixing types in DiagonalProduct 2010-07-07 09:43:29 +02:00
Gael Guennebaud
bfa606d16f * add a IsVectorized mechanism (instead of packet-size>1...)
* vectorize complex<double>
2010-07-06 23:36:00 +02:00
Gael Guennebaud
38d0a0d5d6 add a unit test for previous bug 2010-07-06 20:54:35 +02:00
Gael Guennebaud
2dba4b7ce7 add a unit test for conj_helper and ei_pconj 2010-07-06 20:54:14 +02:00
Gael Guennebaud
bc57c68cf5 bug fix forgot to conjugate the scalar factor when needed 2010-07-06 20:53:48 +02:00
Gael Guennebaud
e04c3f2cc0 reduce code generation and minor speed up 2010-07-06 19:15:02 +02:00
Gael Guennebaud
d6454788d9 add support for vectorized conjugated products 2010-07-06 19:10:24 +02:00
Gael Guennebaud
291fef5760 fix range 2010-07-06 19:09:31 +02:00
Jitse Niesen
49747fa4a9 Various documentation improvements.
* Add short documentation for Array class
* Put all classes explicitly in Core module (where applicable)
* Section on Modules in Quick Reference Guide
* Put Page 7 after Page 6 in Contents :)
2010-07-06 13:10:08 +01:00
Jitse Niesen
3428d80d20 Small changes to tutorial page 1. 2010-07-06 10:48:25 +01:00
Jens Mueller
d849bc4401 Avoid calling resizeLike, if EIGEN_NO_AUTOMATIC_RESIZING is defined 2010-07-06 10:11:18 +02:00
Jens Mueller
5322b670c8 Add all unsupported modules and fix header file paths 2010-07-06 10:25:52 +02:00
Gael Guennebaud
7d23e7f9f1 indentation 2010-07-06 11:02:01 +02:00
Benoit Jacob
d1243b393e Added tag 3.0-beta1 for changeset 8cfbf33f60 2010-07-06 00:50:30 -04:00
Benoit Jacob
8cfbf33f60 fix the overview page and add mention that the wrong stack alignment issue may have been solved by gcc 4.5 2010-07-06 00:50:16 -04:00
Gael Guennebaud
c69a226192 * extend the Has* packet traits and makes all functor use it
* extend the packing routines to support conjugation
2010-07-05 23:27:54 +02:00
Gael Guennebaud
8db60afb47 oops I did not see that 2010-07-05 21:27:15 +02:00
Gael Guennebaud
e1eccfad3f add intitial support for the vectorization of complex<float> 2010-07-05 16:18:09 +02:00
Konstantinos Margaritis
1505221263 add check for non x86 platforms, we get a compile error on arm/powerpc without the check
(there is no known -yet- method to get cpuid, without resolving to kernel /sys interface)
2010-07-05 16:44:41 +03:00
Konstantinos Margaritis
1daf9b11ba check for !x86 platforms, otherwise the BTL benchmark doesn't compile on arm/powerpc 2010-07-05 16:42:11 +03:00
Jitse Niesen
9fa4e9a098 Improve documentation, mostly by adding links to Quick Start Guide. 2010-07-05 10:59:29 +01:00
Gael Guennebaud
efb79600b9 fix warning "type qualifiers ignored on function return type" for long long scalar types 2010-07-05 11:23:05 +02:00
Gael Guennebaud
15a421ef63 char is not necessarily signed.... 2010-07-05 11:15:08 +02:00
Gael Guennebaud
6249d60715 improve packetmath unit test for sum reductions 2010-07-05 10:54:24 +02:00
Gael Guennebaud
fffaa58ac2 fix unaligned workspace in sybb 2010-07-05 10:12:30 +02:00
Gael Guennebaud
8a38047ec5 fix nomalloc_2 issues with ICC and gcc 4.0.1 (and speed up compilation ;) ) 2010-07-04 15:35:21 +02:00
Gael Guennebaud
c201aabf3e comment the workaround of the EIGEN_EMPTY_STRUCT_CTOR workaround for gcc 4.3 2010-07-04 15:26:58 +02:00
Hauke Heibel
282b5614ed Relaxed precision test. 2010-07-04 14:04:07 +02:00
Gael Guennebaud
0c25f868c7 update topic page on products 2010-07-04 10:37:32 +02:00
Gael Guennebaud
41ea92d355 * update the general TOC
* integrate the old geometry/sparse tutorial into the new one (they are better than nothing)
* remove the old tutorial on the core module
2010-07-04 10:14:47 +02:00
Gael Guennebaud
11329f49f4 suppress warning and add a fixme about this transpose argument 2010-07-03 19:39:29 +02:00
Gael Guennebaud
be1fdbf3af fix openmp for row major destination 2010-07-03 12:52:39 +02:00
Hauke Heibel
0d9dc578dd Adapted the MSVC visualizer to the new Dynamic value. 2010-07-03 12:26:53 +02:00
Gael Guennebaud
b4ef323e90 fix bug with openmp 2010-07-03 12:20:13 +02:00
Hauke Heibel
d6791e8f3d Fixed annoying CMake - Qt warning. 2010-07-03 11:52:46 +02:00
Benoit Jacob
5a52f2833f simplify and polish a bit the page 4 / block ops 2010-07-01 20:52:40 -04:00
Benoit Jacob
08c17c412e polish the Array tutorial page 2010-07-01 20:29:13 -04:00
Benoit Jacob
ba7e9a760d actually remove 3.0-beta1 tag 2010-07-01 10:49:25 -04:00
Benoit Jacob
51fae7e57d Removed tag 3.0-beta1 2010-07-01 10:47:03 -04:00
Hauke Heibel
ce1e5e52dd Enable OpenMP testing for MSVC.
Added CMake comments.
2010-07-01 07:28:16 +02:00
Thomas Capricelli
b212227418 shut one more warning 2010-07-01 04:27:45 +02:00
Thomas Capricelli
1399fd9cbd fix compilation issue with clang 2010-07-01 04:26:07 +02:00
Thomas Capricelli
d414ab51f0 oops... fix it better 2010-07-01 03:39:19 +02:00
Thomas Capricelli
2874101b62 fix compilation with icc. Anyway, the use of an enum instead of a
'const bool' is more consistent with the code around.
2010-07-01 03:23:47 +02:00
Thomas Capricelli
04648becf7 fix warnings with old gcc 2010-07-01 03:22:09 +02:00
Jitse Niesen
7d72d4f3c7 Bug fix for NumTraits<T>::lowest() .
std::numeric_limits<T>::min() is the lowest *positive* normalized number
for floating point types.
This fixes the test failure for geo_alignedbox8 for me.
2010-07-01 01:42:31 +01:00
Benoit Jacob
6326f4623a slightly raise the threshold used in this test to accomodate results obtained with gcc 4.1 2010-06-30 19:55:43 -04:00
Benoit Jacob
532aeba308 s/struct/class/g ; bug reported by Thomas 2010-06-30 19:47:26 -04:00
Benoit Jacob
962b30d75e fix linalg tut; remove the old one 2010-06-30 19:27:30 -04:00
Carlos Becker
97f3c7f282 Fixed nullary test not passing on Core Duo 2010-06-30 19:17:29 +01:00
Hauke Heibel
34d79b6a63 Firefox specific style fix. 2010-06-30 18:31:31 +02:00
Hauke Heibel
7b74d376d3 More style fixes. 2010-06-30 18:27:27 +02:00
Hauke Heibel
e1348b9cc9 Slight pimping of the "Basic matrix manipulation" table.
More CSS simplifications.
2010-06-30 18:04:36 +02:00
Manoj Rajagopalan
c64c0f382f Examples for DenseBase::middle{Rows,Cols}() 2010-06-30 11:26:31 -04:00
Benoit Jacob
63287ff08f Added tag 3.0-beta1 for changeset 73db507d15 2010-06-30 10:16:55 -04:00
Benoit Jacob
73db507d15 merge.
first time i see this: someone pushed *between*
my hg pull -u and my hg push ! I guess that means we have very high activity these days. good!
2010-06-30 10:14:09 -04:00
Benoit Jacob
4d4a23cd3e nearly complete page 6 / linear algebra + examples
fix the previous/next links
2010-06-30 10:11:55 -04:00
Carlos Becker
b83225edfb Fixed small typo in arithmetic tutorial 2010-06-30 15:08:25 +01:00
Hauke Heibel
b1741c1dc6 Fixed some doc appearance issue.
Started cleaning up the CSS.
2010-06-30 15:52:00 +02:00
Hauke Heibel
56fe64c15d Fix hover background color for H2.
Align tutorial tables at the top.
2010-06-30 14:05:37 +02:00
Gael Guennebaud
21d940fbe4 fix unsupported module doc 2010-06-30 13:19:54 +02:00
Hauke Heibel
1688b86823 Followed Benoit's comment and removed the Mainpage.dox too. 2010-06-30 13:04:50 +02:00
Gael Guennebaud
020bf9e922 clean the class hierarchy 2010-06-30 13:05:07 +02:00
Hauke Heibel
af9f452299 Removed old doxygen config file. 2010-06-30 12:57:33 +02:00
Hauke Heibel
c66c4b3293 Added exclusion filters. 2010-06-30 12:57:00 +02:00
Jitse Niesen
096c13ea6d Fill in open entries in decompositions table. 2010-06-30 10:41:23 +01:00
Gael Guennebaud
1b8277fc2a update the big linear algebra table (fixes, add notes and definitions) 2010-06-30 10:37:23 +02:00
Gael Guennebaud
a06cd0fb13 it remains only to set the status of RealSchur and EigenSolver 2010-06-29 20:59:23 +02:00
Gael Guennebaud
1f4927a28c update the big table and add an Optimization column 2010-06-29 20:44:51 +02:00
Manoj Rajagopalan
5c58582a08 Renamed DenseBase::{row,col}Range() to DenseBase::middle{Rows,Cols}() 2010-06-29 14:31:39 -04:00
Manoj Rajagopalan
6e5bed69dc Included tests for middleRows() and middleCols() 2010-06-29 12:39:58 -04:00
Gael Guennebaud
82c4a755af disable empty struct trick for buggy gcc 4.3 2010-06-29 18:17:17 +02:00
Benoit Jacob
e5de9e5226 Remove \nonstable yet. The stability rules for Eigen3 are much simpler:
- all what's not in unsupported/ is considered stable API
    (except internal stuff e.g. expression templates).
2010-06-29 10:10:47 -04:00
Benoit Jacob
76152e9844 start linear algebra tutorial 2010-06-29 10:02:33 -04:00
Benoit Jacob
3bd421e073 fix potential warning 2010-06-29 10:02:10 -04:00
Carlos Becker
deba829911 Added Block tutorial to docs index 2010-06-29 14:23:49 +01:00
Jitse Niesen
3070164525 Fix name clash in "m.block(i,j,m,n)" where m has two meanings.
Fix simple typos in tutorial.
2010-06-29 11:42:51 +01:00
Konstantinos Margaritis
cf3616b2c0 AltiVec signed integer pmadd removed, proved to be 2x slower than the scalar trait(!). 2010-06-28 21:24:55 +03:00
Carlos Becker
97889a7f46 Added Block Operations tutorial and code examples 2010-06-28 18:42:59 +01:00
Carlos Becker
82e2e8b13a Modified Array Class tutorial, added examples 2010-06-28 18:42:09 +01:00
Carlos Becker
bdef7eb656 Added doxygen info for .matrix() and .array() 2010-06-28 18:38:28 +01:00
Benoit Jacob
086ad93295 start a topic page on decompositions, with a big table.
still have to write the _tutorial_ on decompositions.
2010-06-28 10:43:11 -04:00
Gael Guennebaud
dbefd7aafb * update redux section
* fix output precision to 3 for the snippets
2010-06-28 13:30:10 +02:00
Gael Guennebaud
768bdd08c8 fix bad tests 2010-06-28 01:01:29 +02:00
Gael Guennebaud
75da254fc3 * use transpose() instead of row vectors (more common use case)
* add a word about noalias and performance for BLAS users
2010-06-28 00:42:57 +02:00
Gael Guennebaud
aae5994b9e mv comma initializer to page 1 2010-06-28 00:22:47 +02:00
Gael Guennebaud
de1220aa62 add a Transposition section in page 2 2010-06-28 00:05:11 +02:00
Gael Guennebaud
ca29620e25 fix filename 2010-06-27 23:45:37 +02:00
Gael Guennebaud
f98c758f61 fix link 2010-06-27 20:21:12 +02:00
Gael Guennebaud
b5659dc9cf show a more fancy example for the getting started tut 2010-06-27 19:37:16 +02:00
Gael Guennebaud
189d4b51c2 fix unused warning when EIGEN_HAS_FUSE_CJMADD 2010-06-27 17:42:03 +02:00
Benoit Jacob
25f44266a2 fix #146 2010-06-27 08:44:21 -04:00
Gael Guennebaud
f096452dfd Fix cache computation on old Intel CPUs which do not
support the cpuid function 0x4
2010-06-27 00:17:38 +02:00
Gael Guennebaud
5e7bd967cc add the manual Intel's way to query cache info 2010-06-26 23:37:42 +02:00
Manoj Rajagopalan
464fc297cf Included definitions for rowRange() and colRange() member functions of DenseBase 2010-06-26 17:37:17 -04:00
Martin Senst
4b474fdb34 Relax assertion to allow for matrices with cols() == 0 and/or rows() == 0. 2010-07-20 21:25:43 +02:00
Gael Guennebaud
95f2e7f3f5 introduce a new LvalueBit flag and split DenseCoeffBase into three level of accessors 2010-07-21 10:57:01 +02:00
Jitse Niesen
3abbdfd621 Add (set)LinSpaced to quick reference guide. 2010-07-20 21:55:22 +01:00
Jitse Niesen
abd5faf784 Require at least MPFR version 2.3.0, because we use mpfr_signbit.
Code in FindMPFR.cmake is taken from FindEigen2.cmake .
2010-07-19 12:26:52 +01:00
Gael Guennebaud
cac147ba10 add support for determinant on empty matrix 2010-07-19 10:45:06 +02:00
Gael Guennebaud
78d3c54631 add a small bench demoing the possibilities of a direct 3x3 eigen decomposition 2010-07-18 17:26:06 +02:00
Gael Guennebaud
ea27678153 fix compilation of ei_tridiagonalization_inplace_selector for 1x1 matrix 2010-07-18 17:10:11 +02:00
Gael Guennebaud
2a820d41df finish/fix level1 blas, all test pass 2010-07-17 13:49:43 +02:00
Gael Guennebaud
dd27e10360 fix level3 blas: it now passes all computational tests 2010-07-17 11:59:09 +02:00
Gael Guennebaud
2d78023815 fix hemm to not use the imaginary part of the diagonal entries 2010-07-17 11:57:54 +02:00
Gael Guennebaud
cbd6fe323c fix a couple a issue with blas (new TRMM api, and enforece column major) 2010-07-16 23:30:06 +02:00
Gael Guennebaud
f59226e901 fix compilation of blas lib 2010-07-16 22:27:24 +02:00
Gael Guennebaud
4c19024fbf re-enable writing to reversed objects 2010-07-16 22:26:07 +02:00
Gael Guennebaud
fb041c260c fix for empty matrices 2010-07-16 22:25:35 +02:00
Gael Guennebaud
883a8cbb2c disable the optimized 3x3 path for complexes which was not working at all 2010-07-16 18:22:00 +02:00
Gael Guennebaud
6ab9e8632f fix bad fuzzy comparison in 3x3 tridiagonalization 2010-07-16 16:38:58 +02:00
Gael Guennebaud
044424b0e2 fix sum()/prod() on empty matrix making sure this does not affect fixed sized object, extend related unit tests including partial reduction 2010-07-16 14:02:20 +02:00
Gael Guennebaud
6a370f50c7 MPRealSupport was missing 2010-07-15 20:45:45 +02:00
Gael Guennebaud
b08c26aefa merge 2010-07-15 20:41:33 +02:00
Gael Guennebaud
84fdbded4d add support for strictly triangular matrix in trmm though it is not really useful 2010-07-15 20:39:20 +02:00
Gael Guennebaud
87e89fea4e add a support module for MPFR C++ with basic unit testing 2010-07-15 16:29:04 +02:00
Gael Guennebaud
bfbe61454e merge 2010-07-15 09:54:31 +02:00
Gael Guennebaud
cf9edd9958 fix compilation for non trivial types 2010-07-14 23:31:38 +02:00
Gael Guennebaud
b6fac91998 merge 2010-07-14 22:51:53 +02:00
Gael Guennebaud
d4d4382b18 use dummy_precision by default instead of 0 2010-07-14 22:50:03 +02:00
Gael Guennebaud
90d6fc0e28 fix ei_aligned_delete for null pointers and non trivial dtors 2010-07-14 22:49:34 +02:00
Jitse Niesen
b0bd1cfa05 Tutorial page 4: add some text, diversify examples.
Use \verbinclude for output text to disable syntax highlighting.
Give tables consistent look.
2010-07-14 10:16:12 +01:00
Gael Guennebaud
e4f3759c4d add a bench for quaternion multiplication 2010-07-13 13:29:35 +02:00
Jitse Niesen
c36316f284 Change EXPAND_AS_DEFINED doxygen configuration option.
Add macros so that MatrixBase::cwiseProduct() and ArrayBase::min() are
documented, and remove one macro which is no longer used.
2010-07-13 10:14:58 +01:00
Jitse Niesen
140ad0908d Tutorial page 3: add more cwise operations, condense rest. 2010-07-12 22:45:57 +01:00
Christoph Hertzberg
6ba5d2c90c Implemented SSE optimized double-precision Quaternion multiplication 2010-07-12 23:30:47 +02:00
Jitse Niesen
8e776c94c1 Tutorial page 1: Put code and output side-by-side. 2010-07-12 12:02:31 +01:00
Gael Guennebaud
19a70ae939 fix doc compilation on non 32bits systems 2010-07-11 11:01:17 +02:00
Gael Guennebaud
850c6d8a2b fix unused warning 2010-07-11 10:58:58 +02:00
Gael Guennebaud
931027f31b add a utilility to debug cpuid, and makes sure we get 0 if we query an unsupported cpuid function 2010-06-26 23:15:06 +02:00
Gael Guennebaud
d8b1ce664b update the main page and add a TOC 2010-06-26 22:42:14 +02:00
Gael Guennebaud
f3c64c7cce improve ref tables 2010-06-26 22:19:03 +02:00
Benoit Jacob
e078bb2637 big improvements to tutorial, especially page 2 (matrix arithmetic).
add placeholders for some 'special topic' pages.
2010-06-26 14:00:00 -04:00
Gael Guennebaud
1c783e252f extend the quick ref table page 2010-06-26 18:49:50 +02:00
Gael Guennebaud
5c866f2d8c started the quick reference tables 2010-06-26 16:59:18 +02:00
Benoit Jacob
85c2c468df rename file 2010-06-25 20:19:17 -04:00
Carlos Becker
9d44005916 add initial versions of pages 2 and 3 of the tutorial: matrix arithmetic and the array class 2010-06-25 20:16:12 -04:00
Benoit Jacob
4338834e33 add tutorial page 1 - the Matrix class
+ 3 examples
2010-06-25 10:04:35 -04:00
Benoit Jacob
a90575514a int main() is a standard main() prototype, and makes for cleaner examples 2010-06-25 10:04:10 -04:00
Benoit Jacob
67d79c6751 adapt to change: lu() now gives partial piv LU, here we want fullPivLu() 2010-06-25 10:02:39 -04:00
Gael Guennebaud
eb4095d41a extend the eigen 2 to 3 guide 2010-06-25 15:32:01 +02:00
Gael Guennebaud
ec07c4109d add default parameters for InnerStride/OuterStride to be
able to simply write OuterStride<> instead of OuterStride<Dynamic>
2010-06-25 14:48:16 +02:00
Gael Guennebaud
4056db01e7 use const Scalar& instead of Scalar for function arguments 2010-06-25 13:52:23 +02:00
Gael Guennebaud
686689e9cf comment all disabled MSVC warnings 2010-06-25 13:31:07 +02:00
Gael Guennebaud
75b6d2b2f8 fix very annoying warning (gcc 4.3): type qualifiers ignored on function return type 2010-06-25 13:20:34 +02:00
Gael Guennebaud
01553c419e fox blcok size computation for fixed size objects 2010-06-25 11:44:55 +02:00
Gael Guennebaud
e313826890 add mixed sparse-dense outer product 2010-06-25 11:36:38 +02:00
Gael Guennebaud
1927b4dff5 Fix use of nesting types in SparseTranspose and split the big SparseProduct.h file 2010-06-25 10:26:24 +02:00
Gael Guennebaud
28e64b0da3 email change 2010-06-24 23:21:58 +02:00
Gael Guennebaud
002f7114d1 add support for oski 2010-06-24 23:21:45 +02:00
Gael Guennebaud
88e7a572fd makes sure to test small sizes 2010-06-24 23:06:21 +02:00
Gael Guennebaud
99e4afd43e makes SparseView a true sparse expression and fix use of nesting types 2010-06-24 22:48:48 +02:00
Gael Guennebaud
f3b875e434 fix infinite loop 2010-06-24 22:18:09 +02:00
Gael Guennebaud
566867428c - add a low level mechanism to provide preallocated memory to gemm
- ensure static allocation for the product of "large" fixed size matrix
2010-06-24 21:44:24 +02:00
Gael Guennebaud
e039edcb42 fix temporary creation rule 2010-06-24 19:21:25 +02:00
Gael Guennebaud
b22fc6cdc3 bug fix in gemv:
solution always use a temporary in dst.innerStride != 1
even though this is not needed when packet_size == 1....
2010-06-24 17:51:25 +02:00
Gael Guennebaud
7e836ccb4c unit test fix for default to row major 2010-06-24 17:49:51 +02:00
Gael Guennebaud
6be06745df block householder : minor optimization 2010-06-24 17:48:38 +02:00
Gael Guennebaud
905beb0953 fix symm 2010-06-24 16:42:43 +02:00
Gael Guennebaud
af38bccd3d fix syrk 2010-06-24 16:26:27 +02:00
Gael Guennebaud
e499646c74 fix vectorization logic test 2010-06-24 15:38:14 +02:00
Gael Guennebaud
19f2f53e2c fix compilation when default to row major 2010-06-24 15:13:41 +02:00
Gael Guennebaud
d44fce501b fix computation of blocking sizes for small triangular matrices 2010-06-24 11:50:28 +02:00
Hauke Heibel
0068d3ccf6 Added version testing for MSVC. 2010-06-24 10:05:24 +02:00
Hauke Heibel
22a6cb2dc0 Fix compilation when the memory layout is RowMajor. 2010-06-24 09:56:59 +02:00
Hauke Heibel
83f1b747e7 Fixed MSVC cpuid. 2010-06-24 09:55:53 +02:00
Gael Guennebaud
0a42f8c876 fix compilation when EIGEN_CPUD is not defined 2010-06-24 09:45:17 +02:00
Gael Guennebaud
8beb60bf63 fix EIGEN_CPUID for i386 & PIC, still remains to fix the MSVC version 2010-06-24 09:29:43 +02:00
Gael Guennebaud
98fec45d3c btl: add a trmm action and update eigen interface 2010-06-23 22:10:49 +02:00
Gael Guennebaud
546587c7d3 default to Intel's API by default 2010-06-23 17:14:06 +02:00
Gael Guennebaud
e1a6bad087 fix cache queries for non core2 CPU ;) 2010-06-23 16:34:51 +02:00
Gael Guennebaud
37dcdb1ed6 add missing typename 2010-06-22 23:43:12 +02:00
Gael Guennebaud
b284bb8bba add a spmv mini becnhmark for Eigen, GMM++, ublas, mtl4, and oski 2010-06-22 21:39:55 +02:00
Gael Guennebaud
b4fe53f561 * makes all product use the new API to set the blocking sizes
* fix an issue preventing multithreading (now Dynamic = -1 ...)
2010-06-22 16:08:35 +02:00
Gael Guennebaud
fd9a9fa0ae slightly optimize computeProductBlockingSizes by explicitely precomputing what is known at compile time 2010-06-22 11:10:38 +02:00
Hauke Heibel
3ae0eee0b8 merge 2010-06-22 09:31:26 +02:00
Hauke Heibel
d132b5b061 Correct the options computation for RowMajor matrices. 2010-06-22 09:30:08 +02:00
Gael Guennebaud
6ff28eb3cf forgot to include this file in my previous commit 2010-06-22 08:59:02 +02:00
Gael Guennebaud
98686ab86c fix in case we don't know how to query the L1/L2 cache sizes 2010-06-21 23:44:20 +02:00
Gael Guennebaud
0212eec23f simplify and optimize block sizes computation for matrix products. They
are now automatically computed from the L1 and L2 cache sizes which are
themselves automatically determined at runtime.
2010-06-21 23:28:50 +02:00
Hauke Heibel
4bac6fbe1e The intrin.h header needs to be included after cmath in order to prevent warnigns.
Fixed (hopefully) final Index realted warnings.
2010-06-21 18:39:24 +02:00
Hauke Heibel
80b6e5f278 Added include reuqired for __cpuid. 2010-06-21 16:43:31 +02:00
Gael Guennebaud
4cd38b333c make bench_gemm print out the queried cache sizes 2010-06-21 12:07:05 +02:00
Gael Guennebaud
e54635da11 add functions to query the L1 and L2/L3 cache sizes 2010-06-21 11:59:37 +02:00
Hauke Heibel
7196777b74 Added missing typename. 2010-06-21 11:39:11 +02:00
Hauke Heibel
dc6ad5e25b More Index related stuff. 2010-06-21 11:36:00 +02:00
Hauke Heibel
5f65a89f49 Compilation fix. 2010-06-21 08:58:23 +02:00
Hauke Heibel
a1af6e1151 This does hopefully really raise the warning/error limit. 2010-06-21 07:41:40 +02:00
Hauke Heibel
8239c3b85b Fix compilation. 2010-06-21 07:37:59 +02:00
Hauke Heibel
bb46a45340 Finally fixed the matrix function/exponential warning.
Index fixes.
2010-06-20 23:13:24 +02:00
Hauke Heibel
69b50047d6 Raise the error/warning limit. 2010-06-20 22:38:36 +02:00
Gael Guennebaud
52165ba55a compilation fix 2010-06-20 22:27:35 +02:00
Hauke Heibel
f34eaa2628 Next try - more Index fixes. 2010-06-20 21:44:25 +02:00
Hauke Heibel
546b802b77 Still fixing warnings. 2010-06-20 20:16:45 +02:00
Hauke Heibel
cb11f2f8a6 Fix compilation of some tests as well as more warnings. 2010-06-20 18:59:15 +02:00
Hauke Heibel
f1679c7185 Utilize Index in all unit tests. 2010-06-20 17:37:56 +02:00
Hauke Heibel
e402d34407 More Index realted warnings. 2010-06-20 15:52:34 +02:00
Hauke Heibel
7548708848 Silence index warnings in triangular unit test.
Silence index warnings in FFT module.
2010-06-20 14:00:14 +02:00
Hauke Heibel
9a6967d9ba Attempt to fix MatrixExponential/Function related warnings. 2010-06-20 13:17:57 +02:00
Hauke Heibel
aeb12b417d Silence indexing warning. 2010-06-20 13:17:37 +02:00
Gael Guennebaud
e3853353fb fix array_comp *= array_real 2010-06-20 00:35:33 +02:00
Gael Guennebaud
7fd8418b19 finish to merge Array into Core:
- mv Array/* into Core/
- merge Functors.h files, and move Norms.h into Dot.h
2010-06-19 23:36:38 +02:00
Gael Guennebaud
575ac5409c add missing support for std::pow(array,scalar) 2010-06-19 23:17:07 +02:00
Gael Guennebaud
eba418a458 remove reference to the dead Array module 2010-06-19 23:00:22 +02:00
Gael Guennebaud
17af8c763d fix compilation of sparse tests 2010-06-19 15:24:39 +02:00
Hauke Heibel
b1103c5767 Fixed spare unit test. 2010-06-19 13:58:07 +02:00
Gael Guennebaud
6db6e358f5 add the possibility to set the cache size at runtime 2010-06-18 23:25:57 +02:00
Gael Guennebaud
f85a1cf5df optimize SparseMatrix iterator 2010-06-18 16:47:41 +02:00
Benoit Jacob
f0a6d56f07 fix linking errors with multiply defined functions 2010-06-18 09:01:34 -04:00
Jitse Niesen
9d4b16c1d1 QuickStart examples: shorten var names, remove superfluous 'using'. 2010-06-18 10:43:22 +01:00
Gael Guennebaud
729960e465 add missing files 2010-06-18 11:36:30 +02:00
Gael Guennebaud
ece48a6450 split the Sparse module into multiple ones, and move non stable parts to unsupported/
(see the ML for details)
2010-06-18 11:28:30 +02:00
Gael Guennebaud
22d07ec2e3 Add blocking inside HouseholderQR based on code from Vincent Lejeune.
This is all internal stuff for now.
2010-06-17 18:30:47 +02:00
Gael Guennebaud
bc99c82d17 add an inplace householder QR dec function in preparation for a block version 2010-06-17 17:27:52 +02:00
Gael Guennebaud
3acd007f9d more compilation fixes for ICC 2010-06-17 17:25:18 +02:00
Gael Guennebaud
9637574e2b compilation fix for ICC 2010-06-17 16:56:42 +02:00
Gael Guennebaud
ab6a044d0d eigenvalues: documentation fixes 2010-06-17 14:34:10 +02:00
Jitse Niesen
9196b6b659 Add second example to QuickStart guide.
Also, some changes suggested by Keir and Benoit on mailing list.
2010-06-17 12:12:40 +01:00
Gael Guennebaud
7fdf218951 makes trmv works with the triangular matrix on the right 2010-06-17 10:17:22 +02:00
Gael Guennebaud
6bff339cc5 add unit tests for other generalized variants 2010-06-17 10:16:15 +02:00
Gael Guennebaud
43086d12d2 implement other variants 2010-06-17 10:11:38 +02:00
Gael Guennebaud
db160f2e0b warn users other variants are not implemented yet... (will do it very soon) 2010-06-16 23:55:08 +02:00
Gael Guennebaud
74006a9fe9 * decouple the generalized selfadjoint eigenvalue problem to the standard one
* uses named values instead of bools
2010-06-16 23:48:16 +02:00
Gael Guennebaud
197ce96c00 typo 2010-06-16 17:23:39 +02:00
Benoit Jacob
42c62c8876 fix #126, part 2/2: the checkTransposeAliasing() assertion was always compiled, for all expressions,
even for expressions that are known at compile time to not need it because they don't involve any transposing.
This gave 'controlling condition is constant' warnings on ICC, and potentially worse, this could generate a lot
of useless code per-expression if the compiler failed to realize that the condition was constant.
2010-06-16 09:23:32 -04:00
Benoit Jacob
2d1ae6fa08 fix #126, part 1/2: fix the return type of coeff() on direcaccess xprs: was amounting to
const (const Scalar&)

which really doesn't make sense.
2010-06-16 09:21:14 -04:00
Benoit Jacob
d0d62e4437 fix #139, exactly the same issue as #138, this time in Assign.h: const Index is not a compile-time constant, must use enum. 2010-06-16 07:37:52 -04:00
Benoit Jacob
404aa963d9 fix #138: const bool is (rightly) not considered a compile-time constant by ICC, use enum. 2010-06-16 07:32:44 -04:00
Jitse Niesen
8438719111 Compilation fix for matrix_exponential test: add 'typename'. 2010-06-16 11:07:40 +01:00
Gael Guennebaud
9726824f7c improve trmm unit test and fix several bugs in trmm 2010-06-15 23:38:21 +02:00
Gael Guennebaud
2e792d1f42 * make the triangular matrix * matrix product works with trapezoidal matrices
* extend the trmm unit test for unit diagonal
2010-06-15 22:00:34 +02:00
Benoit Jacob
134ca4acb3 packet math functions:
- take const Packet& args like the other packet funcs
 - SSE specializations: make them be actual template specializations
2010-06-15 08:29:21 -04:00
Hauke Heibel
7958797648 Ups, fixed a little ugly bug. 2010-06-15 12:37:54 +02:00
Hauke Heibel
99d952466f This scalar needs to be passed by ref to preserve its alignment. 2010-06-15 10:26:12 +02:00
Hauke Heibel
e5aa6a466b Fixed 64bit/Index related warnings in the matrix functions module. 2010-06-15 09:57:41 +02:00
Hauke Heibel
0afb1e80c7 Really fix #123. 2010-06-14 23:02:49 +02:00
Gael Guennebaud
3cabd0c417 fix issue 135 (SparseBlock::operator= for SparseMatrix) 2010-06-14 16:26:33 +02:00
Benoit Jacob
2d65f5d3cd remove extra semicolon; 2010-06-14 09:06:27 -04:00
Benoit Jacob
d788627b54 rename:
EIGEN_SIZE_MIN    ---> EIGEN_SIZE_MIN_PREFER_DYNAMIC
  EIGEN_MAXSIZE_MIN ---> EIGEN_SIZE_MIN_PREFER_FIXED
and make sure to use the latter in products xprs to determine the inner size.
2010-06-14 09:05:08 -04:00
Hauke Heibel
a54772250f Fixes bug #123. 2010-06-14 14:33:10 +02:00
Daniel Lowengrub
8673f68fd8 merged 2010-06-14 14:17:19 +03:00
Jitse Niesen
c2f6cbab8d Fix compilation of docs after changes in Eigenvalues module.
Clean-up after revision 469382407c
.
2010-06-14 10:16:01 +01:00
Daniel Lowengrub
af5117dbd5 fixed a bug in the DenseBase InnerIterator ctor. 2010-06-14 02:18:36 +03:00
Daniel Lowengrub
dcd39a96e1 added the SparseView class. 2010-06-14 02:16:46 +03:00
Jitse Niesen
9e00697ccc First draft for the 5-minute quick start guide to kick off discussions. 2010-06-13 22:39:27 +01:00
Gael Guennebaud
9ffc0f6975 an attempt to fix 133 2010-06-13 23:29:44 +02:00
Gael Guennebaud
f159613210 compilation fix 2010-06-13 22:53:53 +02:00
Hauke Heibel
eb95c57a9f Fixed another enum related warning. 2010-06-12 19:42:16 +02:00
Hauke Heibel
058f7d3486 Fixed another enum related warning. 2010-06-12 15:21:11 +02:00
Hauke Heibel
91c7af28a8 Remove printouts. 2010-06-12 15:16:39 +02:00
Hauke Heibel
340ac9ea9d Fixed warnings regarding enums. 2010-06-12 13:24:02 +02:00
Gael Guennebaud
03331552a9 add a info() function in LLT to report on succes/faillure 2010-06-12 10:12:22 +02:00
Gael Guennebaud
a25749ade9 add missing overload of operator= in SparseVector 2010-06-12 01:01:12 +02:00
Benoit Jacob
f5b1b6b351 undo 314bfa1375
, the right fix was made as part of the Dynamic -> -1 change, the bug was that in Map, the InnerStrideAtCompileTime could be 0, which doesn't make sense. The 0 value in Stride should not have been forwarded as-is.
2010-06-11 08:38:30 -04:00
Benoit Jacob
d72d538747 merge my Dynamic -> -1 change 2010-06-11 08:04:06 -04:00
Benoit Jacob
bdd7c6c88a change the value of Dynamic to -1, since the index type is now configurable.
remove EIGEN_ENUM_MIN/MAX, implement new macros instead
2010-06-11 07:56:50 -04:00
Benoit Jacob
52e8c42a00 unsplit this test: was compiling 16 times the same thing! Need to find another way. Suggestion: should compile the stuff once into a binary library, or properly split into different tests with different code. 2010-06-11 07:15:34 -04:00
Hauke Heibel
00267e3a47 Added some verbosity on failures in order to get an idea of what is goind wrong on GCC 4.3. 2010-06-11 12:13:29 +02:00
Hauke Heibel
f48af91c7e For 1x1 matrices we really need to check the abs diff of the determinants. 2010-06-11 08:08:12 +02:00
Hauke Heibel
cedea2aba4 Fixed warnings regarding missing assignment operator. 2010-06-11 07:59:59 +02:00
Gael Guennebaud
988aaed964 merge 2010-06-10 23:30:43 +02:00
Gael Guennebaud
5b192930b6 add runtime API to control multithreading 2010-06-10 23:30:15 +02:00
Jitse Niesen
4d597e4654 Merge. 2010-06-10 21:28:10 +01:00
Jitse Niesen
fcab4c951d Add line to prevent compiler warning on unused variables. 2010-06-10 21:26:23 +01:00
Gael Guennebaud
842b54fe80 make the cache size mechanism future proof by adding level 2 parameters 2010-06-10 22:11:31 +02:00
Jitse Niesen
54235879a9 Make test slightly fuzzy to account for effect of extended precision. 2010-06-10 19:18:19 +01:00
Gael Guennebaud
986f65c402 merge 2010-06-10 16:44:24 +02:00
Gael Guennebaud
469382407c * Make HouseholderSequence::evalTo works in place
* Clean a bit the Triadiagonalization making sure it the inplace
  function really works inplace ;), and that only the lower
   triangular part of the matrix is referenced.
* Remove the Tridiagonalization member object of SelfAdjointEigenSolver
  exploiting the in place capability of HouseholdeSequence.
* Update unit test to check SelfAdjointEigenSolver only consider
  the lower triangular part.
2010-06-10 16:39:46 +02:00
Gael Guennebaud
d2d7465bcf merge 2010-06-10 11:00:47 +02:00
Gael Guennebaud
d2779a1a8e fix warning with gcc 4.3 2010-06-10 10:59:06 +02:00
Gael Guennebaud
dad19c4173 compilation fix for gcc 4.2 2010-06-10 10:55:49 +02:00
Hauke Heibel
941ca80b80 Adapted the determinant test for rank 1 matrices with zero determinant. 2010-06-10 10:06:14 +02:00
Gael Guennebaud
f8683c409f generalized eigendecomposition doc 2010-06-10 09:44:52 +02:00
Gael Guennebaud
41e5625f96 clean general symm eigensolver 2010-06-10 09:34:49 +02:00
Hauke Heibel
3f388282ae Fixes geo_transformations_3 unit test. 2010-06-10 00:23:11 +02:00
Gael Guennebaud
8855c4e264 fix unit test when GSL is enabled 2010-06-10 00:19:45 +02:00
Gael Guennebaud
8692ccc5fb Fix generalized symm eigensolver (I don't know why the eigenvectors were normalized) 2010-06-10 00:04:33 +02:00
Hauke Heibel
bcf738811e Added missing return statement. 2010-06-10 00:02:10 +02:00
Hauke Heibel
56e585efcc Fixed language issue. 2010-06-09 17:20:31 +02:00
Hauke Heibel
2b7b549e9e Fix #131. 2010-06-09 17:16:05 +02:00
Gael Guennebaud
e242ac9345 fix LDLT, now it really only uses a given triangular part! 2010-06-09 14:01:06 +02:00
Gael Guennebaud
201bd253ad fix ldlt unit test 2010-06-09 13:18:10 +02:00
Hauke Heibel
8cc02169fd Fix devision by zero warning. 2010-06-09 09:48:06 +02:00
Hauke Heibel
45d3b405eb Fixed many MSVC warnings. 2010-06-09 09:30:22 +02:00
Gael Guennebaud
50e43bc75a * add Transpositions to PermutationMatrix conversion
* make PartialPivLu uses the  Transpositions class
2010-06-08 22:23:11 +02:00
Trevor Irons
684656d41c added inline to setL1Cache functions to avoid shared object compile error 2010-06-08 10:56:50 -06:00
Hauke Heibel
fb3fcd0919 Disabled warning caused by declspec(align()). 2010-06-08 20:21:55 +02:00
Hauke Heibel
8b0da2de64 Fix stable_norm compilation. 2010-06-08 20:09:39 +02:00
Hauke Heibel
1c9b7a8d9f Fighting for a green dashboard! Next warning's gone. 2010-06-08 16:02:22 +02:00
Hauke Heibel
4c5778d29d Made the supression of unused variables portable.
EIGEN_UNUSED is not supported on non GCC systems.
2010-06-08 15:52:00 +02:00
Hauke Heibel
2a64fa4947 Eigen types must always be passed by reference in order to retain memory alignment. 2010-06-08 13:49:40 +02:00
Gael Guennebaud
4b5d359c3a improve/fix stable_norm unit test 2010-06-08 13:29:27 +02:00
Hauke Heibel
626afe8b62 Fixed integer type warnings. 2010-06-08 10:06:14 +02:00
Hauke Heibel
bda40da002 Fixed GCC compilation. 2010-06-08 09:37:13 +02:00
Hauke Heibel
f6d26bf6dc Fixed more warnings. 2010-06-08 00:41:33 +02:00
Hauke Heibel
04274f6793 Fixed eigensolver warning. 2010-06-08 00:05:20 +02:00
Gael Guennebaud
f3a568c81d remove ei_ prefix of public global functions, and s/cpu/l1 2010-06-07 19:05:30 +02:00
Gael Guennebaud
727376b5f4 compilation fix (std::sqrt(int) does not exist) 2010-06-07 18:55:39 +02:00
Gael Guennebaud
88cd6885be Add a proof concept API to configure the blocking parameters at runtime.
After validation of the final API I'll update the other products to use it.
2010-06-07 16:35:25 +02:00
Gael Guennebaud
7726cc8a29 clean old stuff used to support precompilation inside a binary lib 2010-06-07 14:47:20 +02:00
Gael Guennebaud
bfeba41174 Add a Transpositions class to ease the representation and
manipulation of permutations as a sequence of transpositions.
Make LDLT use it.
2010-06-04 23:17:57 +02:00
Jitse Niesen
1ff1bd69ac Schur decomposition of 1-by-1 always converges. 2010-06-04 09:40:35 +01:00
Jitse Niesen
9178e2bd54 Add info() method which can be queried to check whether iteration converged. 2010-06-03 22:59:57 +01:00
Jitse Niesen
ed73a195e0 Refactor compute() by splitting off two smaller private methods. 2010-06-03 22:29:11 +01:00
Gael Guennebaud
e64460d5d0 LDLT: make it honors the Lower/Upper directive and make it works inplace 2010-06-03 22:22:14 +02:00
Gael Guennebaud
4159db979d make LDLT uses only the lower triangular part 2010-06-03 21:33:47 +02:00
Gael Guennebaud
d92de9574a fix sparse LDLT with complexes 2010-06-03 11:56:08 +02:00
Gael Guennebaud
8350ab9fb8 * remove ei_index, and let ei_traits propagate the index types
* add an Index type template parapeter to sparse objects
2010-06-03 08:41:11 +02:00
Hauke Heibel
e40852d282 Fixes #104. 2010-06-02 19:17:41 +02:00
Jitse Niesen
38d8352b7b Add field m_maxIterations; break loop when this limit is exceeded. 2010-06-02 17:31:02 +01:00
Gael Guennebaud
9ff0d67156 fix typos (oops) 2010-06-02 17:56:35 +02:00
Gael Guennebaud
8710bd23e7 clean the ambiguity with insertBack and add a insertBackByOuterInner function 2010-06-02 13:32:13 +02:00
Gael Guennebaud
143e6ab9d0 improve aliasing detection for inverse and add unit test 2010-06-02 10:12:13 +02:00
Gael Guennebaud
4ebb80490a implicit conversion to scalar for inner product 2010-06-02 09:45:57 +02:00
Gael Guennebaud
314bfa1375 fix issue #128 : inner stride can also be 0 in which case it means 1... 2010-06-01 22:51:47 +02:00
Jitse Niesen
ab2b33e802 Add cast to aliasing check.
Otherwise, one of the geo tests fails to compile. Now there are some compiler
warnings about aliasing and type-punned pointers that I don't understand.
2010-06-01 17:45:58 +01:00
Jitse Niesen
e3e2380548 Make all compute() methods return a reference to *this. 2010-06-01 17:40:51 +01:00
Trevor Irons
4c6d182c42 Addressess small compile error with OpenMP 2010-06-01 07:09:40 -06:00
Benoit Jacob
e54faba198 merge the backing-out of the stupid RetByVal change, and implement a simple
aliasing check in inverse, that catches simple cases like x = x.inverse()
2010-06-01 09:17:50 -04:00
Benoit Jacob
3e95609cd4 Backed out changeset 641d968a9a 2010-06-01 09:01:39 -04:00
Benoit Jacob
6ce22a61b3 oops, remove extra 'typename' 2010-05-30 16:41:16 -04:00
Benoit Jacob
aaaade4b3d the Index types change.
As discussed on the list (too long to explain here).
2010-05-30 16:00:58 -04:00
Benoit Jacob
faa3ff3be6 tests:
* change test_is_equal so it just checks for equality, doesn't try anymore to allow to ignoring the difference between col and row vectors.
   (needed for the upcoming Index types change)
 * in ei_assert, don't report on cerr if we're inside of VERIFY_RAISES_ASSERT
2010-05-30 16:00:09 -04:00
Benoit Jacob
42f1b7d470 finish the change of adding .sh extensions to scripts 2010-05-30 15:58:11 -04:00
Benoit Jacob
641d968a9a * Make ReturnByValue have the EvalBeforeAssigningBit and explicitly
enforce this mechanism (otherwise ReturnByValue bypasses it).
 (use .noalias() to get the old behavior.)
* Remove a hack in Inverse, futile optimization for 2x2 expressions.
2010-05-30 13:43:08 -04:00
Anton Gladky
09a1b7f7e1 Fixes the problem, described here:
http://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2010/05/msg00154.html
2010-05-28 10:18:37 +02:00
Gael Guennebaud
39c568445c simplify a using statement 2010-06-01 13:59:21 +02:00
Gael Guennebaud
0116261407 make BenchTimer compatible with 2.0 branch 2010-06-01 13:57:38 +02:00
Gael Guennebaud
e2097c55f8 fix issue #125 - *norm() return RealScalar and not Scalar 2010-05-31 22:46:18 +02:00
Jitse Niesen
8dc947821b Allow user to compute only the eigenvalues and not the eigenvectors. 2010-05-31 18:17:47 +01:00
Jitse Niesen
609941380a Change skipU argument to computeU - this reverses the meaning.
See "skipXxx / computeXxx parameters in Eigenvalues module" on mailing list.
2010-05-31 16:48:41 +01:00
Jitse Niesen
c21390a611 Define non-const operator() in Reverse; enable test for this.
Introduction of DenseCoeffBase (revision bfdc1c4973
) meant that non-const
operator() is only defined if DirectAccess is set. This caused the line
"m.reverse()(1,0) = 4;" in MatrixBase_reverse.cpp to fail at compile-time.
Not sure this is correct solution; perhaps we should disallow this? Or make
Reverse DirectAccess with a negative stride - would that break something?
2010-05-31 14:42:04 +01:00
Jitse Niesen
07a65dd02b Fix stupid compilation error in test. 2010-05-31 11:48:47 +01:00
Jitse Niesen
db8631b66a Guard with assert against using decomposition objects uninitialized. 2010-05-30 21:49:35 +01:00
Jens Mueller
48b8ace517 Fix SparseMatrix/SparseVector::sum()
SparseMatrix/SparseVector::sum() uses Map to compute the sum. But Map expects a
pointer.
2010-05-27 17:02:24 +02:00
Manoj Rajagopalan
a240f83216 Fix to ProductBase::evalTo() in order to get matrix multiplication working for numeric
types that don't have implicit conversion from int
2010-05-26 13:00:55 -04:00
Thomas Capricelli
4a2d6ece2e fix readcost for complex types 2010-05-26 02:33:28 +02:00
Jitse Niesen
e7dc772554 Respect MaxRowsAtCompileTime in HouseholderSequence::evalTo().
This fixes the failing test nomalloc_4.
Also remove a print inserted for debugging in schur_real test.
2010-05-25 12:40:42 +01:00
Jitse Niesen
e7d809d434 Update eigenvalues() and operatorNorm() methods in MatrixBase.
* use SelfAdjointView instead of Eigen2's SelfAdjoint flag.
* add tests and documentation.
* allow eigenvalues() for non-selfadjoint matrices.
* they no longer depend only on SelfAdjointEigenSolver, so move them to
  a separate file
2010-05-24 17:43:50 +01:00
Jitse Niesen
8a3f552e39 Return matrices by constant reference where possible.
This changes the return type of:
* eigenvectors() and eigenvalues() in ComplexEigenSolver
* eigenvalues() in EigenSolver
* eigenvectors() and eigenvalues() in SelfAdjointEigenSolver
2010-05-24 17:43:27 +01:00
Jitse Niesen
7a43a4408b Replace local variables by member variables in compute() methods.
This is to avoid dynamic memory allocations in the compute() methods of
ComplexEigenSolver, EigenSolver, and SelfAdjointEigenSolver where possible.
As a result, Tridiagonalization::decomposeInPlace() is no longer used.
Biggest remaining issue is the allocation in HouseholderSequence::evalTo().
2010-05-24 17:43:06 +01:00
Jitse Niesen
68820fd4e8 Use ReturnByValue mechanism for HessenbergDecomposition::matrixH(). 2010-05-24 17:36:13 +01:00
Jitse Niesen
eb3ca68684 Change return type of matrixH() method to HouseholderSequence.
This method is a member of Tridiagonalization and HessenbergDecomposition.
2010-05-24 17:35:54 +01:00
Thomas Capricelli
76dd0e5314 fix some warnings 2010-05-22 19:17:04 +02:00
Thomas Capricelli
79e9e3f24c erm.. use EIGEN_ONLY_USED_FOR_DEBUG() as it already exists. 2010-05-21 18:13:59 +02:00
Thomas Capricelli
618640bf2b fix another warning 2010-05-21 02:14:46 +02:00
Thomas Capricelli
00a3d07795 display actual/expected warning if ei_isApprox() fails 2010-05-21 02:13:50 +02:00
Thomas Capricelli
aadea5ae56 fix a warning 2010-05-21 02:13:16 +02:00
Thomas Capricelli
c1d005e976 introduce a new macro EIGEN_ARG_UNUSED(arg) and use it in some places to
silent some warnings (from clang)
2010-05-21 02:05:25 +02:00
Thomas Capricelli
742bbdfa57 clang/llvm is now good enough. I can compile a project using those (one of
the binary segfaults though, and i think it's related..)
2010-05-21 02:03:43 +02:00
Thomas Capricelli
4daba0750e fix some warnings with clang 2010-05-21 01:46:17 +02:00
Thomas Capricelli
2ab446695b fix some compilation issues with clang (and hopefully bring eigen more
close to std ?)
2010-05-21 01:39:33 +02:00
Thomas Capricelli
17d080edf2 clang shocks on this.
According to people on #llvm, this is indeed not allowed by c++ standard:

[01:33] <coppro> what good would mutable do on a reference?
[01:33] <dgregor> orzel: gcc is wrong to allow "mutable" on references
[01:33] <coppro> just remove mutable; it won't damage the code at all
[01:34] <dgregor> "The mutable specifier can be applied only to names of
class data members (9.2) and cannot be applied to
[01:34] <dgregor> names declared const or static, and cannot be applied to
reference members."
[01:34] <coppro> constness is not passed from an object to the referents of
its members anyways
2010-05-21 01:37:48 +02:00
Thomas Capricelli
b9bcd93ddc fix a compilation pb with clang (it's actually surprising gcc did not complain) 2010-05-20 03:53:09 +02:00
Hauke Heibel
cec297f77b Disabled to __forceinline warning - it creates too many spurious errors and we disabled it only for the unit test (see also the code comment). 2010-05-19 19:35:42 +02:00
Hauke Heibel
39edf8e2bf I was not really aware of the implications on fixed size types when the strong inlining is not present. We really need it on MSVC! 2010-05-19 18:57:38 +02:00
Gael Guennebaud
05910b7996 merge 2010-05-19 16:51:07 +02:00
Gael Guennebaud
188171b991 merge 2010-05-19 16:49:56 +02:00
Gael Guennebaud
64cbd45266 minor chnages in Taucs and Cholmod backends 2010-05-19 16:49:05 +02:00
Hauke Heibel
6c18246a80 DenseBase is implemented as a class, not a struct. 2010-05-19 16:44:28 +02:00
Gael Guennebaud
2b6153d3ed simplify inner product 2010-05-19 16:37:17 +02:00
Gael Guennebaud
bf09fe55ed fix selfadjoint to dense 2010-05-19 16:35:34 +02:00
Hauke Heibel
f0283c13e8 Applied tiny Qt related fixes. 2010-05-19 16:32:47 +02:00
Benoit Jacob
08fbfa93e0 make the cmake options EIGEN_DEFAULT_TO_ROW_MAJOR and disabling EIGEN_SPLIT_LARGE_TESTS work also for unsupported tests 2010-05-18 08:59:39 -04:00
Benoit Jacob
1c04484a01 bug fix, since the last storage order changes, this InnerSize calculation was wrong 2010-05-18 08:24:06 -04:00
Benoit Jacob
5250c4395c compilation fix: const T ---> typename ei_makeconst<T>::type
(error was appearing when building tests with alignmnet disabled)

What is this stuff still doing in MatrixBase.h? Shouldn't it move to DenseBase.h? How are Array blocks compiling?
2010-05-18 08:19:23 -04:00
Gael Guennebaud
cf6d3162cc cache outer size in Block => x1.5 speed up for a.block() = b.block() 2010-05-17 16:54:17 +02:00
Gael Guennebaud
0f3bcf853f fix mixing types in inner product 2010-05-14 08:55:56 +02:00
Gael Guennebaud
6d08301dcc add regression test for previous fix 2010-05-13 23:34:04 +02:00
Gael Guennebaud
42a1c983c1 fix bug in sliced redux 2010-05-13 23:22:18 +02:00
Gael Guennebaud
c55761e015 make inner product return a 1x1 matrix 2010-05-12 18:11:05 +02:00
Benoit Jacob
82d898083f fix compilation error thanks to test case by Trevor Irons, and expand unit test 2010-05-09 13:20:46 -04:00
Benoit Jacob
6624b93d67 add important comment and move stride helpers to DenseCoeffsBase.h 2010-05-09 09:41:54 -04:00
Cyrille Berger
8f076f6817 fix installation of global headers in case the src path contains 'src' 2010-05-08 17:55:55 -04:00
Benoit Jacob
0928c40f68 rename Coeffs.h -> DenseCoeffsBase.h 2010-05-08 16:02:13 -04:00
Benoit Jacob
7cbb84b046 move the strides API to DenseCoeffsBase,
and various fixes to make stuff compile after my big changes
2010-05-08 16:00:05 -04:00
Benoit Jacob
0e2a480466 use CoeffReturnType 2010-05-08 15:58:27 -04:00
Benoit Jacob
eda2795f51 use modern ei_first_aligned function, dont try compiling coeffRef() on rvalue expressions. 2010-05-08 15:57:56 -04:00
Benoit Jacob
5deda97413 remove bogus test that was failing 2010-05-08 15:56:52 -04:00
Benoit Jacob
65bd1652b1 let Diagonal have the DirectAccessBit, using an inner stride 2010-05-08 14:19:04 -04:00
Benoit Jacob
bfdc1c4973 introduce DenseCoeffsBase: this is where the coeff / coeffRef / etc... methods go.
Rationale: coeffRef() methods should only exist when we have DirectAccess. So a natural thing to do would have been to use enable_if, but since there are many methods it made more sense to do the "enable_if" for the whole group by introducing a new class. And that also that the benefit of not changing method prototypes.
2010-05-08 13:45:31 -04:00
Benoit Jacob
d03779f75f fix CwiseUnaryView: it shouldn't have the AlignedBit, but it should have the DirectAccessBit and corresponding strides API. 2010-05-08 13:42:41 -04:00
Jitse Niesen
2d74f1ac92 Document SelfAdjointEigenSolver and add examples. 2010-05-04 17:11:32 +01:00
Hauke Heibel
6ea6276f20 Quiet MSVC. 2010-05-04 14:06:41 +02:00
Jitse Niesen
38021b08c1 Merge. 2010-05-02 21:51:27 +01:00
Jitse Niesen
afed0ef90d Document Tridiagonalization class, remove unused types. 2010-05-01 17:52:16 +01:00
Benoit Jacob
8f249e8b54 fix compilation: const (T&) != const T& , use ei_makeconst 2010-04-30 14:28:35 -04:00
Benoit Jacob
cf4f90ccea fix #116 and remove debug cout's 2010-04-30 11:58:17 -04:00
Benoit Jacob
38facbd55b kill the LeastSquares module.
I didn't even put it in Eigen2Support because it requires several other modules. But if you want we can always create a new module, Eigen2Support_LeastSquares...
2010-04-29 10:40:52 -04:00
Benoit Jacob
664f2d4508 dont try passing --version to qcc 2010-04-29 08:04:42 -04:00
Benoit Jacob
d3f97f7582 forgot hg add 2010-04-29 07:30:00 -04:00
Benoit Jacob
5d63d2cc4b * kill the retval typedefs, instead introduce ei_xxx_retval which does the job automatically in 99% cases and can be specialized
* add real/imag/abs2 global functions for Array
* document ei_global_math_functions_filtering_base
* improve unit tests
2010-04-28 22:42:34 -04:00
Benoit Jacob
e277586958 Complete rework of global math functions and NumTraits.
* Now completely generic so all standard integer types (like char...) are supported.
** add unit test for that (integer_types).
* NumTraits does no longer inherit numeric_limits
* All math functions are now templated
* Better guard (static asserts) against using certain math functions on integer types.
2010-04-28 18:51:38 -04:00
Jitse Niesen
d9c1224133 Simplify computation of eigenvectors in EigenSolver.
* reduce scope of declarations
* use that low = 0 and high = size-1
* rename some variables
* rename hqr2_step2() to computeEigenvectors()
* exploit that ei_isMuchSmallerThan takes absolute value of arguments
2010-04-26 17:43:16 +01:00
Jitse Niesen
024995dbca Use topRows() and rightCols() in ComplexSchur and RealSchur. 2010-04-26 16:59:18 +01:00
Jitse Niesen
4f83d6ad19 Remove doc/snippets/MatrixBase_minor.cpp because minor() was removed. 2010-04-26 16:35:38 +01:00
Carlos Becker
34b3cdb82c Added EIGEN_DONT_PARALLELIZE preprocessor directive 2010-04-26 17:08:54 +02:00
Hauke Heibel
bf71b466e9 Removed ambiguity between Map and Matrix Options template parameter. 2010-04-26 16:59:04 +02:00
Hauke Heibel
17dbe6c743 Added file extensions to our unit test scripts to prevent MSVC from failing to build because of name clashes. 2010-04-26 13:31:58 +02:00
Hauke Heibel
18c70b12d7 Fixed a warning. 2010-04-26 13:31:16 +02:00
Carlos Becker
c4dda79904 Fixed stablenorm test, condition was not met when running tests 2010-04-26 00:20:20 +02:00
Benoit Jacob
ce09b4ddfc compile 2010-04-25 17:10:28 -04:00
Konstantinos Margaritis
9337f371d2 (proper commit this time)
replaced _mm_prefetch in GeneralBlockPanelKernel.h, with ei_prefetch() inline function.
Implemented NEON and AltiVec versions, copied SSE version over from GeneralBlockPanelKernel.h.
Also in GCC case (or rather !_MSC_VER) it's implemented using __builtin_prefetch().
NEON managed to give a small but welcome boost, 0.88GFLOPS -> 0.91GFLOPS.
2010-04-24 00:58:44 +03:00
Konstantinos Margaritis
5acf46bd12 Backed out changeset 6972c140f7 2010-04-24 00:57:10 +03:00
oem
6972c140f7 replaced _mm_prefetch in GeneralBlockPanelKernel.h, with ei_prefetch() inline function.
Implemented NEON and AltiVec versions, copied SSE version over from GeneralBlockPanelKernel.h.
Also in GCC case (or rather !_MSC_VER) it's implemented using __builtin_prefetch().
NEON managed to give a small but welcome boost, 0.88GFLOPS -> 0.91GFLOPS.
2010-04-24 00:44:14 +03:00
Benoit Jacob
e3e34b5920 remove MakeBase, use ei_dense_xpr_base instead
(yes, it was only used in dense xprs anyway)
2010-04-23 12:16:30 -04:00
Benoit Jacob
a16ba80bfa * remove ei_block_direct_access_status
* remove HasDirectAccess / NoDirectAccess constants
2010-04-23 11:36:22 -04:00
Benoit Jacob
58e7297859 * remove class DenseDirectAccessBase
* remove member XprBase typedefs, use ei_dense_xpr_base
* remove member _HasDirectAccess typedefs, use ei_has_direct_access
2010-04-23 10:27:15 -04:00
Benoit Jacob
1dd27ce280 merge 2010-04-23 09:06:28 -04:00
Benoit Jacob
f22ade8ee4 restrict operator[] to vectors, not matrices. 2010-04-23 09:05:46 -04:00
Benoit Jacob
c29b431ad9 remove eigen_gen_credits script 2010-04-22 20:59:19 -04:00
Benoit Jacob
4502afeedf remove disabled/ directory. It's useless. It remains in the hg history anyways. 2010-04-22 20:56:33 -04:00
Benoit Jacob
a4f9ca44ab add minor to Eigen2Support 2010-04-22 20:49:01 -04:00
Benoit Jacob
2362eadcdd remove Minor
adapt 3x3 and 4x4 (non-SSE) inverse paths
2010-04-22 20:40:31 -04:00
Benoit Jacob
abbe260905 remove USING_PART_OF_NAMESPACE_EIGEN, leaving it in Eigen2Support.
improve porting-Eigen2-to-3 docs
2010-04-22 18:27:13 -04:00
Benoit Jacob
ef789fe0d2 forgot to hg add... 2010-04-22 14:32:28 -04:00
Benoit Jacob
bc22f4da9d * fix Eigen2Support, was not including VectorBlock.h
* move the corners support stuff to a new Block.h there
* expand the unit test
2010-04-22 14:31:39 -04:00
Benoit Jacob
00c716d20e merge 2010-04-22 14:11:44 -04:00
Benoit Jacob
9962c59b56 * implement the corner() API change: new methods topLeftCorner() etc
* get rid of BlockReturnType: it was not needed, and code was not always using it consistently anyway
* add topRows(), leftCols(), bottomRows(), rightCols()
* add corners unit-test covering all of that
* adapt docs, expand "porting from eigen 2 to 3"
* adapt Eigen2Support
2010-04-22 14:11:18 -04:00
Hauke Heibel
27a4a748cb MSVC runs into problems when a forward declaration is using a different template type name than the actual declaration.
This fixes the recent issues we observed on MSVC systems.
2010-04-22 13:56:06 +02:00
Adolfo Rodriguez Tsouroukdissian
28dde19e40 - Added problem size constructor to decompositions that did not have one. It preallocates member data structures.
- Updated unit tests to check above constructor.
- In the compute() method of decompositions: Made temporary matrices/vectors class members to avoid heap allocations during compute() (when dynamic matrices are used, of course).

These  changes can speed up decomposition computation time when a solver instance is used to solve multiple same-sized problems. An added benefit is that the compute() method can now be invoked in contexts were heap allocations are forbidden, such as in real-time control loops.

CAVEAT: Not all of the decompositions in the Eigenvalues module have a heap-allocation-free compute() method. A future patch may address this issue, but some required API changes need to be incorporated first.
2010-04-21 17:15:57 +02:00
Benoit Jacob
faf8f7732d merge 2010-04-21 12:31:04 -04:00
Benoit Jacob
e33953b888 fix compilation in Sparse (error introduced yesterday) 2010-04-21 12:28:51 -04:00
Hauke Heibel
2db5387488 Fixed two bad errors on std::vector.
First, MSVC 2010 does not ship a 'fixed'/'adapted' STL.
Second, only under very rare cases we do not even need the aligned_allocator.
2010-04-21 18:21:46 +02:00
Daniel Lowengrub
028bb7ea48 Changed the gdb display format of vectors and added support for quaternions. 2010-04-21 00:10:03 +03:00
Benoit Jacob
4ba032c9ab fix grave bug introduced by me: the low-level matrix-vector product functions can't be fed strided vectors, only strided matrices. 2010-04-20 15:59:17 -04:00
Benoit Jacob
941a7e4ebd oos, remove eval() used for debugging 2010-04-19 13:31:29 -04:00
Benoit Jacob
84d1b2ae3a add platform check for how to link to the standard math library.
This allows to support QNX.
2010-04-19 11:19:22 -04:00
Benoit Jacob
40b2aaa8b1 merge 2010-04-18 22:15:20 -04:00
Benoit Jacob
504a31f643 renaming (MatrixType ---> whatever appropriate)
and documentation improvements
2010-04-18 22:14:55 -04:00
Benoit Jacob
34b14c48f3 shut up stupid gcc 4.5.0 warning 2010-04-18 22:14:03 -04:00
Thomas Capricelli
29a3aec483 erf() is really non standard, better dont pollute eigen with it. 2010-04-19 02:06:11 +02:00
Hauke Heibel
086d5f1ac6 Fixed indentation and removed debug code. 2010-04-18 20:16:39 +02:00
Hauke Heibel
214d5a892d Added support for STL lists with aligned Eigen types. 2010-04-18 20:10:43 +02:00
Hauke Heibel
031932b4ec Disabled erf also for Cygwin where it is not supported and causes errors. 2010-04-18 20:08:56 +02:00
Hauke Heibel
7db0f242ef Disabled unsupported erf on MSVC machines. 2010-04-18 14:37:44 +02:00
Thomas Capricelli
63eaa8948e tests for nonlinear module : use different slots + misc cleaning 2010-04-18 03:47:23 +02:00
Thomas Capricelli
f1deab0e5a introduce ei_erf() for various scalar type 2010-04-18 03:39:22 +02:00
Benoit Jacob
ce32f90fdd clarify help message about make install 2010-04-17 12:10:53 -04:00
Benoit Jacob
ba5b5f6a4b fix compilation 2010-04-17 11:29:25 -04:00
Hauke Heibel
cc33a56140 Added MSVC stack allocation support. 2010-04-17 16:08:17 +02:00
Gael Guennebaud
0326a51f89 fix use of uninitialzed calues 2010-04-17 05:23:23 +02:00
Benoit Jacob
797f63044a oops, forgot to add DenseDirectAccessBase 2010-04-16 14:46:55 -04:00
Benoit Jacob
d9ee28851e fix ei_blas_traits directaccess check: in the case of vectors, having a nontrivial inner stride is OK. 2010-04-16 14:12:53 -04:00
Benoit Jacob
04c663840b * add some 1x1 tests
* temporarily disable tests that strangely fail, with a big FIXME
2010-04-16 12:32:33 -04:00
Benoit Jacob
0ab431d7b8 * merge with mainline
* adapt Eigenvalues module to the new rule that the RowMajorBit must have the proper value for vectors
* Fix RowMajorBit in ei_traits<ProductBase>
* Fix vectorizability logic in CoeffBasedProduct
2010-04-16 11:25:50 -04:00
Benoit Jacob
ff6a46105d * Refactoring of the class hierarchy: introduction of DenseDirectAccessBase, removal of extra _Base/_Options template parameters.
* Introduction of strides-at-compile-time so for example the optimized code really knows when it needs to evaluate to a temporary
* StorageKind / XprKind
* Quaternion::setFromTwoVectors: use JacobiSVD instead of SVD
* ComplexSchur: support the 1x1 case
2010-04-16 10:13:32 -04:00
Gael Guennebaud
ea1a2df370 taucs: make SupernodalMultifrontal the default mode 2010-04-15 12:42:17 +02:00
Gael Guennebaud
0b6b316f18 an attempt to fix compilation with MSVC 2010-04-15 12:36:28 +02:00
Gael Guennebaud
a2324d6265 fix sparse squared norm 2010-04-13 10:40:55 +02:00
Jitse Niesen
614fbe497d Merge. 2010-04-12 18:55:27 +01:00
Jitse Niesen
574ad9efbd Move computation of eigenvalues from RealSchur to EigenSolver. 2010-04-12 18:54:15 +01:00
Jitse Niesen
73d3a27667 RealSchur: Make sure zeros are really zero (cont'd); add default ctor, docs. 2010-04-12 18:14:32 +01:00
Gael Guennebaud
0b0366a53d cholmod: assume selfadjoint matrix by default since selfadjoint flag has been removed 2010-04-09 13:37:05 +02:00
Jitse Niesen
872df22ca4 RealSchur: Make sure zeros are really zero; simplify initFrancisQRStep(). 2010-04-09 11:23:17 +01:00
Gael Guennebaud
1ad6c79467 merge 2010-04-08 13:29:31 +02:00
Gael Guennebaud
7a59f9ae01 make sure that changing CMAKE_INSTALL_PREFIX is properly taken into account 2010-04-08 13:28:21 +02:00
Jitse Niesen
7dea3a33a5 RealSchur: change parameter lists; minor rewrite of computeShift(). 2010-04-07 17:29:12 +01:00
Jitse Niesen
b6829e1d5b RealSchur: use makeHouseholder() to construct the transformation. 2010-04-07 10:27:27 +01:00
Jitse Niesen
cc57df9bea RealSchur: Rename l and n to il and iu. 2010-04-06 18:26:30 +01:00
Jitse Niesen
9fad1e392b RealSchur: split computation in smaller functions. 2010-04-06 17:45:46 +01:00
Jitse Niesen
7dc56b3dfb RealSchur: Use Householder module in Francis QR step. 2010-04-06 16:43:07 +01:00
Jitse Niesen
86df74c765 RealSchur: reduce scope of temporary variables in hqr2(). 2010-04-06 15:26:09 +01:00
Jitse Niesen
dad50338b8 RealSchur: Use PlanarRotation in "found two real eigenvalues" branch. 2010-04-06 15:12:21 +01:00
Jitse Niesen
d88d1cfa62 Merge. 2010-04-02 21:33:34 +01:00
Jitse Niesen
79e1ce6093 RealSchur and EigenSolver: some straightforward renames. 2010-04-02 21:05:32 +01:00
Jitse Niesen
a16a36ecf2 Add tests for real and complex Schur; extend test for Hessenberg.
Make a minor correction to the ComplexSchur class.
2010-04-02 14:32:20 +01:00
Hauke Heibel
9d6afdeb22 ei_psqrt fix for zero input 2010-04-01 15:10:52 +02:00
Jitse Niesen
3a14a13533 Split computation of real Schur form in EigenSolver to its own class.
This is done with the minimal amount of work, so the result is very rough.
2010-04-01 12:32:56 +01:00
Jitse Niesen
8cfa672fe0 Use HessenbergDecomposition in EigenSolver. 2010-03-31 21:50:18 +01:00
Jitse Niesen
1b3f7f2fee Extend documentation and add examples for EigenSolver class. 2010-03-31 11:59:11 +01:00
Benoit Jacob
338ec0390f let the cast functor use the new ei_cast() 2010-03-30 14:51:47 -04:00
Benoit Jacob
16e416b8d7 generalize the idea of the previous commit to all kinds of casts, see this forum thread:
http://forum.kde.org/viewtopic.php?f=74&t=86914
this  is important to allow users to support custom types that don't have the needed conversion operators.
2010-03-30 14:47:45 -04:00
Benoit Jacob
9e0d8697c7 add ei_cast_to_int, we are indeed somethings (e.g. in IO.h) casting scalars to int and the only way to allow users to extend that to their own scalar types that don't have int cast operators, was to allow them specialize ei_cast_to_int_impl. 2010-03-30 14:16:54 -04:00
Benoit Jacob
8f99ae5ea4 move the computation of the number of significant digits to a templated helper struct, that can be specialized to custom types if needed. Should address this request:
http://forum.kde.org/viewtopic.php?f=74&t=86914
2010-03-30 11:38:09 -04:00
Jitse Niesen
e6300efb5c Extend documentation for HessenbergDecomposition. 2010-03-28 17:33:56 +01:00
Thomas Capricelli
0a5c2d8a54 fix misc warnings, more importantly when NDEBUG is defined, assert() is a
nop.
2010-03-27 18:58:29 +01:00
Jitse Niesen
af08770890 Center version number on main page of API documentation. 2010-03-26 12:36:42 +00:00
Manuel Yguel
eb0c921a58 Fix some doc typos. 2010-03-25 16:54:00 +01:00
Thomas Capricelli
df1cbe8c3d fix display of modules list in documentation 2010-03-25 08:50:23 +01:00
Manuel Yguel
671cfb7ad0 Fix wrong header and warnings in polynomialutils.cpp 2010-03-25 03:31:33 +01:00
Manuel Yguel
89f2d5667f Add the possibility to use the polynomial solver of the gsl. 2010-03-25 03:25:47 +01:00
Manuel Yguel
5ef83d6a6c Add missing test files for Polynomials module. 2010-03-25 03:21:52 +01:00
Manuel Yguel
9a4a08da46 Creation of the Polynomials module with the following features:
* convenient functions:
  - Horner and stabilized Horner evaluation
  - polynomial coefficients from a set of given roots
  - Cauchy bounds
* a QR based polynomial solver
2010-03-25 03:15:05 +01:00
Gael Guennebaud
4e871c6c80 blas: fix compilation and build both a shared and static lib 2010-03-24 19:34:18 +01:00
Jitse Niesen
c68098b9be Clean up ComplexSchur::compute() . 2010-03-24 14:10:33 +00:00
Jitse Niesen
13a1b0ba27 Add snippets file which should have been added in the previous commit. 2010-03-24 13:04:03 +00:00
Jitse Niesen
37e17938e9 Extend documentation of ComplexSchur and add examples. 2010-03-23 12:49:09 +00:00
Jitse Niesen
307c428253 Move documentation of MatrixBase methods in MatrixFunctions to module page.
I think that because MatrixFunctions is in unsupported/ and MatrixBase is
not, doxygen does not include the MatrixBase methods defined and documented
in the MatrixFunctions module with the other MatrixBase methods. This is a
kludge, but at least the documentation is not lost.
2010-03-22 13:58:19 +00:00
Jitse Niesen
525d6b655f Merge. 2010-03-21 21:59:00 +00:00
Jitse Niesen
8e5d2b6fc4 Rename Complex in ComplexSchur and ComplexEigenSolver to ComplexScalar
for consistency with the RealScalar type; correct ComplexEigenSolver
docs to take non-diagonalizable matrices into account; refactor
ComplexEigenSolver::compute().
2010-03-21 21:57:34 +00:00
Benoit Jacob
1803db6e84 merge 2010-03-21 11:28:31 -04:00
Benoit Jacob
92da574ec2 * allow matrix dimensions to be 0 (also at compile time) and provide a specialization
of ei_matrix_array for size 0
* adapt many xprs to have the right storage order, now that it matters
* add static assert on expressions to check that vector xprs
  have the righ storage order
* adapt ei_plain_matrix_type_(column|row)_major
* implement assignment of selfadjointview to matrix
  (was before failing to compile) and add nestedExpression() methods
* expand product_symm test
* in ei_gemv_selector, use the PlainObject type instead of a custom Matrix<...> type
* fix VectorBlock and Block mistakes
2010-03-21 11:28:03 -04:00
Gael Guennebaud
8b093dd2df oops, fix symv (innerStride instead of outerStride) 2010-03-20 20:51:44 +01:00
Jitse Niesen
d91ffffc37 Allow ComplexEigenSolver and ComplexSchur to work with real matrices.
Add a test which covers this case.
2010-03-20 17:04:40 +00:00
Hauke Heibel
fbdf16d425 Added x()/y() and z() access functions to translations. 2010-03-19 20:11:40 +01:00
Jitse Niesen
d3e271c47e Extend documentation and add examples for ComplexEigenSolver. 2010-03-19 18:23:36 +00:00
Benoit Jacob
547269da35 fix the flags and matrix options, to always have the right RowMajor bit in the vector case 2010-03-19 02:12:23 -04:00
Benoit Jacob
9dba86df0b merge 2010-03-18 20:11:38 -04:00
Benoit Jacob
089bd89512 compile with gcc 4.5 2010-03-18 20:10:24 -04:00
Jitse Niesen
0ee10f7da4 Document member functions and types of ComplexEigenSolver. 2010-03-18 13:42:17 +00:00
Jitse Niesen
04a4e22c58 API change: ei_matrix_exponential(A) --> A.exp(), etc
As discussed on mailing list; see
http://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2010/02/msg00190.html
2010-03-16 17:26:55 +00:00
Gael Guennebaud
d536fef1bb fix and extend replicate optimization, and add the packet method though it is currently disabled 2010-03-15 10:39:00 +01:00
Hauke Heibel
d68b85744f Replaced strong with weak inlines in CwiseUnaryOp. 2010-03-14 13:01:10 +01:00
Hauke Heibel
6d08f71a2d Removed strong inlines which cannot always be inlined. 2010-03-14 12:09:29 +01:00
Hauke Heibel
0e5a232dae Ups - again a missing typename. 2010-03-14 11:58:44 +01:00
Hauke Heibel
fc20e6fd55 Try to avoid modulo operations in Replicate if possible. 2010-03-13 14:33:39 +01:00
Hauke Heibel
b9644f3323 Propagate fixed size dimensions if available (on MSVC it leads >2.5x speedup for some reductions). 2010-03-13 13:15:27 +01:00
Benoit Jacob
3e08c22028 attempt to fix #101 2010-03-11 12:41:46 -05:00
Hauke Heibel
2a82b162d7 Nest expression within MatrixWrapper by value. 2010-03-10 17:13:07 +01:00
Hauke Heibel
b20b393a4e Enable resizing of Arrays. 2010-03-10 17:12:45 +01:00
Hauke Heibel
dd9ff1b9a6 Fix MSVC warnings. 2010-03-09 09:04:21 +01:00
Benoit Jacob
74a7c5caee implement the idea that row-vectors have the RowMajorBit and col-vectors don't. 2010-03-09 00:16:07 -05:00
Benoit Jacob
b81351cb07 nomalloc: minor cleanup 2010-03-08 21:30:06 -05:00
Adolfo Rodriguez Tsouroukdissian
5a36f4a8d1 Propagate all five matrix template parameters to members and temporaries of decomposition classes. One particular advantage of this is that decomposing matrices with max sizes known at compile time will not allocate.
NOTE: The ComplexEigenSolver class currently _does_ allocate (line 135 of Eigenvalues/ComplexEigenSolver.h), but the reason appears to be in the implementation of matrix-matrix products, and not in the decomposition itself.
The nomalloc unit test has been extended to verify that decompositions do not allocate when max sizes are specified. There are currently two workarounds to prevent the test from failing (see comments in test/nomalloc.cpp), both of which are related to matrix products that allocate on the stack.
2010-03-08 19:31:27 +01:00
Gael Guennebaud
898762529e update the product selection logic to use the Max* sizes 2010-03-08 22:55:58 +01:00
Gael Guennebaud
2af9468dd1 update the product selection logic to use the Max* sizes 2010-03-08 22:54:31 +01:00
Gael Guennebaud
9a3b00c040 add missing cmake directives for arch/Default 2010-03-08 22:15:35 +01:00
Thomas Capricelli
b2e7329356 tests : fix compilation issues, adding <iostream> and removing
<Eigen/Array>
2010-03-08 20:34:24 +01:00
Benoit Jacob
89343a38af * Fix #97 : Householder operations on 1x1 matrices
* Fix VectorBlock on 1x1 "vectors"
* remove useless makeTrivialHouseholder function
2010-03-08 12:37:04 -05:00
Benoit Jacob
4293a4d1af * let a = foo() work when a is a row-vector xpr and foo() returns a ReturnByValue col-vector
* remove a few useless resize() in evalTo() implementations
2010-03-08 10:34:59 -05:00
Mark Borgerding
3565e89be2 minor edit 2010-03-07 23:57:02 -05:00
Mark Borgerding
101cc03176 merge 2010-03-07 23:46:26 -05:00
Mark Borgerding
e31929337e needed different proxy return types for fwd,inv to work around static asserts 2010-03-07 22:05:48 -05:00
Mark Borgerding
5b2c8b77df created FFT::fwd and FFT::inv with ReturnByValue 2010-03-07 21:31:06 -05:00
Hauke Heibel
9fe040ad29 Reintroduced the if-clause for MSVC ei_ploadu via _loadu_. 2010-03-07 14:05:26 +01:00
Gael Guennebaud
aeea00a9cf fix compilation 2010-03-07 12:32:24 +01:00
Gael Guennebaud
3130b7a722 bugcount--, this time trmm 2010-03-06 22:57:50 +01:00
Gael Guennebaud
1958b7eccc stride() => inner/outerStride() 2010-03-06 22:39:15 +01:00
Gael Guennebaud
4402034678 pff I introduced much too many bugs latey, count-- 2010-03-06 22:24:50 +01:00
Gael Guennebaud
61ce1de048 fix symm 2010-03-06 22:15:59 +01:00
Gael Guennebaud
a7d199bf9a fix trsolve 2010-03-06 21:37:14 +01:00
Gael Guennebaud
6f0b96dcf4 fix issue #100 (fix syrk) 2010-03-06 21:16:43 +01:00
Gael Guennebaud
271fc84e47 bugfix in gebp for 32bits x86 2010-03-06 20:52:20 +01:00
Benoit Jacob
c4f8afdf49 #undef minor at the right place 2010-03-06 14:44:57 -05:00
Benoit Jacob
7e2afe7e95 remove the __ARM_NEON__ check there since Konstantinos said he removed it but apparently didn't commit :) 2010-03-06 12:11:08 -05:00
Benoit Jacob
bf0a21a695 * disable static alignment on QCC
* remove obsolete #error
2010-03-06 09:28:58 -05:00
Benoit Jacob
2bd31d3fbc * include Macros.h much earlier: since it takes care of the alignment platform detection, it is needed before we do the vectorization stuff in Eigen/Core !!
* kill EIGEN_DONT_ALIGN_HEAP option (one should use EIGEN_DONT_ALIGN)
* rename EIGEN_DONT_ALIGN_STACK to EIGEN_DONT_ALIGN_STATICALLY. hope it's a better name.
2010-03-06 09:05:15 -05:00
Hauke Heibel
61a14539c7 merge 2010-03-06 11:48:19 +01:00
Benoit Jacob
f03d95348d introduce EIGEN_DONT_ALIGN_STACK (disables alignment attributes) and EIGEN_DONT_ALIGN_HEAP (disables aligned malloc)...
you can still use EIGEN_DONT_ALIGN to do both at once.
2010-03-06 02:17:37 -05:00
Gael Guennebaud
afd7ee759b fix copy pasted comment 2010-03-05 21:35:11 +01:00
Konstantinos Margaritis
273b236f72 Altivec brought up to date. Most tests pass and performance is better than before too! 2010-03-05 22:28:49 +02:00
Hauke Heibel
51b0159c96 Fixed line endings. 2010-03-05 18:11:54 +01:00
Gael Guennebaud
f2a246c225 add a small program to bench all combinations of small products 2010-03-05 17:16:19 +01:00
Gael Guennebaud
c442208358 clean a bit the bench_gemm files 2010-03-05 11:35:43 +01:00
Gael Guennebaud
5f172cd01f add a FIXME 2010-03-05 10:45:29 +01:00
Gael Guennebaud
48d0595c29 * dynamically adjust the number of threads
* disbale parallelisation if we already are in a parallel session
2010-03-05 10:44:31 +01:00
Gael Guennebaud
dd961f8c60 add an option to test ompenmp 2010-03-05 10:22:27 +01:00
Gael Guennebaud
62ac021606 fix openmp version for scalar types different than float 2010-03-05 10:16:25 +01:00
Gael Guennebaud
d13b877014 remove the 1D and 2D parallelizer, keep only the GEMM specialized one 2010-03-05 10:04:17 +01:00
Gael Guennebaud
24ef5fedcd minor cleaning 2010-03-05 09:57:04 +01:00
Gael Guennebaud
279ad44509 merge 2010-03-05 09:46:58 +01:00
Gael Guennebaud
620bd28480 enable posix_memalign for QNX 2010-03-05 09:44:21 +01:00
Gael Guennebaud
7e2683dc39 merge 2010-03-04 18:59:56 +01:00
Gael Guennebaud
0964810fba merge 2010-03-04 18:59:03 +01:00
Gael Guennebaud
ea8cad5151 make the number of registers easier to configure per architectures 2010-03-04 18:58:12 +01:00
Gael Guennebaud
cefd9b8888 merge with default branch 2010-03-04 18:47:52 +01:00
Hauke Heibel
1723068694 Moved x()/y()/z() and w() access functions to DenseBase; they are now available for Arrays as well. 2010-03-04 18:33:51 +01:00
Gael Guennebaud
8ed1ef4469 add a minor FIXME 2010-03-04 18:30:28 +01:00
Benoit Jacob
68d94d914e integer division is vectorizable on no SIMD platform, not just SSE. 2010-03-04 09:03:06 -05:00
Konstantinos Margaritis
710bc073a7 arm_neon.h is a standard header file, fixed 2010-03-03 12:15:34 -06:00
Benoit Jacob
6c89fd4df0 minor cleanup 2010-03-03 13:16:21 -05:00
Gael Guennebaud
7dd81aad74 factorize default performance related settings to a single file
included after the architecture specific files such that they
can be adapted by each platform.
2010-03-03 18:47:58 +01:00
Konstantinos Margaritis
112c550b4a Added initial NEON support, most tests pass however we had to use some hackish workarounds
as gcc on ARM (both CodeSourcery 4.4.1 used and experimental 4.5) fail to
ensure proper alignment with __attribute__((aligned(16))). This has to be
fixed upstream to remove the workarounds.
2010-03-03 11:25:41 -06:00
Benoit Jacob
45d19afb18 cleanup/simplification in computation of matrix flags 2010-03-03 09:58:43 -05:00
Benoit Jacob
7dbe806711 merge 2010-03-03 09:55:46 -05:00
Benoit Jacob
6a92168915 Backed out changeset 2f3d685e0c
This was implementing deep changes that after discussion on the mailing list seem to need further discussion/thinking.
2010-03-03 09:54:50 -05:00
Hauke Heibel
aa6570c3a3 Added a missing inline hints.
Removed a useless Nested temporary.
2010-03-03 15:24:58 +01:00
Gael Guennebaud
b0ffd9bf04 clean #defined tokens, and use clock_gettime for the real time 2010-03-03 09:41:29 +01:00
Gael Guennebaud
2f3d685e0c a matrix (or array) does not always have the LinearAccessBit!
=> fixes in outerStride and matrix flags
2010-03-02 15:31:39 +01:00
Gael Guennebaud
0ed5edd24d blas: add a default implementation of xerbla 2010-03-02 14:50:41 +01:00
Gael Guennebaud
a76c296e7f blas: fix most of level1 functions 2010-03-02 14:45:43 +01:00
Benoit Jacob
bca04bd983 fix compilation 2010-03-02 08:41:35 -05:00
Gael Guennebaud
a2d7c239f5 blas: fix HEMM and HERK 2010-03-02 12:44:40 +01:00
Gael Guennebaud
7fd6458fec selfadjoint: do not reference the imaginary part of the diagonal 2010-03-02 12:43:55 +01:00
Gael Guennebaud
abfed301cb blas: fix SYRK 2010-03-02 09:37:10 +01:00
Eamon Nerbonne
ff6b94d6d0 BenchTimer: avoid warning about symbol redefinition on win32, and include <Eigen/Core> (required to compile) 2010-03-02 08:46:11 +01:00
Gael Guennebaud
f1d3101956 blas: add warnings for non implemented functions 2010-03-03 09:32:10 +01:00
Hauke Heibel
32823caa62 Adapted the comment and removed it from the public dox. 2010-03-03 07:52:19 +01:00
Gael Guennebaud
3295c1c3e6 product selector: the symmetric case 2010-03-02 23:18:13 +01:00
Hauke Heibel
afad108b5f Added a comment to prevent placing an EIGEN_STRONG_INLINE where it makes no sense. 2010-03-02 19:36:21 +01:00
Eamon Nerbonne
3efb3cc828 Changed product type selector to fix perf regression. 2010-03-02 12:08:49 +01:00
Gael Guennebaud
c7828ac45c add missing implementation of uniform scaling products 2010-03-02 17:38:40 +01:00
Hauke Heibel
3cc9e3f5bb Fixes a compilation issue for MSVC. 2010-03-01 19:56:24 +01:00
Gael Guennebaud
a7b9250ad0 blas interface: fix compilation, fix GEMM, SYMM, TRMM, and TRSM,
i,e., they all pass the blas test suite. More to come
2010-03-01 19:06:07 +01:00
Jitse Niesen
a1ac56a7c7 Add (failing) test for computing HouseholderQR of a 1x1 matrix. 2010-03-01 13:46:41 +00:00
Gael Guennebaud
65eba35f98 rm useless omp shared directive 2010-03-01 13:34:44 +01:00
Gael Guennebaud
1710c07f63 remove Qt's atomic dependency, I don't know what I was doing wrong... 2010-03-01 13:09:47 +01:00
Jitse Niesen
2d7bd1ec91 Make MatrixFunctions tests more robust.
* Use absolute error instead of relative error.
* Test on well-conditioned matrices.
* Do not repeat the same test g_repeat times (bug fix).
* Correct diagnostic output in matrix_exponential.cpp .
2010-03-01 12:05:57 +00:00
Gael Guennebaud
31aa17e4ef GEMM: move the first packing of A' before the packing of B' 2010-03-01 11:10:30 +01:00
Gael Guennebaud
aeff3ff391 make Aron's idea work using Qt's atomic implementation for the synchronisation 2010-03-01 10:57:32 +01:00
Benoit Jacob
f1f3c30ddc remove the hack to make the static assertion on types actually show up.
indeed, now that we use the meta selector for transposing as needed, the static asserts work very well.
2010-02-28 11:10:13 -05:00
Benoit Jacob
07023b94d8 forgot defined(...) 2010-02-28 10:11:28 -05:00
Benoit Jacob
9334ed4444 on 64-bit systems, glibc's malloc returns 16-byte aligned ptrs, and we now take advantage of that. 2010-02-28 10:10:53 -05:00
Benoit Jacob
a480e7e60f * fix ei_handmade_aligned_realloc (was calling realloc on wrong ptr)
* add missing std::  (at least for QNX compatibility)
* add big comments to "structure" the file
2010-02-28 09:10:41 -05:00
Hauke Heibel
ff8c2149c1 Added a generic reallocation implementation based on ei_aligned_malloc/_free.
Rewrote ei_handmade_aligned_realloc such that it is now using std::realloc.
Reorganized functions in Memory.h for better readability.
Add missing <cerrno> include to Core (it's now required in Memory.h).
2010-02-28 14:32:57 +01:00
Hauke Heibel
40bd69fbaa Hide some internal stuff from the docs. 2010-02-28 12:56:37 +01:00
Benoit Jacob
1d9c18a8f3 comment out cerr's 2010-02-28 00:53:06 -05:00
Thomas Capricelli
eb3a3351cc misc cleaning 2010-02-28 02:51:35 +01:00
Benoit Jacob
27f5250258 Only include <iosfwd> unless either EIGEN_DEBUG_ASSIGN is defined or we're in eigen2 support mode 2010-02-27 19:04:22 -05:00
Benoit Jacob
e84f7e07e9 add ei_posix_memalign_realloc 2010-02-27 18:57:07 -05:00
Benoit Jacob
22fabb8940 add missing inline keyword, thanks to Eamon. 2010-02-27 17:51:48 -05:00
Thomas Capricelli
e0830cb1b7 Use a specialization of test_is_equal() instead of defining COMPARE() 2010-02-27 17:56:22 +01:00
Hauke Heibel
6c9eb36222 Added support for realloc based conservative resizing. 2010-02-27 17:25:07 +01:00
Hauke Heibel
78b2c7e16e Fixed a typo. 2010-02-27 17:24:42 +01:00
Benoit Jacob
3f393490ad dot: handle the rowvector.dot(colvector) case where one needs to transpose. 2010-02-27 11:19:14 -05:00
Thomas Capricelli
15a33622ac * define COMPARE(,), which prints expected/actual results in case of failure
* use it in test/NonLinearOptimization.cpp
2010-02-27 16:30:15 +01:00
Benoit Jacob
d9f6380499 Remove the dot product's separate implementation and use cwiseProduct.sum instead.
Also take special care to get nicely working static  assertions.
2010-02-27 10:03:27 -05:00
Benoit Jacob
b5c79e7291 add examples 2010-02-26 22:26:21 -05:00
Benoit Jacob
2c9a91812e merge 2010-02-26 21:47:54 -05:00
Benoit Jacob
814e40c72a let redux use the new ByOuterInner accessors 2010-02-26 21:46:43 -05:00
Benoit Jacob
4927841cba Document Map and Stride, add examples. 2010-02-26 21:29:04 -05:00
Benoit Jacob
b1f666d007 Fix Map-with-Stride and cover it by new unit tests. 2010-02-26 20:12:51 -05:00
Gael Guennebaud
6924bf2e99 implement Aron's idea of interleaving the packing with the first computations 2010-02-26 15:58:22 +01:00
nerbonne
c72a5074e6 Fixed perf problems for vector subtraction: inlining wasn't always happening when necessary. 2010-02-26 15:46:43 +01:00
Benoit Jacob
32115bff1e * add VERIFY_IS_EQUAL, should compile faster and it's natural when no arithmetic is involved.
* rename 'submatrices' test to 'block'
* add block-inside-of-block tests
* remove old cruft
* split diagonal() tests into separate file
2010-02-26 09:03:13 -05:00
Gael Guennebaud
ac425090f3 BTL: allow to bench real time 2010-02-26 14:57:49 +01:00
Gael Guennebaud
8d4a0e6753 fix compilation without openmp 2010-02-26 14:57:22 +01:00
Gael Guennebaud
c05047d28e fix some BTL issues 2010-02-26 12:51:20 +01:00
Gael Guennebaud
3ac2b96a2f implement a smarter parallelization strategy for gemm avoiding multiple
paking of the same data
2010-02-26 12:32:00 +01:00
Jitse Niesen
d86f5339b2 ComplexSchur: fix bug introduced in my previous commit.
The value of c is actually used a few lines later.
2010-02-26 09:47:17 +00:00
Benoit Jacob
f56ac04c34 DenseBase::IsRowMajor now takes the special case of vectors into account. 2010-02-25 21:24:42 -05:00
Benoit Jacob
b1c6c215a4 merge 2010-02-25 21:07:30 -05:00
Benoit Jacob
769641bc58 * Implement the ByOuterInner accessors
* use them (big simplification in Assign.h)
* axe (Inner|Outer)StrideAtCompileTime that were just introduced
* ei_int_if_dynamic now asserts that the size is the expected one: adapt to that in Block.h
* add rowStride() / colStride() in DenseBase
* implement innerStride() / outerStride() everywhere needed
2010-02-25 21:01:52 -05:00
Jitse Niesen
90e4a605ef ComplexSchur: compute shift more stably, introduce exceptional shifts.
Both the new computation of  the eigenvalues of a 2x2 block and the
exceptional shifts are taken from EISPACK routine COMQR.
2010-02-25 22:33:38 +00:00
Gael Guennebaud
53bae6b3f8 update matrix product selection rules for 1xSmallxLarge and the transposed case 2010-02-25 21:59:25 +01:00
Gael Guennebaud
959a1b5d63 detect and implement inplace permutations 2010-02-25 16:30:58 +01:00
Gael Guennebaud
d9ca0c0d36 optimize inverse permutations 2010-02-25 15:31:15 +01:00
Benoit Jacob
77c922bf05 * move the 's': InstructionsSet ---> InstructionSets
* proper capitalization: SSE, AltiVec
2010-02-25 06:43:45 -05:00
Thomas Capricelli
50a5ac3c4b oops, fix typo 2010-02-25 05:31:22 +01:00
Thomas Capricelli
00bc535b66 provide a static method to describe which SIMD instructions are used 2010-02-24 21:52:08 +01:00
Thomas Capricelli
0f3d69b65e Provide "eigen" defines to decide which instruction set is used
(sse3, ssse3 and sse4), independantly from the compiler.
Only those defines should be used in other places, and the user can
rely on those to know which sets are used.
2010-02-24 21:43:30 +01:00
Gael Guennebaud
7c98c04412 add reconstructedMatrix() to LLT, and LUs
=> they show that some improvements have still to be done
   for permutations, tr*tr, trapezoidal matrices
2010-02-24 19:16:10 +01:00
Gael Guennebaud
a7e4c0f825 make testsuite aware of EIGEN_CTEST_ARGS 2010-02-24 11:28:38 +01:00
Gael Guennebaud
f7aa9873ca * fix LDLT's default ctor use
* add a reconstructedMatrix() function to LDLT for debug purpose
2010-02-24 10:40:16 +01:00
Benoit Jacob
60325b8330 actually, this is not even meant to be a termination criterion. so the proper fix is this. 2010-02-23 16:10:26 -05:00
Benoit Jacob
3d066f4bc7 LDLT:
* fix bug thanks to Ben Goodrich: we were terminating at the wrong place, leaving some matrix coefficients with wrong values.
* don't use Higham's formula here: we're not trying to be rank-revealing.
2010-02-23 16:05:37 -05:00
Benoit Jacob
d92df336ad Further LU test improvements. I'm not aware of any test failures anymore, not even with huge numbers of repetitions.
Finally the createRandomMatrixOfRank() function is renamed to createRandomPIMatrixOfRank, where PI stands for 'partial isometry', that is, a matrix whose singular values are 0 or 1.
2010-02-23 15:40:24 -05:00
Gael Guennebaud
a1e1103328 add a 2D parallelizer 2010-02-23 21:40:15 +01:00
Gael Guennebaud
022e2f5ef4 fix typo 2010-02-23 18:24:15 +01:00
Gael Guennebaud
68eaefa5d4 update BTL (better timer, eigen2 => eigen3, etc) 2010-02-23 18:23:12 +01:00
Benoit Jacob
7dc75380c1 * FullPivLU: replace "remaining==0" termination condition (from Golub) by a fuzzy compare
(fixes lu test failures when testing solve())
* LU test: set appropriate threshold and limit the number of times that a specially tricky test
  is run. (fixes lu test failures when testing rank()).
* Tests: rename createRandomMatrixOfRank to createRandomProjectionOfRank
2010-02-23 09:04:59 -05:00
Gael Guennebaud
4a0d41c5fb merge 2010-02-23 14:34:55 +01:00
Hauke Heibel
1fd8d7b96a Attempt to fix PGI compilation issue. 2010-02-23 11:35:51 +01:00
Mark Borgerding
b528b747c1 merge 2010-02-22 21:44:30 -05:00
Mark Borgerding
5d530e0373 enable caller to supply FFT length for Eigen Matrix interface functions to effect zero pad or source shrink at Nyquist bin 2010-02-22 21:43:30 -05:00
Gael Guennebaud
3beedba244 merge 2010-02-22 21:32:29 +01:00
Thomas Capricelli
d3b314569b provide default values for CXX, remove duplicate define 2010-02-22 15:39:17 +01:00
Jitse Niesen
e6f0cd7121 Merge. 2010-02-22 16:17:43 +00:00
Gael Guennebaud
d2b0eadf52 fully adapt the gebp kernel and optimize it for CPU with only 8 registers
(transplanted from 2ed88ebbf1995be90b8d0c25ff10248c8f56d023)
2010-02-22 16:35:05 +01:00
Gael Guennebaud
51a4b929a1 implement an even lower level version of the gebp kernel for MSVC (it seems to be faster with gcc as well)
(transplanted from 9a5643551fe068497f84a81cd8986febf1918382)
2010-02-22 15:18:29 +01:00
Hauke Heibel
3e6ab8f93b ups 2010-02-22 11:34:25 +01:00
Hauke Heibel
d5af5ab92b Added getRealTime() for windows. 2010-02-22 11:23:27 +01:00
Gael Guennebaud
f797ba0abe extend the bench timer to allow benchmarking of parallel code,
improvements are welcome
2010-02-22 11:04:35 +01:00
Gael Guennebaud
801440c519 fix BTL's eigen interface
(transplanted from 437f40acc1
)
2010-02-22 09:32:16 +01:00
Gael Guennebaud
eb905500b6 significant speedup in the matrix-matrix products 2010-02-23 13:06:49 +01:00
Gael Guennebaud
d579d4cc37 oops 2010-02-22 17:57:15 +01:00
Gael Guennebaud
fc4a85ecd5 fully adapt the gebp kernel and optimize it for CPU with only 8 registers 2010-02-22 16:35:05 +01:00
Gael Guennebaud
dd569c7d0f merge 2010-02-22 15:19:19 +01:00
Gael Guennebaud
e00f1fd125 implement an even lower level version of the gebp kernel for MSVC (it seems to be faster with gcc as well) 2010-02-22 15:18:29 +01:00
Hauke Heibel
6730fd9f3f Port BenchTimer fix. 2010-02-22 11:42:58 +01:00
Gael Guennebaud
4ba25a8d5c merge 2010-02-22 11:30:36 +01:00
Gael Guennebaud
aaaf855a88 add a small benchmark to quickly bench/compare SMP support 2010-02-22 11:09:57 +01:00
Gael Guennebaud
1c6bdb4060 merge 2010-02-22 11:09:05 +01:00
Gael Guennebaud
3e62fafce8 clean a bit the parallelizer 2010-02-22 11:08:37 +01:00
Gael Guennebaud
b20935be9b add initial openmp support for matrix-matrix products
=> x1.9 speedup on my core2 duo
2010-02-22 09:40:34 +01:00
Gael Guennebaud
437f40acc1 fix BTL's eigen interface 2010-02-22 09:32:16 +01:00
Thomas Capricelli
1a70f3b48d fix compilation 2010-02-21 19:30:11 +01:00
Hauke Heibel
a901bed33a Added IsRowMajor enum to DenseBase. 2010-02-21 18:26:14 +01:00
Hauke Heibel
e2a059863e Added missing precision/eps functions to AutoDiffScalar. 2010-02-21 15:44:34 +01:00
Hauke Heibel
f079f52b58 merge 2010-02-21 15:25:28 +01:00
Hauke Heibel
f75e6773b0 Added ei_traits<Quaternion>::PlainObject. 2010-02-21 15:24:10 +01:00
Hauke Heibel
ac8ff44278 Tried to get rid of MSVC warning D9025. 2010-02-21 15:23:51 +01:00
Thomas Capricelli
a7d085eb4e NonLinearOptimization : clean 'mode' handling from the old minpack code :
* this is actually a boolean, not an int
* use a better name
* can be set at initialization time instead of bloating all methods signatures
2010-02-21 12:41:37 +01:00
Gael Guennebaud
608959aa6f compilation fix in ldlt() for non matrix types 2010-02-21 10:29:19 +01:00
Gael Guennebaud
71fecd2371 add missing return value 2010-02-20 18:19:34 +01:00
Hauke Heibel
6b4cecc1c6 CMake cleanup. 2010-02-20 17:39:58 +01:00
Jitse Niesen
4e389b195d Change MatrixFunction::separation() parameter from 0.01 to 0.1 .
The latter is actually the value used in the literature.
2010-02-20 16:27:04 +00:00
Hauke Heibel
abc8c01080 Renamed PlainMatrixType to PlainObject (Array != Matrix).
Renamed ReturnByValue::ReturnMatrixType ReturnByValue::ReturnType (again, Array != Matrix).
2010-02-20 15:53:57 +01:00
Jitse Niesen
67ce07ea83 matrix_function test: replace expm(A).inverse() by expm(-A)
The latter is more stable. This fixes one of the issues with the test.
Also, make typedef's in MatrixFunctionReturnValue public; this is
necessary to get the test to compile.
2010-02-20 14:45:50 +00:00
Hauke Heibel
f0c8dcf1e2 Renamed AnyMatrixBase to EigenBase. 2010-02-20 15:26:02 +01:00
Gael Guennebaud
4f8773c23a fix stupid enum values 2010-02-19 17:46:36 +01:00
Benoit Jacob
5491531a81 add Stride.h 2010-02-18 20:44:17 -05:00
Benoit Jacob
b73e22905d miserable half-working state, commiting to a fork just in case, just to perfect
my day, my hard disk would die.
Will write a more detailed commit message once it's working.
2010-02-18 20:42:38 -05:00
Jitse Niesen
39d9f0275b Update matrix_exponential test after API change in ei_matrix_function
Apologies for forgetting this yesterday and not testing properly.
2010-02-17 09:50:11 +00:00
Mark Borgerding
2cd1ad2ded typo in merge 2010-02-16 22:06:23 -05:00
Mark Borgerding
f200c84d9f merge 2010-02-16 21:41:04 -05:00
Mark Borgerding
8f51a4ac90 found out about little-documented FFTW_PRESERVE_INPUT which has effect on c2r transforms 2010-02-16 20:44:48 -05:00
Jitse Niesen
319bf3130b Use ReturnByValue to return result of ei_matrix_function(), ... 2010-02-16 16:43:11 +00:00
Jitse Niesen
25019f0836 Use ReturnByValue to return result of ei_matrix_exponential() . 2010-02-15 19:17:25 +00:00
Gael Guennebaud
a9096b626b not all versions of gcc support -Wno-variadic-macros 2010-02-15 11:39:57 +01:00
Gael Guennebaud
016943f870 avoid 2 redundant calls to resize 2010-02-15 11:31:36 +01:00
Gael Guennebaud
dcb395c6f5 explicitly disable the use of evalTo for dense object 2010-02-15 11:09:33 +01:00
Gael Guennebaud
21d0eb3f11 the default implementation should really call evalTo 2010-02-15 11:01:55 +01:00
Gael Guennebaud
d00bff91ad workaround weird gcc 4.0.1 compilation error 2010-02-15 11:00:30 +01:00
Hauke Heibel
8519558d11 Workaround for compounds affected by #94. 2010-02-15 10:11:10 +01:00
Jitse Niesen
b18f737aa1 Test matrix functions with matrices with clustered imaginary eivals.
The idea is that these test MatrixFunction::swapEntriesInSchur(),
which is not covered by existing tests. This did not work out as
expected, but nevertheless it is a good test so I left it in.
2010-02-13 22:49:01 +00:00
Jitse Niesen
a4a2671fd0 Refactor matrix_function test in preparation of next commit. 2010-02-13 22:38:27 +00:00
Benoit Jacob
9251cfed9b this had to be done here, not at the end. 2010-02-12 09:03:16 -05:00
Benoit Jacob
37ca4200b2 Piotr's patch was missing many occurences of size_t. So,
using std::size_t;
This is the only way that we can ensure QCC support in the long term without having to think about it everytime.
2010-02-12 08:58:29 -05:00
Gael Guennebaud
a76950bdab fix a couple of ICE with gcc 4.0.1 2010-02-12 09:41:56 +01:00
Piotr Trojanek
1701a5d1f8 std:: namespace fixup for more restricive compilers such as QNX's QCC 2010-02-10 13:24:47 +01:00
Hauke Heibel
ae0a17d30b Here is the proper fix. 2010-02-11 11:39:02 +01:00
Hauke Heibel
13ce92f5ba Fixed notemporary unit test. 2010-02-11 11:31:36 +01:00
Hauke Heibel
93e86b0884 Fixed typos.
Replace NumTraits<bool>::dummy_precision() (three locations) by false in order to suppress warnings.
2010-02-11 11:31:22 +01:00
Gael Guennebaud
48f5980669 fix compilation (cwise and epsilon) 2010-02-11 09:24:29 +01:00
Thomas Capricelli
602778ea26 also fix tests for NumTraits<double>::epsilon() 2010-02-11 01:49:27 +01:00
Thomas Capricelli
fd19dd57d8 fix usage of epsilon wrt to latest API change 2010-02-11 01:43:36 +01:00
Thomas Capricelli
ccc58e935e fix usage of epsilon wrt to latest API change 2010-02-11 01:43:03 +01:00
Jitse Niesen
fc5fa77743 unsupported/Eigen/AlignedVector3: dummy_precision is now in NumTraits 2010-02-10 17:59:27 +00:00
Hauke Heibel
d0e8342a04 Fixed warning. 2010-02-10 18:00:36 +01:00
Gael Guennebaud
0ca67afe6a finally here is a simple solution making (a*b).diagonal() even faster than a.lazyProduct(b).diagonal() !! 2010-02-10 14:08:47 +01:00
Mark Borgerding
1d342e135c changed destination argument to reference 2010-01-22 22:52:13 -05:00
Mark Borgerding
141c746fc7 if the src.stride() != 1, then the layout is not continuous -- need to copy to temporary 2010-01-22 01:17:36 -05:00
Mark Borgerding
cd7912313d changed FFT function vector and Matrix args to pointer as Benoit suggested
implemented 2D Complex FFT for FFTW impl
2010-01-22 00:35:03 -05:00
Mark Borgerding
a30d42354f updated comments and played around with Map 2010-01-21 21:10:16 -05:00
Mark Borgerding
7a6cb2a39c added benchmark for unscaled and half-spectrum FFTs 2010-01-21 21:09:26 -05:00
Hauke Heibel
f1a025185a Added array() to ArrayBase and matrix() to MatrixBase(). 2010-01-21 17:55:09 +01:00
Jitse Niesen
dbf3af866e Remove some Array #includes. 2010-01-21 12:31:03 +00:00
Hauke Heibel
7bf5930496 Adapted Geometry includes.
Adapted the decomposition documentation regarding the solve signature.
2010-01-21 09:43:30 +01:00
Hauke Heibel
ecc71abdda Added the Array include's warning for GCC. 2010-01-20 21:36:50 +01:00
Hauke Heibel
26df0609e2 Corrected the Array include's deprecation warning for MSVC. 2010-01-20 20:56:52 +01:00
Hauke Heibel
85d80d0fcd merge 2010-01-20 20:51:42 +01:00
Hauke Heibel
5d48cc1f5b Moved the Array module to Core. 2010-01-20 20:51:01 +01:00
Manuel Yguel
71b64d3498 Updated tests for enhanced AlignedBox with volume, diagonal and better handling of integral types. 2010-01-20 14:55:10 +01:00
Gael Guennebaud
8918d18e21 Improved patch from Manuel Yguel:
Enhance AlignedBox to accept integral types and add some usefull methods: diagonal, volume, sample.
2010-02-10 11:40:55 +01:00
Gael Guennebaud
bb290977b8 add highest and lowest functions to NumTraits 2010-02-10 11:11:21 +01:00
Gael Guennebaud
fe0827495a * move dummy_precision and epsilon to NumTraits
* make NumTraits inherits std::numeric_limits
2010-02-10 10:52:28 +01:00
Hauke Heibel
c11df02f0d Deactivated test which requires variadic macros. 2010-02-09 20:52:15 +01:00
Hauke Heibel
5da3049b80 Regression tests for number of nested temporaries.
Moved EIGEN_DEBUG_MATRIX_CTOR to ei_matrix_storage to capture resize related allocations.
2010-02-09 20:32:48 +01:00
Gael Guennebaud
f96e6a6944 merge 2010-02-09 16:41:48 +01:00
Gael Guennebaud
71e580c4aa fix nesting in Arraywrapper and nesting_ops 2010-02-09 16:38:36 +01:00
Hauke Heibel
04333c6ace Now variadic macro related warnings should be supressed as well under Linux. 2010-02-09 16:37:24 +01:00
Gael Guennebaud
905050b239 extend sparse product benchmark with ublas 2010-02-09 15:55:36 +01:00
Gael Guennebaud
285bc336d5 document lazyProduct 2010-02-09 14:45:17 +01:00
Gael Guennebaud
840977529f * as promised, remove the "optimization" for Product::diagonal()
* add MatrixBase::lazyProduct
2010-02-09 14:34:31 +01:00
Gael Guennebaud
9ce1212d7c For the record, here is a solution for (a*b).diagonal, at the cost of extra copies
if a and/or b as to be evaluated. So in the next commit I'll remove it. A nice
solution would be to evaluate the lhs/rhs into member of the initial product,
but that would be overkill.
2010-02-09 14:28:22 +01:00
Hauke Heibel
0a680a9857 Added a non-diagonal product nesting test. 2010-02-09 14:24:17 +01:00
Hauke Heibel
dd283b3f82 Fixed paste&copy error. 2010-02-09 14:12:41 +01:00
Hauke Heibel
928ae382b4 Added debug only unit test for nesting ops - just run ./check nesting. 2010-02-09 14:07:37 +01:00
Gael Guennebaud
8185a3c6cf fix one useless temp & copy 2010-02-09 13:16:29 +01:00
Gael Guennebaud
1cb59e4781 fix nesting lazy prod by ref 2010-02-09 11:27:30 +01:00
Gael Guennebaud
d104d2cd29 add accessors to coeff based product 2010-02-09 11:13:22 +01:00
Gael Guennebaud
5686eca7b1 * fix multiple temporary copies for coeff based products
* introduce a lazy product version of the coefficient based implementation
  => flagged is not used anymore
  => small outer product are now lazy by default (aliasing is really unlikely for outer products)
2010-02-09 11:05:39 +01:00
Gael Guennebaud
0398e21198 s/UnrolledProduct/CoeffBasedProduct 2010-02-09 10:02:26 +01:00
Gael Guennebaud
c076fec734 fix the multiple temporary issue for nested products 2010-02-09 09:58:34 +01:00
Gael Guennebaud
8b016e717f get rid of NestParentByRefBit 2010-02-08 16:51:41 +01:00
Hauke Heibel
871698d3aa Introduced NestParentByRefBit and NestByRefBit - this should fix temporaries related to nested products.
Fixed a few typos and a few warnings.
2010-02-06 17:43:32 +01:00
Gael Guennebaud
6f3f857897 make noalias works for coefficient based products 2010-02-05 23:44:24 +01:00
Gael Guennebaud
52167be4c8 make sure the correct diagoanl() function is called in trace() 2010-02-04 18:51:29 +01:00
Gael Guennebaud
73eb0e633c * resurected Flagged from Eigen2Support
* reimplement .diagonal() for ProductBase to make (A*B).diagonal() more efficient!
2010-02-04 18:28:09 +01:00
Gael Guennebaud
b44240180f optiization: make hybrid small/large outer products use the unrolled path 2010-02-04 17:17:57 +01:00
Hauke Heibel
d0b4ef81f0 Prevent temporaries for reductions. 2010-02-04 14:26:03 +01:00
Hauke Heibel
1a77334d54 Silenced type conversion warnings. 2010-02-03 19:20:25 +01:00
Hauke Heibel
05837be8fb Fixed a warning.
Transform::Identity() is now returning a Transform.
2010-02-03 09:46:27 +01:00
Hauke Heibel
8861dce7ee Fixed 32bit builds. 2010-02-03 09:07:17 +01:00
Hauke Heibel
7b2dd988fa Fixes #89.
Added regression test.
2010-02-02 09:27:41 +01:00
Gael Guennebaud
7c41fb66f8 fix compilation on 32bits systems 2010-02-01 11:45:08 +01:00
Gael Guennebaud
08f154b93a remove some trailing nestbyvalue 2010-02-01 11:44:44 +01:00
Gael Guennebaud
dd817361f5 use unrolled product path for small outer product 2010-01-31 12:28:16 +01:00
Hauke Heibel
15c0a78c6e One warning less... 2010-01-30 17:24:18 +01:00
Gael Guennebaud
43f0c0cbb3 fix triangular view assignment 2010-01-30 09:02:18 +01:00
Gael Guennebaud
b6521b799f add specialization of ei_ref_selector for Array (fix a big perf issue \!) 2010-01-29 21:28:23 +01:00
Hauke Heibel
6dee5440e4 Adapted mean to work with complex numbers.
Added regression test.
2010-01-29 12:12:02 +01:00
Hauke Heibel
42b88983ff Fixed mean reduction leading to unresolved symbol. 2010-01-29 11:48:16 +01:00
Hauke Heibel
ae06365bbd Disable variadic macro warning when compiling at full warning level.
I was not able to get a macro version running and thus I opted for a cmake patch.
2010-01-29 09:53:19 +01:00
Thomas Capricelli
2b2fcc9460 erm.... using nxn is the actual purpose of this variant, fix this. 2010-01-29 08:59:25 +01:00
Jitse Niesen
375b5faa8a Fix copy-paste error in first_aligned test. 2010-01-28 17:06:20 +00:00
Benoit Jacob
13b078efc9 remove reference to dead option 2010-01-28 08:46:01 -05:00
Hauke Heibel
33abe75afa Fixed Quaternion operator*= added regression test. 2010-01-28 10:32:44 +01:00
Thomas Capricelli
98a584ceb8 Put the Status outside of the class, it really does not depend on the
FunctorType or Scalar template parameters.
2010-01-28 10:29:26 +01:00
Thomas Capricelli
27cf1b3a97 eigenization of ei_r1updt() 2010-01-28 04:28:52 +01:00
Thomas Capricelli
40eac2d8a0 misc cleaning / eigenization 2010-01-28 04:19:39 +01:00
Thomas Capricelli
fcd074c928 silent warning of icc 2010-01-27 23:43:32 +01:00
Thomas Capricelli
bd732986bc fix compilation 2010-01-27 23:43:15 +01:00
Gael Guennebaud
0ce5bc0d14 add support for global math function for array 2010-01-27 23:23:59 +01:00
Hauke Heibel
7d92b7ad5f Modified license header. 2010-01-27 20:47:37 +01:00
Hauke Heibel
3bfba8c9a9 Added the missing unit test file. 2010-01-27 20:34:42 +01:00
Hauke Heibel
5b9cc65418 Added EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION macro including unit tests and documentation. 2010-01-27 20:34:05 +01:00
Benoit Jacob
828d058b4b EIGEN_ENUM_MIN ---> EIGEN_SIZE_MIN 2010-01-27 11:42:04 -05:00
Benoit Jacob
dcbf104bcc add EIGEN_DEFAULT_TO_ROW_MAJOR cmake option for the tests. 2010-01-27 07:48:48 -05:00
Benoit Jacob
35bacf7cb8 *forward port fix in MapBase::coeff(int) and coeffRef(int)
*forward port expanded map.cpp unit test
*fix unused variable warnings
2010-01-27 07:11:49 -05:00
Thomas Capricelli
7ba9dc07ed port ei_rwupdt to c++, and misc cleaning 2010-01-27 09:01:13 +01:00
Thomas Capricelli
e97529c2e3 doc : update code, mention examples 2010-01-27 08:14:50 +01:00
Hauke Heibel
4365a48748 Added an ei_linspaced_op to create linearly spaced vectors.
Added setLinSpaced/LinSpaced functionality to DenseBase.
Improved vectorized assignment - overcomes MSVC optimization issues.
CwiseNullaryOp is now requiring functors to offer 1D and 2D operators.
Adapted existing functors to the new CwiseNullaryOp requirements.
Added ei_plset to create packages as [a, a+1, ..., a+size].
Added more nullaray unit tests.
2010-01-26 19:42:17 +01:00
Thomas Capricelli
afb9bf6281 use PlanarRotation<> instead of handmade givens rotation in cminpack code
+ cleaning.
This results in some more memory being used, but not much.
2010-01-26 17:40:55 +01:00
Thomas Capricelli
c04a93df31 clean r1mpyq: remove fortran leftovers 2010-01-26 14:08:52 +01:00
Thomas Capricelli
55f328b264 misc cleaning 2010-01-26 13:20:24 +01:00
Thomas Capricelli
71f513e250 forgot to commit this: qform.h is not used anymore 2010-01-26 13:08:29 +01:00
Thomas Capricelli
69f11c08a1 more eigenization, dropped 'ipvt' in lm 2010-01-26 12:09:52 +01:00
Thomas Capricelli
8a690299c6 fix possible segfault 2010-01-26 11:48:32 +01:00
Thomas Capricelli
d791b51112 remove spaces 2010-01-26 10:50:43 +01:00
Thomas Capricelli
113995355b get rid of ei_qform + lot of other cleaning, now that we do not depend on
minpack qr factorization.
2010-01-26 08:42:48 +01:00
Thomas Capricelli
ba2a9cce03 some more eigenization 2010-01-26 07:36:15 +01:00
Thomas Capricelli
a3034ee079 cleaning 2010-01-26 06:05:01 +01:00
Thomas Capricelli
91561cded4 use a plain matrix to store the upper triangular matrix 'R', instead
of the "compact inside a vector" scheme used by fortran/minpack.
The most difficult part is to fix all related code. Tests pass.
2010-01-26 05:59:58 +01:00
Thomas Capricelli
4b859c8554 cleaning 2010-01-26 01:59:32 +01:00
Thomas Capricelli
c759814f11 some more (thoroughly checked) eigenization 2010-01-26 01:43:58 +01:00
Jitse Niesen
bdb0e9fcd0 Clean up one compilation error and two warnings. 2010-01-26 16:02:19 +00:00
Thomas Capricelli
1403cea087 fix a bug introduced between the cminpack version of Manolis Lourakis and
the one from Frédéric Devernay.
Here, we want to compute the max over the column, the -1 is not needed in
fortran because indices start at 1, contrary to c/c++.
2010-01-26 04:55:36 +01:00
Thomas Capricelli
9651e0c503 Use eigen methods for solving triangular systems. We loose again very
slightly on both speed and precision on some tests.
2010-01-25 11:34:52 +01:00
Thomas Capricelli
92be7f461b define ei_lmpar2() that takes a ColPivHouseholderQR as argument. We still
need to keep the old one around, though.
2010-01-25 07:23:38 +01:00
Thomas Capricelli
ee0e39284c Replace the qr factorization from (c)minpack (qrfac) by Eigen's own stuff.
Results as checked by unit tests are very slightly worse, but not much.
2010-01-25 07:22:28 +01:00
Thomas Capricelli
1cb0be05b0 useful cleaning 2010-01-25 07:08:08 +01:00
Thomas Capricelli
cbf6022e5a useless cleaning 2010-01-25 07:07:31 +01:00
Benoit Jacob
6ae7d842a3 generate a compilation error when using ReturnByValue::coeff() or coeffRef(),
instead of doing an infinite recursion
2010-01-24 21:44:18 -05:00
Jitse Niesen
858539a6af Use matrices with clustered eigenvalues in matrix function test.
This is in order to get better code coverage.
Test matrix_function_3 now fails regularly because ComplexSchur
reaches the max number of iterations; further study needed.
2010-01-24 22:56:28 +00:00
Thomas Capricelli
d08035f3e1 fix the script again (definitely?) + cleaning 2010-01-22 19:26:29 +01:00
Gael Guennebaud
be11a254ac rm ExpressionMaker stuff (weird as I was pretty sure that I had already removed them) 2010-01-22 10:17:43 +01:00
Gael Guennebaud
d40c110053 lot of cleaning:
- clean the *_PUBLIC_INTERFACE_*
- update Diagonal, ReturnByValue, ForceAlignedAccess, UnaryView, etc. to support array
- many other small stuff
2010-01-22 10:15:41 +01:00
Jitse Niesen
e78e3cd41b Fix bug in MatrixBase::setIdentity(int, int). 2010-01-20 12:07:46 +00:00
Jitse Niesen
e0c2c6385f Add small test for Matrix::setIdentity()
This is to exhibit the bug that makes the jacobisvd_7 test fail.
2010-01-20 10:51:59 +00:00
Hauke Heibel
89ee9f092f Fixed compilation of MatrixFunctions module. 2010-01-20 11:32:13 +01:00
Gael Guennebaud
d5d5417062 add SSE code (from Intel) for the fast inversion of 4x4 matrices of double 2010-01-19 16:04:04 +01:00
Gael Guennebaud
60b0ddc3e1 update the fast 4x4 SSE inversion code from more recent Intel's code 2010-01-19 15:33:45 +01:00
Jitse Niesen
a13ffbd836 Get rid off GCC warning on comparing enums from different types. 2010-01-19 11:05:52 +00:00
Mark Borgerding
dacfa97e82 merge 2010-01-18 19:53:44 -05:00
Mark Borgerding
adb2170eb8 removed Eigen::Complex class since it offered insufficient advantage over std::complex when sane real,imag structure packing is assumed.
for more info see:
http://www.cpptalk.net/portable-complex-numbers-between-c-c--vt46432.html
2010-01-18 19:39:22 -05:00
Thomas Capricelli
c8b9097740 erm.. forgot to test after previous commit. Now it's ok (tm). 2010-01-19 01:00:59 +01:00
Gael Guennebaud
9f899808d7 fix scalar - matrix 2010-01-18 22:56:47 +01:00
Gael Guennebaud
0158d78906 extend CwiseNullaryOp to support Array 2010-01-18 22:56:25 +01:00
Gael Guennebaud
c70d54257b add unit tests for true array objects 2010-01-18 22:54:20 +01:00
Thomas Capricelli
c436abd0ac fix both compilation and previous fix : now 'basicstuff' passes again.
(Gael: i dont think you meant removing this setIdentity(), did you?)
2010-01-18 10:29:11 +01:00
Gael Guennebaud
6b380992b5 fix != 2010-01-18 08:18:48 +01:00
Thomas Capricelli
0c89475317 unit tests for == / != operators 2010-01-17 23:57:59 +01:00
Gael Guennebaud
71630b2160 fix MatrixBaseAddons example 2010-01-17 20:04:49 +01:00
Benoit Jacob
b5a6f382ca work around warning about /* inside of a comment (gcc 4.4) 2010-01-16 11:50:09 -05:00
Hauke Heibel
37d4505228 More documentation improvements. 2010-01-16 15:43:11 +01:00
Hauke Heibel
90d5a7c0dd Adapted doxygen's new style sheet.
Added documentation to some of the typedefs.
2010-01-15 15:45:07 +01:00
Gael Guennebaud
dd4b2f044d forgot to include this file in previous commit 2010-01-15 13:36:09 +01:00
Gael Guennebaud
d62ee0668f remove useless using comp. assignment operators 2010-01-15 13:34:28 +01:00
Gael Guennebaud
76a355817b fix a warning 2010-01-15 13:26:39 +01:00
Benoit Jacob
bfe6fdde24 allow to multiply a householder sequence and a matrix when one is real and one is complex.
This is especially important as in bidiagonalization, the band matrix is real.
2010-01-15 00:35:26 -05:00
Benoit Jacob
ddc32adb0e New UpperBidiagonalization class 2010-01-14 22:30:58 -05:00
Benoit Jacob
f1d1756cdd Introduce third template parameter to HouseholderSequence: int Side.
When it's OnTheRight, we read householder vectors as rows above the diagonal.
With unit test. The use case will be bidiagonalization.
2010-01-14 19:16:49 -05:00
Gael Guennebaud
5d796e363c compilation fix for UmfPack 2010-01-14 22:31:06 +01:00
Hauke Heibel
814659c201 Changed parts of the documentation.
The param keyword is now tparam (in Matrix).
Made PlainMatrixType non-internal (currently MatrixBase only); I think this is an important typedef in particular when writing your own template methods.
2010-01-14 10:10:07 +01:00
Hauke Heibel
624902f559 Enabled class diagrams (requires dot, i.e. graphviz).
Adapted the style sheet in order to center class diagrams.
2010-01-13 17:59:42 +01:00
Hauke Heibel
c0b2aa0ace Added some minor comments.
Adapted some of the doc/snippets.
2010-01-13 17:51:09 +01:00
Thomas Capricelli
a33b2dfeb3 introduce new state, "Not started" 2010-01-13 05:17:58 +01:00
Hauke Heibel
a87c0a5ed8 Fixes #83. 2010-01-12 17:13:46 +01:00
Hauke Heibel
553fb31f7e Using operator*= is not required in MapBase. Since no other operator*= is present, none of the base class operator*='s may be hidden and all of them should be visible. As far as I was able to verify, this is not affecting GCC. This fixes #84. 2010-01-12 16:30:03 +01:00
Hauke Heibel
ffaea1d995 merge 2010-01-12 13:38:46 +01:00
Hauke Heibel
e48c3faf25 Fixed the ProductReturnType (at least for UnrolledProducts).
Fixed operator= (MSVC specific) in Array.
2010-01-12 13:38:04 +01:00
Hauke Heibel
a8ea2c8cef Fixes #81. 2010-01-12 10:07:06 +01:00
Hauke Heibel
caa9ced853 Add a real plain matrix type to the ei_nested declaration used in product return type. 2010-01-12 09:41:06 +01:00
Jitse Niesen
65cd1c7639 Add support for matrix sine, cosine, sinh and cosh. 2010-01-11 18:05:30 +00:00
Hauke Heibel
a05d42616b Fixed DenseStorageBase typedef (MSVC specific).
Unified the ei_plain_matrix_type.
2010-01-11 18:16:59 +01:00
Benoit Jacob
24a09ceae8 * Fix a bug in HouseholderQR with mixed fixed/dynamic size: must use EIGEN_SIZE_MIN instead of EIGEN_ENUM_MIN, and there are many other occurences throughout Eigen!
* HouseholderSequence:
  - add shift parameter
  - add essentialVector() method to start abstracting the direction
  - add unit test in householder.cpp
2010-01-11 08:48:39 -05:00
Hauke Heibel
325da2ea3c Fixed conservativeResize.
Fixed multiple overloads for operator=.
Removed debug output.
2010-01-11 13:57:50 +01:00
Jitse Niesen
376341de4a Eigen/src/Core/DenseStorageBase.h: add 'typename' 2010-01-11 10:04:39 +00:00
Hauke Heibel
83d21d5ff6 Fixes unit test swap_3. Friends are not inherited. 2010-01-10 23:15:36 +01:00
Hauke Heibel
3d5912d458 Backed out the removal of the actual resize like implementation. Now, resizing by dimension is optional. 2010-01-10 23:11:05 +01:00
Hauke Heibel
350c7beb92 Fixed swapping and corresponding MSVC compilation. 2010-01-10 20:02:26 +01:00
Hauke Heibel
e0f5b4add3 Fixed MSVC compilation. 2010-01-10 15:36:28 +01:00
Jitse Niesen
3eb80eecde doc/A05_PortingFrom2To3.dox: fix typos 2010-01-09 18:54:31 +00:00
Jitse Niesen
3407e8a67e triangularView<UpperTriangular> --> triangularView<Upper>
Necessary after c5d7c9f0de
 (big delete of "triangular").
2010-01-08 12:49:46 +00:00
Jitse Niesen
ef0ed5b271 test/triangular.cpp: isUpper() --> isUpperTriangular()
Necessary to get the test to compile after c5d7c9f0de
.
I'm assuming that isUpperTriangular() is the name we want; the alternative
is to change Eigen/src/Core/{MatrixBase,TriangularMatrix}.h
2010-01-08 12:46:24 +00:00
Benoit Jacob
0fb0307377 implement BandMatrix::evalTo (thus avoid infinite recursion when assigning a BandMatrix to a Matrix) 2010-01-07 22:08:18 -05:00
Benoit Jacob
44ed79fc3c finally, undo this 2010-01-07 22:03:58 -05:00
Benoit Jacob
b05f59ee07 Backed out changeset 58fb27cd56 2010-01-07 22:00:45 -05:00
Benoit Jacob
58fb27cd56 undo 2010-01-07 21:53:52 -05:00
Benoit Jacob
7befc8d6f3 undo my last commit 2010-01-07 21:51:40 -05:00
Trevor Irons
5f0cf1d7f6 Added std::sqrt(std::complex<float>) and std::sqrt(std::complex<double>) support to MathFunctions.h 2010-01-07 15:03:51 -07:00
Gael Guennebaud
c5d7c9f0de remove the Triangular suffix to Upper, Lower, UnitLower, etc,
and remove the respective bit flags
2010-01-07 21:15:32 +01:00
Benoit Jacob
82ec250a0f make applyHouseholderOnTheRight take a row vector, not a column vector:
this is how it's used in practice.
2010-01-07 12:50:02 -05:00
Gael Guennebaud
c24de5b413 typo 2010-01-06 17:43:11 +01:00
Gael Guennebaud
2fbe8da7a1 improved a bit the list of API changes 2010-01-06 17:35:22 +01:00
Gael Guennebaud
7d3fe69eff Various documentation updates:
- update the tutorial
- update doc of deprecated cwise function
- update cwise doc snippets
2010-01-06 17:18:38 +01:00
Gael Guennebaud
c11300dbd5 a couple of fixes 2010-01-06 17:16:30 +01:00
Thomas Capricelli
a0efdd843c actually stop on failure 2010-01-06 17:14:31 +01:00
Benoit Jacob
e77748ef96 merge 2010-01-06 08:24:42 -05:00
Benoit Jacob
f287ad651a fix comments 2010-01-06 08:23:19 -05:00
Gael Guennebaud
95c00ca8ff started a page on the porting from Eigen2 to 3, updated a bit the tutorial 2010-01-06 13:56:04 +01:00
Gael Guennebaud
023e0dfb4e improve the new experimental sparse product 2010-01-05 19:56:59 +01:00
Gael Guennebaud
eda4e98c61 merge 2010-01-05 16:04:36 +01:00
Gael Guennebaud
801e601ff1 a couple of improvements in the Autodiff module 2010-01-05 16:04:05 +01:00
Gael Guennebaud
c3823dce72 extend benchmark for sparse products 2010-01-05 16:03:35 +01:00
Gael Guennebaud
d8534be728 add a novel, experimental sparse product 2010-01-05 15:57:16 +01:00
Gael Guennebaud
1837b65b28 add operators *= and /= (bis) 2010-01-05 15:41:01 +01:00
Gael Guennebaud
39209edd71 port unsupported modules to new API 2010-01-05 15:38:20 +01:00
Gael Guennebaud
cab85218db add missing operators: /, /=, *= 2010-01-05 15:36:32 +01:00
Gael Guennebaud
3e22e3907f fix types of scalar constants 2010-01-05 15:35:44 +01:00
Gael Guennebaud
97f0f02e10 forgot to hg add this file 2010-01-05 14:36:55 +01:00
Gael Guennebaud
9d9e00b608 merge and add start/end to Eigen2Support 2010-01-05 13:07:32 +01:00
Gael Guennebaud
90d2ae7fec fix aliasing detection 2010-01-05 12:46:07 +01:00
Gael Guennebaud
37851cfe11 fix a coupe of warnings 2010-01-05 10:15:29 +01:00
Benoit Jacob
51b8f014f3 merge 2010-01-04 21:26:15 -05:00
Benoit Jacob
39ac57fa6d Big renaming:
start ---> head
  end   ---> tail
Much frustration with sed syntax. Need to learn perl some day.
2010-01-04 21:24:43 -05:00
Benoit Jacob
78ba523d30 Make snippet run successfully again:
the snippet for 'eval' was taking m=m.transpose() as an example of code
 that needs an explicit call to eval(), but that doesn't work anymore now
 that we have the clever assert detecting aliasing issues.
2010-01-04 21:23:37 -05:00
Thomas Capricelli
e9724c8ea2 accessor for the levenberg-marquardt parameter 2010-01-05 01:22:53 +01:00
Jitse Niesen
708e6629e2 Further refactoring of MatrixFunction<MatrixType, 1>
* move some data to member variables
* split and/or rename member functions
* document all members
2010-01-04 23:13:15 +00:00
Thomas Capricelli
fd19e0a9ea unimportant small fix 2010-01-04 23:25:00 +01:00
Thomas Capricelli
57275b2b8c make some changes to please clang, fix some warnings too. 2010-01-04 23:21:04 +01:00
Thomas Capricelli
95d9cb77f8 fix compilation in some cases 2010-01-04 22:45:33 +01:00
Gael Guennebaud
71a171c267 s/asMatrix()/matrix() 2010-01-04 19:13:08 +01:00
Gael Guennebaud
b6898996d4 fix dirty triangular unit test 2010-01-04 19:02:43 +01:00
Gael Guennebaud
8eab9fb87e port VectorwiseOp and Swap to the novel mechanisms, and various cleanning 2010-01-04 19:00:16 +01:00
Gael Guennebaud
826bff58c6 Fix #69 for the second time, and add the respective regression test 2010-01-04 17:36:26 +01:00
Benoit Jacob
80d1f9e966 remove debug output. sorry! 2010-01-02 18:01:39 -05:00
Benoit Jacob
ff94eaa4ae clarify docs as requested on forum 2010-01-02 12:55:32 -05:00
Benoit Jacob
25f8adfa6c * Fix bug #79: ei_alignmentOffset was assuming that ptr is multiple of
sizeof(Scalar), and that assumption breaks with double on linux x86-32.
* Rename ei_alignmentOffset to ei_first_aligned
* Rewrite its documentation and part of its body
* The variant taking a MatrixBase doesn't need a separate size argument.
2010-01-02 12:38:16 -05:00
Benoit Jacob
ed5c972801 put the assign assert and debug info before the assignment itself 2010-01-01 21:47:53 -05:00
Benoit Jacob
c436d94f18 Instead of EIGEN_JOBS, introduce EIGEN_MAKE_ARGS and EIGEN_CTEST_ARGS. This is much more powerful!
Notice that CTest 2.8 supports the -j argument, although that is undocumented.
Last commit of 2009! Happy new year to all!
2009-12-31 16:13:56 -05:00
Benoit Jacob
2038f9cc8d * The 'check' and 'buildtests' scripts no longer take a jobs parameter.
Instead, they honor the EIGEN_JOBS environment variable if defined.
* The syntax ${BLABLA} in bash scripts was conflicting with CMake configured
  file syntax. Resolved by using the @ONLY option and the @BLABLA@ syntax.
2009-12-30 15:07:05 -05:00
Jitse Niesen
233540e58a Refactoring of MatrixFunction: Simplify handling of fixed-size case. 2009-12-30 17:34:48 +00:00
Jitse Niesen
fcf821b77d Rename test per naming convention. 2009-12-28 22:30:08 +00:00
Jitse Niesen
d35cc381fe Refactor MatrixFunction class: Split new class MatrixFunctionAtomic off. 2009-12-27 20:44:19 +00:00
Jitse Niesen
a25c9b1e46 Simplify and document Sylvester equation solver in MatrixFunction. 2009-12-27 18:09:50 +00:00
Gael Guennebaud
72b6c05bf0 sorry for committing this mess 2009-12-23 13:30:25 +01:00
Gael Guennebaud
24302ad5cd fix #76, MayLinearVectorize depends on MaxSizeAtCompileTime and not on MaxInnerSize 2009-12-23 13:19:28 +01:00
Gael Guennebaud
0b5853d917 fix the xpr analyzer for Transpose 2009-12-23 13:17:46 +01:00
Gael Guennebaud
c90ccd089a clean a bit Hessenberg and make sure the subdiagonal coeff is real even for 2x2 matrices 2009-12-23 12:30:05 +01:00
Gael Guennebaud
791bac25f2 fix #75, and add a basic unit test for Hessenberg
(it was indirectly tested by the eigenvalue decomposition)
2009-12-23 12:18:54 +01:00
Gael Guennebaud
d65c8cb60a fix #69 and extend unit tests or triangular solvers 2009-12-23 11:48:53 +01:00
Gael Guennebaud
5adfe934c8 add checks for on the right triangular solving with matrices 2009-12-23 10:24:13 +01:00
Gael Guennebaud
fcc3be5dce a couple of fixes after thye merge 2009-12-23 09:07:01 +01:00
Gael Guennebaud
eaaba30cac merge with default branch 2009-12-22 22:51:08 +01:00
Gael Guennebaud
e182e9c616 extend the DenseStorageMatrix mechanism to all expressions 2009-12-22 17:37:11 +01:00
Jitse Niesen
eeec7d842e merge 2009-12-21 19:13:31 +00:00
Jitse Niesen
f54a2a0484 Add support for general matrix functions.
This does the job but it is only a first version. Further plans:
improved docs, more tests, improve code by refactoring, add convenience
functions for sine, cosine, sinh, cosh, and (eventually) add the matrix
logarithm.
2009-12-21 18:53:00 +00:00
Benoit Jacob
4ec99bbc0c support gcc 4.5 2009-12-21 13:49:43 -05:00
Jitse Niesen
9f1fa6ea5e Fix compilation error in doc/examples/class_CwiseBinaryOp.cpp .
This is a follow-up of 9d54783036
 (better work around for empty structs).
2009-12-21 18:16:01 +00:00
Jitse Niesen
32f6242b60 Set default for second argument for check script.
Otherwise, buildtests will be run with a second argument of "" if check
is called with only one argument, which leads to infinitely many jobs.
2009-12-21 11:35:08 +00:00
Gael Guennebaud
02beaea2f8 add missing inclusion of LU/arch, thanks to J.B. Rouault 2009-12-19 13:49:00 +01:00
Gael Guennebaud
f8cb9a6230 oops, remove duplicated ctor 2009-12-19 13:45:14 +01:00
Gael Guennebaud
9d54783036 much better workaround for empty struct (the previous one caused GCC 4.3 to generate wrong code leading to segfaults) 2009-12-18 17:08:59 +01:00
Gael Guennebaud
af4d8c5cec a couple of fixes, now Array passes the linearstructure test 2009-12-17 19:28:54 +01:00
Gael Guennebaud
4b70b47998 clean a bit Matrix and fix static Map functions 2009-12-17 14:48:26 +01:00
Gael Guennebaud
5ca90e1b0c some cleaning in DenseStorageBase 2009-12-17 13:56:33 +01:00
Gael Guennebaud
ebb2878829 finally add a Array class with storage via the introduction of a DenseStorageBase
base class shared by both Matrix and Array
2009-12-17 13:37:00 +01:00
Gael Guennebaud
4e9c227bd5 partial LU optimization: noalias 2009-12-17 11:43:42 +01:00
Gael Guennebaud
30d47860dd more fixes 2009-12-17 10:43:46 +01:00
Gael Guennebaud
34c95029ca a couple of fixes and cleaning 2009-12-17 10:00:35 +01:00
Jitse Niesen
945cbc3bc6 Add test for issue #75 (Hessenberg of 1x1 matrix).
Also remove an superfluous #include in matrixExponential test.
2009-12-16 22:24:24 +00:00
Gael Guennebaud
2033903376 a trivial compilation fix 2009-12-16 19:21:10 +01:00
Gael Guennebaud
9f79558839 a lot of cleaning and fixes 2009-12-16 19:18:40 +01:00
Gael Guennebaud
22a6ab1f4b add an eigen2support test and a few fixes 2009-12-16 17:37:21 +01:00
Benoit Jacob
5cb779e5e1 * introduce ei_alignmentOffset(MatrixBase&,Integer)
couldnt put it in Memory.h as it needs the definition of MatrixBase
* make Redux use it
2009-12-16 08:53:14 -05:00
Gael Guennebaud
e0aa29121f this really fix the previous warning 2009-12-16 13:06:47 +01:00
Gael Guennebaud
c35fcf3bbd fix warning by making ei_empty_struct::_ei_dummy_ private 2009-12-16 12:53:55 +01:00
Gael Guennebaud
bb59c22dc9 fix compilation when mixing types 2009-12-16 12:48:15 +01:00
Gael Guennebaud
6db6774c46 * fix aliasing checks when the lhs is also transposed. At the same time,
significantly simplify the code of these checks while extending them
  to catch much more expressions!
* move the enabling/disabling of vectorized sin/cos to the architecture traits
2009-12-16 11:41:16 +01:00
Gael Guennebaud
7a9988ebb6 fix spasre triangular solve for row major lower matrices 2009-12-14 10:25:21 +01:00
Thomas Capricelli
0d8ffe5240 ignore more build*/ directories 2009-12-11 02:39:49 +01:00
Gael Guennebaud
a314814a6e suppress unused variable warnings 2009-12-15 13:59:02 +01:00
Benoit Jacob
949f14e1e4 no, this wasn't equivalent to ei_pload at all, after all! 2009-12-15 07:43:05 -05:00
Benoit Jacob
805eb9cc8b Gael, who is a man of few words^Winstructions, is right, as usual. 2009-12-15 06:50:40 -05:00
Hauke Heibel
3ea1f97f69 Suppressed the warning for missing assignment generators (forgot that in the last submission).
Commented Quake3's fast inverser sqrt in SSE's MathFunction header.
2009-12-15 08:09:14 +01:00
Benoit Jacob
46a9cac7fb silence 'statement has no effect' warning with gcc 4.4 2009-12-14 23:31:00 -05:00
Benoit Jacob
4948448939 *use scalar instructions, packet not needed here
*remove unused var warning
2009-12-14 23:13:54 -05:00
Benoit Jacob
39095c8faa only include SSE path if SSE enabled 2009-12-14 22:52:11 -05:00
Benoit Jacob
d02eccf584 add SSE path for Matrix4f inverse, taken from Intel except that we do a kosher
division instead of RCPPS-followed-by-Newton-Raphson. The rationale for that is
that elsewhere in Eigen we dont allow ourselves this approximation (which throws
2 bits of mantissa), so there's no reason we should allow it here.
2009-12-14 22:47:14 -05:00
Benoit Jacob
d5f3b2dc94 change the Arch constants: const int ---> enum, more explicit names, and use
of a namespace instead of Prefix_Name.
2009-12-14 17:26:24 -05:00
Hauke Heibel
832045d363 Warning 4512 (assignment operators could not be generated) is now simply disabled.
All unimplemented assignment operators have been removed.
2009-12-14 10:32:43 +01:00
Hauke Heibel
4498864fc8 Fixed a bad type conversion. 2009-12-13 09:26:57 +01:00
Jitse Niesen
63957ad5d6 Remove //@{ ... //@} for same reason as in changeset 2026ea7ff2
.
2009-12-13 00:29:31 +00:00
Jitse Niesen
929521678d Correct type of ei_solve_retval<LLT,...>::operator= 2009-12-12 23:54:44 +00:00
Hauke Heibel
3dce51bd8e Removed more warnings. 2009-12-12 14:49:43 +01:00
Hauke Heibel
d088ee35f6 Added to possibility to compile unit tests at maximum warning level.
Silenced (amongst others) many conversion related warnings.
2009-12-12 11:39:07 +01:00
Hauke Heibel
494a88685e Fixed the bad fix - now the unsupported examples and snippets work on windows. 2009-12-11 19:39:01 +01:00
Hauke Heibel
9a8c16810b Reverted Jitse's change - the targets unsupported_examples and unsupported_snippets are unknown over here. 2009-12-11 19:11:01 +01:00
Jitse Niesen
2026ea7ff2 Coax doxygen in producing better docs for MatrixFunctions.
The //@{ ... //@} in unsupported/Eigen/MatrixFunctions for some reason
caused doxygen to list the constructor of the MatrixExponential class
as a separate function in the MatrixFunctions module without any reference
to the class; very confusing.
2009-12-11 15:54:21 +00:00
Thomas Capricelli
7d444375e7 fix compilation (for some reason the pb happens only under windows) 2009-12-11 02:38:28 +01:00
Gael Guennebaud
9facdaf7b9 some compilation fixes 2009-12-10 22:15:22 +01:00
Gael Guennebaud
7caf751fdd adapt select, replicate and reverse 2009-12-10 22:00:35 +01:00
Benoit Jacob
d2e44f2636 * 4x4 inverse: revert to cofactors method
* inverse tests: use createRandomMatrixOfRank, use more strict precision
* tests: createRandomMatrixOfRank: support 1x1 matrices
* determinant: nest the xpr
* Minor: add comment
2009-12-09 12:43:25 -05:00
Benjamin Schindler
f0315295e9 Handle row and col major matrices in the gdb pretty printer 2009-12-08 19:12:26 +01:00
Benjamin Schindler
4da991eaa8 Display the data ptr as part of the header 2009-12-08 18:40:36 +01:00
Benjamin Schindler
a4c162dbdc Correct license header of the gdb pretty printer 2009-12-08 18:18:05 +01:00
Benjamin Schindler
f2304f3b88 Adding __init__.py so the printers can be used directly from the checkout 2009-12-08 18:17:46 +01:00
Hauke Heibel
64beff03b6 Added a 'pretty printer' for the msvc debugger (tested on Visual Studio 2008). 2009-12-08 18:09:00 +01:00
Benjamin Schindler
097cab26fb Added a pretty printer python script for Eigen::Matrix (gdb-7.0 and later). 2009-12-08 18:06:03 +01:00
Jitse Niesen
8bfa354ee3 Documentation clean up.
* remove non-existant reference to CwiseAll
* define \householder_module (used in HouseholderSequence.h)
* update I01_TopicLazyEvaluation.dox - Product is now called GeneralProduct
* remove reference to list of examples which was deleted ages ago
* rename PartialLU_solve.cpp snippet to PartialPivLU_solve.cpp
2009-12-08 15:12:27 +00:00
Jitse Niesen
a682a0eeb1 C05_TutorialLinearAlgebra.dox: Correct file name 2009-12-08 11:08:04 +00:00
Jitse Niesen
39ceba409b Various improvements to the docs for unsupported.
* Enable compilation of examples for unsupported.
* Fix use of std::vector in BVH example.
* Add an example for the matrix exponential.
* Bug fixes in unsupported/doc/{examples,snippets}/CMakeLists.txt .
2009-12-07 19:10:11 +00:00
Gael Guennebaud
8e05f9cfa1 add a DenseBase class for MAtrixBase and ArrayBase and more code factorisation 2009-12-04 23:17:14 +01:00
Gael Guennebaud
36969cc2a5 add a slerp benchmark (for accuracy and speed)) 2009-12-04 15:02:38 +01:00
Gael Guennebaud
c68c695b87 Fix poor Quaternion::slerp snapping 2009-12-04 15:01:17 +01:00
Gael Guennebaud
ea684af6b4 merge 2009-12-04 12:40:29 +01:00
Gael Guennebaud
7aad434160 fix compilation and clean a bit Map<Quaternion> 2009-12-04 12:26:56 +01:00
Marton Danoczy
ffaea19a70 Fixed compilation warnings in MSVC with Scalar==float 2009-12-03 14:01:34 +01:00
bjornpiltz
af17770680 Fix compilation for MSVC. 2009-12-03 09:27:15 +01:00
Mark Borgerding
012cd62c81 explicitly cast to use the acos(long double) 2009-12-02 22:58:34 -05:00
Mark Borgerding
e5c91b4e95 removed troublesome M_PI and M_PIl constants 2009-12-02 17:23:09 -05:00
Gael Guennebaud
e12f5adbde fix MSVC10 compilation 2009-12-02 19:32:54 +01:00
Benoit Jacob
de25059502 * Remove test_ prefix in tests
* tests now honor EIGEN_REPEAT and EIGEN_SEED if no arguments were passed
2009-12-02 12:07:47 -05:00
Benoit Jacob
b0100a336a merge 2009-12-02 11:12:02 -05:00
Benoit Jacob
3e73f6036c * HouseholderSequence:
* be aware of number of actual householder vectors
    (optimization in non-full-rank case, no behavior change)
  * fix applyThisOnTheRight, it was using k instead of actual_k
* QR: rename matrixQ() to householderQ() where applicable
2009-12-02 11:11:09 -05:00
Hauke Heibel
e3b5a90611 Removed unused 'benchmark'. 2009-12-02 16:51:40 +01:00
Benoit Jacob
3279e39340 * fix include for case-sensitive filesystem
* on GNU, clock_gettime requires linking -lrt
2009-12-02 10:03:16 -05:00
Mathieu Gautier
26ea7c9801 * remove empty destructors in Matrix.h and MatrixStorage.h 2009-12-02 11:09:56 +01:00
Hauke Heibel
84551d067e merge 2009-12-02 11:08:44 +01:00
Hauke Heibel
95861fbd6c Added NestByValue and .nestByValue() again for the sake of backwards compatibility. 2009-12-02 10:53:30 +01:00
Hauke Heibel
e3612bc0b8 Removed unnecessary code. 2009-12-02 09:11:24 +01:00
Mark Borgerding
c05ae35441 merge with tip 2009-12-01 18:03:15 -05:00
Mark Borgerding
ff1e9542f6 added comments to help vim understand the header files are c++. 2009-12-01 18:00:29 -05:00
Mark Borgerding
d1e06721a2 instruction to remove CMakeCache.txt for out-of-source build 2009-12-01 17:39:29 -05:00
Mark Borgerding
0e8cd8de4d quieted signed/unsigned comparison warning 2009-12-01 17:38:23 -05:00
Mark Borgerding
8fce0b5459 added newline at the end of file to quiet gcc warning 2009-12-01 17:37:33 -05:00
Thomas Capricelli
291fd4f8da merge 2009-12-01 21:07:20 +01:00
Benoit Jacob
68117c267c ColPivQR: now the unit tests even succeeds:
* with random matrices multiplied by 1e+8 (i.e. fixed wrong absolute fuzzy compare)
* with 10,000 repetitions (i.e. the fuzzy compare is really clever)
and when it occasionnally fails, less than once in 10,000 repeats, it is only on the exact rank computation.
2009-12-01 13:51:35 -05:00
Benoit Jacob
95d88e1327 Big reworking of ColPivQR and its unit test, which now passes even with thousands of repetitions and correctly tests matrices of all sizes. Several surprises along the way: for example, a major cause of trouble was the optimized "table of column squared norms" where the accumulation of imprecision was a serious issue; another surprise is that tests like "x!=0" before dividing by x really benefit from being replaced by fuzzy tests, as i hit real cases where i got wrong results in 1/epsilon. 2009-12-01 13:26:29 -05:00
Benoit Jacob
49c0986d86 minor cleanup 2009-12-01 13:22:14 -05:00
Hauke Heibel
d3250cb38f That's it NestByValue and .nestByValue() are both gone! 2009-12-01 13:29:08 +01:00
Hauke Heibel
b08d5b2d2c Even more NestByValue cleanup... 2009-12-01 13:16:51 +01:00
Hauke Heibel
2bf354da80 Much more NestByValue cleanup. 2009-12-01 11:51:22 +01:00
Hauke Heibel
3091be5134 Removed NestByValue dependency from Cholesky, Eigenvalues, LU and QR. 2009-12-01 10:22:54 +01:00
Hauke Heibel
7b3e205ebd Removed NestByValue dependency from VectorwiseOp. 2009-12-01 09:56:40 +01:00
Hauke Heibel
88be826791 Removed NestByValue dependency from MatrixBase::select(). 2009-12-01 09:49:15 +01:00
Hauke Heibel
82971a5dcd Adapted the number of test runs. 2009-12-01 09:29:56 +01:00
Hauke Heibel
1fc5fdea25 Added missing typedef (will I ever learn it!?)
Removed unsupported directories that do not provide CMakeList.txt (CMake 2.8 warning).
The BenchTimer is now also working on Cygwin.
2009-12-01 09:20:05 +01:00
Hauke Heibel
052742e6f9 merge 2009-12-01 07:55:07 +01:00
Hauke Heibel
7af1ee0b6c Added the profiling test to unsupported. 2009-12-01 07:53:09 +01:00
Gael Guennebaud
b2a5fb874f add specialization ei_ref_selector for sparse matrix types 2009-12-01 06:21:29 +01:00
Thomas Capricelli
120882c4f1 fix another 'duplicated content in doxygen pages' bug : exclude *.orig
files
2009-11-30 19:42:00 +01:00
Hauke Heibel
e6c560aedf Removed wrong typename. 2009-11-30 19:06:07 +01:00
Hauke Heibel
1c2e476fa7 Initial commit for a modified ei_nested logic. 2009-11-30 18:56:56 +01:00
Hauke Heibel
66534b782c Some of our unit tests require mathematical constants and thus we rely on non-ansi code.
It seems as if the new standard removed pow(T,int).
M_PIL is only defined when _GNU_SOURCE is defined.
2009-11-30 16:54:04 +01:00
Thomas Capricelli
21ff296652 Adapted a mail from Mark about some design and add it as documentation for
the FFT module.
2009-11-30 16:21:21 +01:00
Thomas Capricelli
a255336e4f fix doc 2009-11-28 02:42:05 +01:00
Benoit Jacob
4b1aca2288 precision ---> dummy_precision 2009-11-26 22:05:02 -05:00
Thomas Capricelli
c245054aa8 cleaning 2009-11-26 08:30:38 +01:00
Thomas Capricelli
f948df5a72 cleaning 2009-11-26 07:37:37 +01:00
Thomas Capricelli
db39f892a3 kill yet another un-needed parameter 2009-11-26 05:48:38 +01:00
Thomas Capricelli
905aecf803 make qrsolv use eigen types 2009-11-26 04:29:51 +01:00
Thomas Capricelli
e18caf7a01 clean qrsolv 2009-11-26 04:06:40 +01:00
Thomas Capricelli
e95f736402 reduce ei_qrsolv() signature, wa is actually a 'working array' 2009-11-26 03:26:41 +01:00
Benoit Jacob
5923bcb1b9 improve the scripts for building unit tests:
* support unsupported/
* use egrep instead of grep, properly escape special chars.
2009-11-25 21:26:37 -05:00
Thomas Capricelli
746c787a76 computes column norms outside of ei_qrfac() 2009-11-26 02:53:58 +01:00
Thomas Capricelli
9cbfdbad22 cleaning 2009-11-26 02:42:27 +01:00
Thomas Capricelli
f795681da0 export stableNorm(), blueNorm() and hypotNorm() to colwise() and rowwise()
+ rudimentary test
2009-11-26 02:28:13 +01:00
Thomas Capricelli
dca80b5f22 use typedef 2009-11-25 23:08:46 +01:00
Thomas Capricelli
a6380ae272 silent warnings 2009-11-25 23:08:39 +01:00
Benoit Jacob
40ce7589de Added tag actual-start-from-scratch for changeset 1dabb45d94 2009-11-25 10:57:32 -05:00
Benoit Jacob
1e2bcba5e4 forward port slight changes in the 4x4 inverse test 2009-11-25 09:08:03 -05:00
Benoit Jacob
684d76eba3 add SSE4 support, start with integer multiplication 2009-11-24 15:12:43 -05:00
Benoit Jacob
abdb2a2bd5 fix assert and handle Unit shapes 2009-11-24 12:14:40 -05:00
Benoit Jacob
e6ea9e401c improve precision test 2009-11-23 11:24:06 -05:00
Benoit Jacob
44d0d667cd 4x4 inverse:
* change block selection threshold from 1e-2 to 1e-1
* add rigorous precision test
2009-11-23 10:13:21 -05:00
Thomas Capricelli
06f11f3379 fix important typo 2009-11-21 02:00:47 +01:00
Gael Guennebaud
80ebeae48d Add the concept of base class plugins, and started to write the ArrayBase class.
Sorry for this messy commit but I have to commit it...
2009-11-20 18:20:55 +01:00
Gael Guennebaud
4af1753b6f * remove EnforceAlignedAccess option to Block, VectorBlock, Map and MapBase
because thanks to the previous commit this is not needed anymore
* add a more general ForceAlignedAccess expression which can be used for any expression.
  It is already used by StableNorm.h.
2009-11-20 16:30:14 +01:00
Benoit Jacob
3c5e32f0da improvements in FindEigen*.cmake, ported from changes in CMakeLists.txt:
- better regular expression
 - grep the whole file, not expensive anyway, more robust
2009-11-20 10:17:59 -05:00
Gael Guennebaud
eb8f450071 Hey, finally the copyCoeff stuff is not only used to implement swap anymore :)
Add an internal pseudo expression allowing to optimize operators like +=, *= using
the copyCoeff stuff.
This allows to easily enforce aligned load for the destination matrix everywhere.
2009-11-20 15:39:38 +01:00
Jitse Niesen
34be9d4537 Replace toDense() by toDenseMatrix() in tests. 2009-11-20 12:22:46 +00:00
Jitse Niesen
b0baf43114 Eigen/CMakeLists.txt: remove parens from if.
Only CMake 2.6.3 and later recognize this syntax, and at the moment we
require 2.6.2. CMake uses the right precendence, per its man page, so the
parentheses are not necessary.
2009-11-20 11:26:26 +00:00
Benoit Jacob
6cbf662f14 * don't laugh, but these bugs took me forever to fix.
* expand unit tests to make sure to catch them: they nearly escaped the existing tests as these memory violations were highly dependent on the numbers of rows and cols.
2009-11-19 22:01:13 -05:00
Benoit Jacob
eac3232095 minor improvements in triangular stuff 2009-11-19 20:50:50 -05:00
Benoit Jacob
88b551e89b * fix compilation of unit-tests (sorry, had tested only 1 channel)
* remove buggy (superfluous?) specialization in the meta-unroller
2009-11-19 19:20:19 -05:00
Benoit Jacob
a20a744adc TriangularMatrix: extend to rectangular matrices 2009-11-19 17:07:55 -05:00
Benoit Jacob
2275f98d7b move signature file to root directory, where it belongs 2009-11-19 12:41:28 -05:00
Benoit Jacob
bbf0eb35a7 * in Eigen/CMakeLists.txt, finally do a globbing to we no longer will have problems with "oops forgot to install new module".
* add a file Eigen/signature_of_eigen3_matrix_library, use it to make FindEigen3.cmake more solid: able to find Eigen in either eigen3/ or eigen/ and not mix it up with Eigen2.
2009-11-19 12:31:11 -05:00
Benoit Jacob
b5f4636d42 * eigen2->eigen3
* bump version to 2.91.0
* add FindEigen3.cmake
2009-11-19 12:09:04 -05:00
Benoit Jacob
abb2a1bb15 simplification 2009-11-18 17:44:20 -05:00
Benoit Jacob
126a8e6a69 fix remaining bug in ColPivHouseholderQR, so now all tests pass again 2009-11-18 17:40:45 -05:00
Benoit Jacob
40865fa28c fix bugs, old and new:
* old bug: in CwiseBinaryOp: only set the LinearAccessBit if both sides have the same storage order.
* new bug: in Assign.h, only consider linear traversal if both sides have the same storage order.
2009-11-18 17:20:39 -05:00
Benoit Jacob
11fa2ae2c6 temporarily disable linear traversal.
Actually I don't think it's buggy. But it probably triggers existing bugs, I suspect that
some xprs have LinearAccessBit and shouldn't have it.
Also this fixes the "bugs" with JacobiSVD ---> now it works again
2009-11-18 16:31:14 -05:00
Benoit Jacob
8860203e6a fix stuff after the PermutationMatrix changes.
I still have JacobiSVD errors when cols>rows
2009-11-18 12:41:24 -05:00
Gael Guennebaud
e3d890bc5a Another big refactoring change:
* add a new Eigen2Support module including Cwise, Flagged, and some other deprecated stuff
* add a few cwiseXxx functions
* adapt a few modules to use cwiseXxx instead of the .cwise() prefix
2009-11-18 18:15:19 +01:00
Benoit Jacob
94c706d04f Assign.h: add LinearTraversal (non-vectorized index-based traversal)
Rename some constants to make names match more closely what they mean.
2009-11-18 11:57:07 -05:00
Gael Guennebaud
0529ecfe1b Big refactoring/cleaning in the spasre module with
in particular the addition of a selfadjointView, and the
extension of triangularView. The rest is cleaning and does not
change/extend the API.
2009-11-18 14:52:52 +01:00
Gael Guennebaud
1e62e0b0d8 more ET refactoring:
* extend Cwise for multiple storage base class
* a lot of cleaning in the Sparse module
2009-11-17 16:04:19 +01:00
Benoit Jacob
9f21e2aab7 port the QR module to PermutationMatrix 2009-11-17 08:14:54 -05:00
Gael Guennebaud
63bcc1c0fb adapt CwiseBinaryOp and the Sparse counter part 2009-11-17 10:11:27 +01:00
Benoit Jacob
30b610a10f vade retro 2009-11-16 21:45:01 -05:00
Benoit Jacob
ac00902f84 for consistency: PlainMatrixType ---> DenseMatrixType 2009-11-16 21:43:15 -05:00
Benoit Jacob
984c000778 addToDense ---> addTo
subToDense ---> subTo
2009-11-16 21:33:41 -05:00
Benoit Jacob
07412b2075 PermutationMatrix: add setIdentity and transpositions methods
LU: make use of that
2009-11-16 21:28:26 -05:00
Benoit Jacob
b90744dc05 Port FullPivLU to PermutationMatrix 2009-11-16 17:05:12 -05:00
Benoit Jacob
76c614f9bd PartialPivLU: port to PermutationMatrix
PermutationMatrix: add resize()
2009-11-16 15:36:07 -05:00
Benoit Jacob
eb6df28c6c DiagonalMatrix: release-quality documentation
BandMatrix: rename toDense() ---> toDenseMatrix() for consistency
2009-11-16 15:25:58 -05:00
Benoit Jacob
e8d0dbf82e PermutationMatrix:
* make multiplication order not be reversed
 * release-quality documentation
2009-11-16 15:07:33 -05:00
Benoit Jacob
8a1bada43d initialize-by-zero: remember that when the newsize==oldsize, resize() must remain a NOP 2009-11-16 13:45:06 -05:00
Gael Guennebaud
1c9a2d246f adapt CwiseUnaryOp and CwiseUnaryView 2009-11-16 19:39:29 +01:00
Gael Guennebaud
2a3a6fe45e Experiment the ET refactoring on Transpose for Dense and Sparse storages.
All tests work fine.
2009-11-16 18:19:08 +01:00
Benoit Jacob
307898e84b merge 2009-11-16 09:39:59 -05:00
Benoit Jacob
b25eb5fdaa PermutationMatrix: add inverse() and product of permutations 2009-11-16 09:39:07 -05:00
Benoit Jacob
e09768e3bc handle make errors ---> exit, don't run ctest 2009-11-16 09:38:44 -05:00
Thomas Capricelli
a89b22f352 rename test for coherency with previous renaming of the module 2009-11-16 04:34:04 +01:00
Thomas Capricelli
f7e73f1bf9 don't be shy and test them all 2009-11-16 04:20:13 +01:00
Benoit Jacob
955cd7f884 * add PermutationMatrix
* DiagonalMatrix:
   - add MaxSizeAtCompileTime parameter
   - DiagonalOnTheLeft ---> OnTheLeft
   - fix bug in DiagonalMatrix::setIdentity()
2009-11-15 21:12:15 -05:00
Benoit Jacob
1aaa9059c0 maketests -> buildtests 2009-11-15 19:26:28 -05:00
Benoit Jacob
9aa37f3108 prevent in-source builds. hope it's ok with you... it's still possible, of course, to have the build dir as a subdir of the source dir. 2009-11-15 00:11:33 -05:00
Benoit Jacob
3f04a14d7c there's no reason why we should follow the FSF's stupid recommendation for the naming of these files, right? This could give the wrong impression that Eigen is only GPL-licensed. 2009-11-14 23:26:07 -05:00
Benoit Jacob
c4dacabcc8 add workaround for Guillaume 2009-11-14 22:04:55 -05:00
Mathieu Gautier
6680fa42ee * add Map<Quaternion> test based on Map from test/map.cpp
* replace implicit constructor AngleAxis(QuaternionBase&) by an explicit one, it seems ambiguous for the compiler
* remove explicit constructor with conversion type quaternion(Quaternion&): conflict between constructor.
* modify EIGEN_INHERIT_ASSIGNEMENT_OPERATORS to suit Quaternion class
2009-11-13 16:41:51 +01:00
Jitse Niesen
d07c05b3a5 Build tests for unsupported modules if EIGEN_LEAVE_TEST_IN_ALL_TARGET 2009-11-13 13:05:57 +00:00
Benoit Jacob
7e3c4096d8 xargs ---> xargs echo
(xargs alone doesnt seem to be documented in the man page, while xargs echo is documented)
2009-11-12 15:37:50 -05:00
Benoit Jacob
9b7708f660 introduce check target, and some renaming 2009-11-12 15:02:52 -05:00
Benoit Jacob
8b563d7163 ouch, avoid infinite loop!
optimization is not so important here, so a for loop will do.
2009-11-12 14:08:47 -05:00
Benoit Jacob
5266a78aca also optionnally initialize by zero after resizing 2009-11-12 12:49:00 -05:00
Benoit Jacob
8132ee3908 * add non-default option to initialize matrices by 0
(useful for porting)
* maketests really has to be in test/
2009-11-12 12:39:22 -05:00
Benoit Jacob
358452bbe6 * add ./debug and ./release scripts
* update the messages
* rename EIGEN_CMAKE_RUN_FROM_CTEST to something saner
2009-11-12 12:07:18 -05:00
Benoit Jacob
fc492b6264 add mctestr script. In your build directory, just do:
./mctestr ^qr 5
and it will build all tests matching ^qr with 5 jobs and then do `ctest -R ^qr`
2009-11-12 09:35:10 -05:00
Benoit Jacob
bc18ba7e49 * add maketests script. It is like make but takes a regexp allowing to build selected targets. Next step will be a "mctestr" script doing that and then calling ctest -R.
* in runtest.sh, don't override the default number of repeats. If one thinks the default should be changed, let's change it at the source.
2009-11-11 21:25:21 -05:00
Benoit Jacob
ff7fbc9431 * use standard CMAKE_BUILD_TYPE
* remove debug_xxx targets
* runtest.sh: don't run make
2009-11-11 16:11:33 -05:00
Jitse Niesen
343eec7ca8 Compilation fix: makeHousholderInPlace now uses references. 2009-11-11 16:23:09 +00:00
Benoit Jacob
bf691cc3f1 fix PowerPC platform detection 2009-11-11 10:52:00 -05:00
Thomas Capricelli
b53c2fcc99 fix for *.pc install dir (suggested by Ingmar Vanhassel on IRC) 2009-11-11 15:28:39 +01:00
Benoit Jacob
a440385b41 *adapt Householder to the convention that we now favor refs over ptrs for output. Keep "workspace" as pointer because it is an array (which is now more obvious).
*rename makeHouseholderSequence to householderSequence, because that's what it returns.
2009-11-10 21:22:20 -05:00
Thomas Capricelli
e06aa749a4 doxygen : exclude diff files 2009-11-10 22:17:23 +01:00
Thomas Capricelli
2612bbdf8b make the complex module appear in doxygen + small documentation 2009-11-10 22:02:10 +01:00
Thomas Capricelli
d47a723a6e make FFT appear in doxygen doc, and provide a mininum of documentation 2009-11-10 21:58:17 +01:00
Thomas Capricelli
2c9f46d151 fix Skyline module doxygen stuff 2009-11-10 21:47:57 +01:00
Thomas Capricelli
df117a64c7 merge with main repository 2009-11-10 21:34:43 +01:00
Thomas Capricelli
ae76c97704 documentation fixes 2009-11-10 21:33:36 +01:00
Gael Guennebaud
f647fb8dd4 fix compilation and removed some unused stuff in skyline 2009-11-10 21:22:55 +01:00
Thomas Capricelli
6a56262bf4 merge with main repository 2009-11-10 20:31:07 +01:00
Gael Guennebaud
58632c1652 fix #68 I did not see the skyline matrix patch contained that 2009-11-10 14:19:03 +01:00
Gael Guennebaud
1879403562 mv the Skyline module to unsupported/ 2009-11-10 12:47:42 +01:00
Thomas Capricelli
42b92c2022 merge with main repository 2009-11-09 19:02:52 +01:00
Thomas Capricelli
77fd44a246 revert previous commit on the matter : once doxygen cache is flushed
this gives very bad results
2009-11-09 19:00:48 +01:00
Benoit Jacob
92749eed11 * merge
* remove a ctor in QuaternionBase as it gives a strange error with GCC 4.4.2.
2009-11-09 09:08:03 -05:00
Benoit Jacob
4b366b07be add missing includes 2009-11-09 08:04:20 -05:00
Benoit Jacob
9a0900e33e last round of changes, mainly to return derived types instead of base types, and fix various compilation issues 2009-11-09 07:51:31 -05:00
Gael Guennebaud
670651e2e0 Quaternion: fix compilation, cleaning 2009-11-09 10:48:18 +01:00
Thomas Capricelli
087df89e20 few doc fixes 2009-11-09 06:45:27 +01:00
Thomas Capricelli
d1cc2745f7 Reduce general diff with eigen-tip. Moreover, this test now seems to pass
again.
2009-11-09 05:12:50 +01:00
Thomas Capricelli
17f3e8571c more documentatin 2009-11-09 04:52:47 +01:00
Thomas Capricelli
3e17046668 only define groups once in unsupported, in order to prevent ambiguity for
the group names.
2009-11-09 04:36:01 +01:00
Thomas Capricelli
de195e0e78 some more documentation 2009-11-09 04:21:45 +01:00
Thomas Capricelli
ac8f7d8c9c various fixes in headers 2009-11-09 03:32:40 +01:00
Thomas Capricelli
71a3e96b49 rename NonLinear to NonLinearOptimization 2009-11-09 03:27:15 +01:00
Thomas Capricelli
09cb27c587 documentation + move "namespace eigen" to the main file, as others do. 2009-11-09 03:25:21 +01:00
Thomas Capricelli
cddc83752c starting documentation 2009-11-09 03:07:36 +01:00
Thomas Capricelli
ecbcdafb0f include NonLinearOptimization_Module and NumericalDiff_Module
+ cleaning
2009-11-09 03:06:23 +01:00
Benoit Jacob
e4e58e8337 simplifications in the ei_solve_impl system, factor out some boilerplate code 2009-11-08 16:51:41 -05:00
Thomas Capricelli
751a333491 merge with main repository 2009-11-08 22:27:32 +01:00
Benoit Jacob
ba7bfe110c port the qr module to ei_solve_xxx. 2009-11-08 10:21:26 -05:00
Gael Guennebaud
aa0974286f fix compilation adding a makeconst helper struct 2009-11-07 09:07:23 +01:00
Gael Guennebaud
5dc02fe5e9 improve a bit AutoDiffVector, but it still not working 2009-11-06 11:34:58 +01:00
Gael Guennebaud
6647a58847 update product bench 2009-11-06 11:33:18 +01:00
Gael Guennebaud
771c0507fb back out previous back out, and this time don't forget
to include the NumTraits.h file in the commit ;)
2009-11-06 11:23:18 +01:00
Jitse Niesen
1470afda5b Backed out previous changeset: Does not compile.
There is no member Nested in NumTraits.
2009-11-06 09:16:25 +00:00
Gael Guennebaud
fe81b3f651 Add the possibility to control the storage mode of scalar value (by value or reference)
in order to avoid unecessary copies when using complex scalar types (e.g., a AutoDiffScalar)
2009-11-05 18:06:33 +01:00
Jitse Niesen
daa4574a43 Add regression test for issue #66 (ComplexSchur of zero matrix). 2009-11-05 03:46:18 +00:00
Benoit Jacob
68210b03c1 port svd to the ei_xxx_return_value thing
this commit made in caltrain from Palo Alto to SF
2009-11-04 21:00:12 -05:00
Benoit Jacob
4c456d4211 fix bug in svd solve reported on forum, was apparently assuming square matrix, not sure how the unit test could work. 2009-11-04 11:46:17 -05:00
Hauke Heibel
3979f6d8aa Let's try to stick to the original code, thus activate the fix of #62 only for 64 bit builds. 2009-11-04 15:49:22 +01:00
Hauke Heibel
e2170b9f7e Direct access of the packet structs fixes bug #62 and doe not seem to
influence compiler optimization.
2009-11-04 15:38:11 +01:00
kayhman
1333fe651d Added basic SkylineMatrix. 2009-11-04 15:18:12 +01:00
Mark Borgerding
103f741619 initialize Eigen::Complex arrays 2009-11-09 14:08:44 -05:00
Gael Guennebaud
a7bebe0aeb an attempt to fix a compilation issue with MSVC 2009-11-04 09:04:50 +01:00
Benoit Jacob
0182695204 move cholesky to ei_xxx_return_value 2009-11-03 11:34:45 -05:00
Benoit Jacob
a77872dd6c move partial-pivoting lu to ei_solve_impl 2009-11-03 03:06:34 -05:00
Benoit Jacob
da363d997f introduce ei_xxx_return_value and ei_xxx_impl for xxx in solve,kernel,impl
put them in a new internal 'misc' directory
2009-11-03 02:18:10 -05:00
Gael Guennebaud
979431b987 fix #66 : upper triangular checks in ComplexSchur 2009-11-02 10:46:40 +01:00
Benoit Jacob
5ba19a53a6 rephrase tutorial on Map 2009-10-31 14:37:11 -04:00
Benoit Jacob
3ae4e3880f fix compilation 2009-10-31 14:36:31 -04:00
Benoit Jacob
48261fc773 * default MatrixBase ctor: make it protected, make it a static assert, only do the check when debugging eigen to avoid slowing down compilation for everybody (this check is paranoiac, it's very seldom useful)
* add private MatrixBase ctors to catch cases when the user tries to construct MatrixBase objects directly
2009-10-31 11:50:15 -04:00
Mark Borgerding
ec70f8006b added inlines to a bunch of functions 2009-10-31 00:13:22 -04:00
Mark Borgerding
4c3345364e moved half-spectrum logic to Eigen::FFT 2009-10-30 23:38:13 -04:00
Mark Borgerding
d659fd9b14 moved real-half-spectrum reflection into Eigen::FFT 2009-10-30 20:26:30 -04:00
Mark Borgerding
a26b729cc9 moved scaling to Eigen::FFT 2009-10-30 19:50:11 -04:00
Mark Borgerding
0fa68b9e50 switched to BenchUtil.h 2009-10-30 19:46:45 -04:00
Benoit Jacob
f975b9bd3e SVD::solve() : port to new API and improvements 2009-10-30 08:51:33 -04:00
Benoit Jacob
6b48e932e9 *port the Cholesky module to the new solve() API
*improve documentation
2009-10-29 21:11:05 -04:00
Benoit Jacob
a2268ca6b3 properly implement BenchTimer on POSIX
(may require a platform check for the clock name on non-linux platforms)
2009-10-29 15:47:56 -04:00
Hauke Heibel
d0562bd473 corrected the computation cost of mean 2009-10-29 19:58:54 +01:00
Hauke Heibel
c70a603e34 added mean() reduction 2009-10-29 19:56:58 +01:00
Gael Guennebaud
e513cc75c4 oops I forgot to include that file in the previous commit (fixing #65) 2009-10-29 14:24:09 +01:00
Gael Guennebaud
541eac0828 fix #65: MatrixBase::nonZero() 2009-10-29 14:22:02 +01:00
Mark Borgerding
7911df4b6e improved selftest for Eigen::Complex -- mainly a documentation of what does not work 2009-10-28 23:22:10 -04:00
Mark Borgerding
288ba155f1 forgot Complex test file 2009-10-28 23:05:18 -04:00
Mark Borgerding
938f03e5cf added many inlines and attempted to fix castable pointer so it works with std::vector 2009-10-28 23:02:18 -04:00
Benoit Jacob
e8dd552257 sync with mainline 2009-10-28 19:06:45 -04:00
Benoit Jacob
2840ac7e94 big huge changes, so i dont remember everything.
* renaming, e.g. LU ---> FullPivLU
* split tests framework: more robust, e.g. dont generate empty tests if a number is skipped
* make all remaining tests use that splitting, as needed.
* Fix 4x4 inversion (see stable branch)
* Transform::inverse() and geo_transform test : adapt to new inverse() API, it was also trying to instantiate inverse() for 3x4 matrices.
* CMakeLists: more robust regexp to parse the version number
* misc fixes in unit tests
2009-10-28 18:19:29 -04:00
Benoit Jacob
6219f9acfa * rename new Quat class to Quaternion, remove existing Quaternion
* add Copyright line for Mathieu
* cast() was broken (compile errors) and needed anyway to be in QuaternionBase
* it's VectorBlock<T,3>, don't pass additional parameter 1, it has different meaning!!
* make it compile with GCC (put 'typename' at the right location)
2009-10-27 15:45:24 -04:00
Mathieu Gautier
611d2b0b1d Quaternion could now map an array of 4 scalars :
new classes :
* QuaternionBase
* Map<Quaternion>
2009-10-27 13:19:16 +00:00
Hauke Heibel
427f8a87d1 Added dox for the new typedefs. 2009-10-27 16:02:36 +01:00
Hauke Heibel
dbaba9019b Added more common typedefs. 2009-10-27 15:57:21 +01:00
Hauke Heibel
7cc9fb5d0a Umeyama is now working with fixed size src and dst points. 2009-10-27 15:29:12 +01:00
Benoit Jacob
1f1c04cac1 sync the documentation examples 2009-10-26 14:37:43 -04:00
Benoit Jacob
44cdbaba4d * make inverse() do a ReturnByValue
* add computeInverseWithCheck
* doc improvements
* update test
2009-10-26 14:16:50 -04:00
Benoit Jacob
07d1bcffda remove 1 useless layer of functions 2009-10-26 12:30:29 -04:00
Benoit Jacob
ec02388a5d big rewrite in Inverse.h
in particular, the API is essentially finalized and the 4x4 case is fixed to be numerically stable.
2009-10-26 11:18:23 -04:00
Hauke Heibel
66fe5a5f36 It is just not that easy and requires more work to get it done right. 2009-10-24 14:48:34 +02:00
Gael Guennebaud
a382963b04 * extend Map to allow the user to specify whether the mapped data
is aligned or not. This is done using the Aligned constant:
  Map<MatrixType,Aligned>::Map(data);
* rename ForceAligned to EnforceAlignedAccess, and update its doc,
  and emphasize this is mainly an internal stuff.
2009-10-23 14:26:14 +02:00
Mark Borgerding
0167f5ef43 added inline to many functions 2009-10-22 23:06:19 -04:00
Benoit Jacob
83a7b7c44c support gcc 3.3 2009-10-22 15:56:10 -04:00
Hauke Heibel
99bb29abcf demeaning with colwise expression 2009-10-22 10:11:26 +02:00
Mark Borgerding
e3d08443dc inlining,all namespace declaration moved to FFT, removed preprocessor definitions, 2009-10-21 20:53:05 -04:00
Benoit Jacob
68d48511b2 move PartialLU to the new API 2009-10-21 17:06:42 -04:00
Mark Borgerding
78a53574b7 merge branches 2009-10-21 10:28:56 -04:00
Mark Borgerding
85f8d1f0c6 renamed 'Traits' to 'Impl', added vim modelines for syntax highlighting 2009-10-21 10:27:17 -04:00
Benoit Jacob
c3180b7ffb MatrixBase:
* support resize() to same size (nop). The case of FFT was another case where that make one's life far easier.
   hope that's ok with you Gael. but indeed, i don't use it in the ReturnByValue stuff.

FFT:
 * Support MatrixBase (well, in the case with direct memory access such as Map)
 * adapt unit test
2009-10-20 23:25:49 -04:00
Benoit Jacob
471b4d5092 handle mark's first commits before he configured his id 2009-10-20 21:53:54 -04:00
Mark Borgerding
902b6dcd6c added Eigen::FFT and
Eigen::Complex
2009-10-20 21:33:48 -04:00
Hauke Heibel
5e3e6ff71a Added Windows support to the BenchTimer. 2009-10-20 22:08:13 +02:00
Mark Borgerding
d9b418bf12 merged eigen2_for_fft into eigen2 mainline 2009-10-20 15:18:01 -04:00
Benoit Jacob
13f31b8daf * make PartialLU avoid to generate inf/nan when given a singular matrix
(result undefined, but at least it won't take forever on intel 387)
* add lots of comments, especially to LU.h
* fix stuff I had broken in Inverse.h
* split inverse test
2009-10-20 00:36:07 -04:00
Benoit Jacob
d1db1352f5 update doc snippets 2009-10-19 17:22:04 -04:00
Benoit Jacob
890bff977e * proper check for Make
* fix documentation of ei_add_test
2009-10-19 15:56:03 -04:00
Benoit Jacob
6c1b91678b kill ei_add_test_multi. Now the macro ei_add_test does all that automatically, by parsing the source file. No risk anymore to specify the wrong number of tests! Also, introduce CALL_SUBTESTX for X=1..10 that allows to port existing code much quicker. And port already the product* and eigensolver* files. 2009-10-19 14:40:35 -04:00
Benoit Jacob
580672ea43 Add new default option EIGEN_SPLIT_LARGE_TESTS and cmake macro ei_add_test_multi.
When enabled, large tests are split into smaller executables.
This needs minimal changes in the unit tests.
Updated the LU test to use it.
2009-10-19 13:29:00 -04:00
Benoit Jacob
9a700c2974 * LU unit test: finally test fixed sizes
* ReturnByValue: after all don't eval to temporary for generic MatrixBase impl
2009-10-19 10:56:37 -04:00
Benoit Jacob
47eeb40380 remove the m_originalMatrix member. Instead, image() now takes the original matrix as parameter. It was the only method to use it anyway. Introduce m_isInitialized. 2009-10-18 15:21:19 -04:00
Benoit Jacob
d71c7f42d3 * useThreshold -> setThreshold
* remove defaultThreshold()
2009-10-18 14:20:14 -04:00
Benoit Jacob
0255f28279 oops, didn't want to commit that 2009-10-18 01:35:07 -04:00
Benoit Jacob
8332c232db big huge changes in LU!
* continue the decomposition until a pivot is exactly zero;
  don't try to compute the rank in the decomposition itself.
* Instead, methods such as rank() use a new internal parameter
  called 'threshold' to determine which pivots are to be
  considered nonzero.
* The threshold is by default determined by defaultThreshold()
  but the user can override that by calling useThreshold(value).
* In solve/kernel/image, don't assume that the diagonal of U
  is sorted in decreasing order, because that's only approximately
  true. Additional work was needed to extract the right pivots.
2009-10-18 00:47:40 -04:00
Gael Guennebaud
7b0c4102fa * add a Make* expression type builder to allow the
construction of generic expressions working
  for both dense and sparse matrix. A nicer solution
  would be to use CwiseBinaryOp for any kind of matrix.
  To this end we either need to change the overall design
  so that the base class(es) depends on the kind of matrix,
  or we could add a template parameter to each expression
  type (e.g., int Kind = ei_traits<MatrixType>::Kind)
  allowing to specialize each expression for each kind of matrix.
* Extend AutoDiffScalar to work with sparse vector expression
  for the derivatives.
2009-10-16 13:22:38 +02:00
Gael Guennebaud
44ba4b1d6d add operator+ scalar to AutoDiffScalar 2009-10-16 11:27:04 +02:00
Benoit Jacob
3c4a025a54 merge 2009-10-15 16:09:43 -04:00
Benoit Jacob
41e942d3fb don't try to finish early 2009-10-15 16:09:17 -04:00
Hauke Heibel
d177c1f3ac Inlining fixes + fixed typo.
Removed ei_assert in presence of static assert.
2009-10-15 21:07:14 +02:00
Gael Guennebaud
1503043981 autodiff:
* fix namespace issue
* simplify Jacobian code
* fix issue with "Dynamic derivatives"
2009-10-15 18:43:15 +02:00
Hauke Heibel
0927ba1fd3 More warning fixes. 2009-10-14 19:55:23 +02:00
Hauke Heibel
c37cfc32b3 Fixed more W4 warnings. 2009-10-14 11:08:00 +02:00
Hauke Heibel
f4661e696e Resize is only defined in Matrix and not in MatrixBase.
I am not sure whether the better fix is to move the resize functions to MatrixBase.
2009-10-14 11:07:11 +02:00
Hauke Heibel
949582c809 Added prod() reduction to the AsciiQuickReference. 2009-10-14 09:40:22 +02:00
Gael Guennebaud
8c37b1b5b7 add missing PartialReduxExpr::coeff(index) function 2009-10-13 14:41:57 +02:00
Gael Guennebaud
1443094072 compilation fix: make the generic template ctor explicit 2009-10-13 09:23:09 +02:00
Gael Guennebaud
2049f742e4 trivial compilation fix 2009-10-13 08:53:01 +02:00
Benoit Jacob
c4ab6a2032 also test that the matrix Q is unitary 2009-10-12 22:33:51 -04:00
Thomas Capricelli
456f7d094d merge with eigen-tip 2009-10-13 01:14:19 +02:00
Hauke Heibel
e5bf72679c Fixed nmake parameter.
Disabled debug_* targets for MSVC_IDE (they already exist).
Removed the make usage message for MSVC_IDE.
2009-10-09 14:09:25 +02:00
Gael Guennebaud
81a70cef5c merge 2009-10-07 14:26:42 +02:00
Gael Guennebaud
8f3e33581e extend the sparse matrix assembly benchmark 2009-10-07 14:25:53 +02:00
Gael Guennebaud
af31345df3 really fix stable norm compilation for older gcc 2009-10-07 14:25:12 +02:00
Gael Guennebaud
075830ddb0 - remove the debug_test_* targets from "all"
(otherwise they are compiled when you simply run
   make in test/ or when enforcing "test" to be part of "all")
- add linking libraries to the debug_test_* targets
2009-10-07 14:22:44 +02:00
Benoit Jacob
9115d33fae the answer to the ultimate question in life is: 664 2009-10-06 11:44:57 -04:00
Benoit Jacob
24e1d3266a merge 2009-10-06 09:27:01 -04:00
Benoit Jacob
80ede36b24 allow arbitrary resulttype, fixes Xuewen's issue, and this stuff is going to get deeply refactored soon anyway. 2009-10-06 09:26:28 -04:00
Gael Guennebaud
4cf7366027 fix compilation in stable norm, move a platform check to the unit tests 2009-10-06 10:24:41 +02:00
Gael Guennebaud
904f35d194 discard vectorization in matrix-vector product when data is not even
aligned on the scalar type size (e.g., for double on 32 bits system without -malign-double)
2009-10-05 17:22:16 +02:00
Benoit Jacob
bb1cc0d092 after all we're not aligning to 8byte boundary
keep most of the changes though as they make the code more extensible
2009-10-05 10:55:42 -04:00
Benoit Jacob
f01a8112d6 merge 2009-10-05 10:11:50 -04:00
Benoit Jacob
d41577819b we were already aligning to 16 byte boundary fixed-size objects that are multiple of 16 bytes;
now we also align to 8byte boundary fixed-size objects that are multiple of 8 bytes.
That's only useful for now for double, not e.g. for Vector2f, but that didn't seem to hurt. Am I missing something? Do you prefer that we don't align Vector2f at all?
Also, improvements in test_unalignedassert.
2009-10-05 10:11:11 -04:00
Hauke Heibel
a7d51435e1 added cygwin specific stuff 2009-10-05 14:00:32 +02:00
Benoit Jacob
a9a9ba8453 remove unneeded stuff 2009-10-05 07:58:53 -04:00
Benoit Jacob
fa9fc1397b next attempt ... introduce EIGEN_CMAKE_RUN_FROM_CTEST, in that case don't EXCLUDE_FROM_ALL 2009-10-05 07:42:31 -04:00
Benoit Jacob
b78b2ede5f finally, the right fix: set CTEST_BUILD_TARGET.
So this is the come-back of btest target, and the default target is empty again.
2009-10-04 20:27:44 -04:00
Benoit Jacob
7956fc49a0 dd first-time tip, to warn against doing "make".
now i think we're reasonably safe.
2009-10-03 22:11:30 -04:00
Thomas Capricelli
5f32088443 use provided $USER if available, let the caller do the update (safer) 2009-10-04 03:35:02 +02:00
Benoit Jacob
d040c9fc9e add INSTALL and message about no need to do "make" 2009-10-03 17:19:14 -04:00
Benoit Jacob
a1d9b76dd5 add debug targets like debug_qr to build a specific test with debug info
remove the btest target, instead just do "make" since anyway we have to let "make" build the tests
2009-10-03 16:50:50 -04:00
Benoit Jacob
3e4cb08054 fix #59, can't EXCLUDE_FROM_ALL the test directory 2009-10-03 15:51:42 -04:00
Hauke Heibel
7d2ca0e05e Added cmake project definitions. 2009-10-02 18:45:24 +02:00
Benoit Jacob
71f19d90d0 forgot to hg add this file 2009-10-02 12:40:19 -04:00
Benoit Jacob
57e1c5b0aa fix permissions 666->660 2009-10-02 11:32:36 -04:00
Benoit Jacob
2b810ea818 finally, actually purge the Main Page 2009-10-02 11:22:47 -04:00
Gael Guennebaud
bcdeb68b63 merge 2009-10-01 13:28:22 +02:00
Gael Guennebaud
9a3cae4655 better fix for (v * v') * v, we still have to find a way to reorder it 2009-10-01 13:27:03 +02:00
Benoit Jacob
3529179376 merge 2009-10-01 07:26:47 -04:00
Hauke Heibel
5409ce1625 Fixed wrong line endings. 2009-10-01 07:20:09 +02:00
Benoit Jacob
3a315fdc9a make Replicate ctor require the exact expected type 2009-09-30 15:47:11 -04:00
Gael Guennebaud
d7a2a37a4c bugfix in the eigenvalue solvers (forgot to resize the eigen vectors) 2009-09-30 16:48:02 +02:00
Benoit Jacob
4b04a9bcfa *add test to prevent future regression 2009-09-29 21:00:13 -04:00
Benoit Jacob
fa65b09661 add outerproduct coeff(int,int) method.
This is needed to make this expression work:
(vec1*vec2.transpose())*vec3
Gael, no objection? Seems to make sense as that's fast.
2009-09-29 20:30:28 -04:00
Thomas Capricelli
977ed615a6 be sure that there's no name clash between NumericalDiff::df and the
original functor df()
2009-09-28 17:45:45 +02:00
Benoit Jacob
457b7cba96 more message improvements, tell the user about building a specific test 2009-09-28 11:08:31 -04:00
Benoit Jacob
eeabd18afc Fix compilation of HouseholderQR and ColPivotingHouseholderQR for non-square fixed-size matrices.
For Colpiv that was just changing MatrixQType to MatrixType in the instantiation of HouseholderSequence.
For HouseholderQR I also re-ported the solve method from Colpiv as there were multiple issues.
2009-09-28 10:49:55 -04:00
Benoit Jacob
67bf7c90c5 * update test to expose bug #57
* update createRandomMatrixOfRank to support fixed size
2009-09-28 09:40:18 -04:00
Thomas Capricelli
7968737247 fix tests : we perform slightly worse because we do use one more function
evaluation in our numericaldiff than what (c)minpack did
2009-09-28 04:13:57 +02:00
Thomas Capricelli
d912034565 fdjac2 is not needed anymore 2009-09-28 03:49:23 +02:00
Thomas Capricelli
d3850641a1 remove some duplicated code LevenbergMarquardt::minimizeNumericalDiff*() by
using the generic Eigen NumericalDiff recently introduced.

LevenbergMarquardt::lmdif1(), which is provided as a convenience method for
people porting code from (c)minpack, is now a static function
2009-09-28 03:26:42 +02:00
Thomas Capricelli
87be19de4a central sheme for numerical diff 2009-09-28 02:55:30 +02:00
Thomas Capricelli
206b5e3972 starting work on a Numerical differenciation module 2009-09-28 02:43:07 +02:00
Thomas Capricelli
a453298322 cleaning doc 2009-09-28 02:42:19 +02:00
Thomas Capricelli
52026eb800 cleaning 2009-09-28 02:35:42 +02:00
Thomas Capricelli
de942a44c2 default argument for _jac in functor operator() : this way, we can use
AutoDiffJacobian::operator()(x,value) exactly as the original functor
2009-09-28 01:28:48 +02:00
Thomas Capricelli
8e8997d403 use dynamic type in functor, as NonLinear only knows about this currently 2009-09-28 01:19:29 +02:00
Thomas Capricelli
bee14ee8e6 use operator() so that to be coherent with eigen AutoDiff functor 2009-09-28 00:32:31 +02:00
Thomas Capricelli
956d65ea63 define a generic functor and makes other ones inherit it 2009-09-28 00:18:14 +02:00
Benoit Jacob
765600458b * bump to 2.90.0 now that it's agreed that we're doing eigen3
---> question: do we change the prefix eigen2/ to eigen3/ now?
       no, better wait until we've also changed the repository name
* more message improvements: "Install Eigen" was unclear as it left
  out other things like the BLAS library
2009-09-27 18:05:54 -04:00
Benoit Jacob
2e4be5a75c improve message 2009-09-27 17:55:58 -04:00
Thomas Capricelli
251c0f45ac remove references to adolc and split tests functions for clarity 2009-09-27 23:54:06 +02:00
Benoit Jacob
92480ffd26 * Introduce make targets btest (build tests), blas (build blas lib), demos (build demos).
* remove EIGEN_BUILD_TESTS and siblings
* add summary at the end of cmake run, hopefully not too verbose
* fix build of quaternion demo
* kill remnants of old binary library option
2009-09-27 17:48:53 -04:00
Benoit Jacob
6b23cb2101 remove the hack we made to allow api.kde.org to generate the dox. Update the error help page. 2009-09-27 11:39:51 -04:00
Hauke Heibel
e115fa3cea Ok, too many class bodies - it was only required for ei_svd_precondition_2x2_block_to_be_real. 2009-09-27 17:18:19 +02:00
Hauke Heibel
3c74d6b7d4 Added private, non-implemented assignment operators to functions that don't need them (fixes VC warning on /W4). 2009-09-27 17:03:02 +02:00
Hauke Heibel
13545eab9b Fixed VC compilation error on the JacobiSVD module. 2009-09-27 17:00:10 +02:00
Benoit Jacob
924b55e9a9 when copying a ReturnByValue into a MatrixBase, first eval it to a PlainMatrixType.
This allows to limit the number of instantiations of the big template method evalTo.
Also allows to get rid of the dummy MatrixBase::resize().
See "TODO" comment.
2009-09-26 22:48:16 -04:00
Thomas Capricelli
b1637df4f4 update URL for adol-c 2009-09-27 01:56:50 +02:00
Benoit Jacob
e82ab8a5dd move also inverse() to ReturnByValue, by doing a solve on NestByValue<Identity>.
also: adding resize() to MatrixBase was really needed ;)
2009-09-26 11:40:29 -04:00
Gael Guennebaud
c532f42a0e update the sparse tutorial wrt not so recent changes about the filling API 2009-09-25 16:30:44 +02:00
Hauke Heibel
104f9954e1 Removed implicit type conversion (VC warning fix). 2009-09-25 14:58:20 +02:00
Hauke Heibel
21d2533723 Matrix::conservativeResize, resize only when necessary. 2009-09-25 14:44:48 +02:00
Gael Guennebaud
04dc63776a add a wip blas library built on top of Eigen. TODO:
- write extentive unit tests (maybe this already exist in other projects)
- the level2 functions still have to be implemented
2009-09-25 13:08:39 +02:00
Gael Guennebaud
bdf603caec remove some dirty lines 2009-09-25 12:58:41 +02:00
Gael Guennebaud
e12bd2e8d2 extend the support for bool 2009-09-25 12:58:04 +02:00
Hauke Heibel
3d6e4ab879 Uuups that was not yet intended for a commit. 2009-09-25 10:14:16 +02:00
Hauke Heibel
2fbf5ce7df Fixed issue #57. 2009-09-25 10:12:09 +02:00
Benoit Jacob
e58e9c842e remove (changesets), it's enough numbers like this 2009-09-24 15:14:45 -04:00
Benoit Jacob
ddfd23a13e * sort by last name alphabetically
* replace (no own changesets) by (no information)
2009-09-24 13:56:33 -04:00
Thomas Capricelli
68988e4ad0 use -f so that the script is happy even if the log file is not there 2009-09-24 13:26:23 +02:00
Benoit Jacob
905b3b9379 oops, don't append, overwrite 2009-09-24 07:18:31 -04:00
Benoit Jacob
64648b4b35 improvements, especially: automatically flush the server side cache 2009-09-24 07:04:55 -04:00
Benoit Jacob
a279a277e3 fix typo 2009-09-23 21:01:14 -04:00
Benoit Jacob
51db7ab0df add eigen_gen_credits script 2009-09-23 20:58:20 -04:00
Hauke Heibel
b347075936 Removed unnecessary MSVC check. 2009-09-22 10:03:40 +02:00
Benoit Jacob
176c26feb5 allow to do xpr = solve(b) etc... just by adding a dummy MatrixBase::resize() 2009-09-22 01:41:09 -04:00
Benoit Jacob
4f9e270343 * make LU::kernel() and LU::image() also use ReturnByValue
* make them return zero vector in the degenerate case, instead of asserting
  (let's stick to the principle that we only assert on memory errors)
2009-09-22 00:16:51 -04:00
Benoit Jacob
0ad3494bd3 fix docs 2009-09-22 21:51:23 -04:00
Benoit Jacob
ab5cc8284a convert LU::solve() to the new API 2009-09-22 20:58:29 -04:00
Benoit Jacob
c1c780a94f * ReturnByValue:
-- simpplify by removing the 2nd template parameter
  -- rename Functor to Derived, as now it's a usual CRTP
* Homogeneous:
  -- in products, honor the Max sizes etc.
2009-09-22 12:20:45 -04:00
Hauke Heibel
c6822d6723 Added EIGEN_REF_TO_TEMPORARY define for rvalue support.
Allowed VC10 to make use of static_assert.
2009-09-21 19:59:58 +02:00
Benoit Jacob
1df54e3ac2 fix bug #42, add missing Transform::Identity() 2009-09-19 19:59:49 -04:00
Benoit Jacob
828a79ac78 allow to override EIGEN_RESTRICT, to satisfy a smart ass blogger who claims
that eigen2 owes all its performance to nonstandard restrict keyword.
well, this can also improve portability in case some compiler doesn't have __restrict.
2009-09-19 19:45:58 -04:00
Benoit Jacob
3c780fd472 add legalese 2009-09-20 06:00:39 -04:00
Benoit Jacob
bd491a89c5 add demo of how to mix eigen with C code 2009-09-20 05:49:17 -04:00
Gael Guennebaud
0b60027f3c implement __gnuc_forget_about_setZero_its_over_now 2009-09-18 15:36:05 +02:00
Benoit Jacob
6b5f96cb03 undef B0 2009-09-19 19:14:28 -04:00
Gael Guennebaud
3b5a9acba8 fix stable_norm unit test 2009-09-18 11:41:38 +02:00
Benoit Jacob
0b426ea00d update page to explain how to get rid of it 2009-09-18 22:01:49 -04:00
Gael Guennebaud
add5381be7 finish my evalToDense => evalTo change 2009-09-17 23:51:16 +02:00
Gael Guennebaud
5ba7fe3bee clean the commented asm instructions because now I'm sure
the previous fix is ok
2009-09-17 23:34:00 +02:00
Gael Guennebaud
f2737148b0 merge 2009-09-17 23:21:48 +02:00
Benoit Jacob
760636a237 fix bug #52: Transform::inverse() should return a Transform 2009-09-18 18:45:45 -04:00
Gael Guennebaud
9395326e44 fix #53: performance regression, hopefully I did not resurected another
perf. issue...
2009-09-17 23:18:21 +02:00
Gael Guennebaud
fcae32cc3f compilation fixes 2009-09-17 15:11:13 +02:00
Gael Guennebaud
24950bdfcb make ColPivotingQR use HouseholderSequence 2009-09-16 15:56:20 +02:00
Gael Guennebaud
49dd5d7847 * add a HouseholderSequence class (not good enough yet for Triadiagonalization and HessenbergDecomposition)
* rework a bit AnyMatrixBase, and mobe it to a separate file
2009-09-16 14:35:42 +02:00
Gael Guennebaud
77f858f6ab improve ComplexShur api and doc 2009-09-16 14:34:08 +02:00
Benoit Jacob
a4fd0aa25b * fix bug in col-pivoting qr, forgot to swap the colNorms when swapping cols
* add Gael a copyright line
2009-09-16 14:19:59 -04:00
Benoit Jacob
46be9c9ac1 * fix super nasty bug: vector.maxCoeff(&index) didn't work when 'vector'
was a row-vector. Fixed by splitting the vector version from the matrix version.
* add unit test, the visitors weren't covered by any test!!
2009-09-16 14:18:30 -04:00
Gael Guennebaud
4a6e5694d6 disable warning 279: controlling expression is constant for ICC 2009-09-15 13:03:24 +02:00
Gael Guennebaud
9e9abab2b9 bugfixes for ICC (compilation and runtime) 2009-09-15 11:53:24 +02:00
Gael Guennebaud
432fcefcb1 fix warning with gcc 4.2 2009-09-15 11:27:31 +02:00
Gael Guennebaud
d5319f4ba8 fix warning in stable norm 2009-09-15 11:16:58 +02:00
Thomas Capricelli
7a8ec4ba26 cleaning 2009-09-15 04:17:11 +02:00
Thomas Capricelli
6d8baa757e fix indentation (and only that) 2009-09-14 23:47:44 +02:00
Mark Borgerding
a39de276a9 added the test case for FFTW 2009-09-14 01:52:26 -04:00
Thomas Capricelli
ab88ba6f7f provide some default values for important results. So that we can read them
even before *Init() and do no get random values.
2009-09-13 23:55:08 +02:00
Thomas Capricelli
8c3f7d8e94 cleaning 2009-09-13 01:44:34 +02:00
Thomas Capricelli
8b84c3733a functors need not be const 2009-09-11 20:50:01 +02:00
Jitse Niesen
9f14d72927 Remove no-op statement in AlignedVector3. 2009-09-10 09:22:06 +01:00
Thomas Capricelli
72746838ad merge with tip 2009-09-10 02:37:08 +02:00
Jitse Niesen
2a6db40f10 Re-factor matrix exponential.
Put all routines in a class. I think this is a cleaner design.
2009-09-08 14:51:34 +01:00
Jitse Niesen
220ff54131 Fix LaTeX error in doxygen comment. 2009-09-08 14:41:54 +01:00
Hauke Heibel
26ed19e4cf Fixed if clause. 2009-09-08 10:20:26 +02:00
Hauke Heibel
3a2499fb11 Fixed conservative_resize compilation errors. 2009-09-08 10:02:19 +02:00
Hauke Heibel
e6cac85333 Added missing casts. 2009-09-08 08:27:18 +02:00
Hauke Heibel
437a79e1ab Fixed unit test and improved code reusage for resizing. 2009-09-07 17:48:42 +02:00
Hauke Heibel
e49236bac6 Ups - that was not intended to be part of the commit. 2009-09-07 17:23:29 +02:00
Hauke Heibel
64095b6610 Changed the AnyMatrixBase / ei_special_scalar_op inheritance order as proposed by Gael.
Added conservativeResizeLike as discussed on the mailing list.
2009-09-07 17:22:01 +02:00
Gael Guennebaud
8f4bf4ed7f add optional compile flags to enable coverage testing 2009-09-07 14:05:27 +02:00
Gael Guennebaud
ae1d1c8f6c improve coverage of matrix-vector product 2009-09-07 14:04:56 +02:00
Gael Guennebaud
fb5f546161 improve coverage of unitOrthogonal 2009-09-07 12:53:25 +02:00
Gael Guennebaud
b56bb441dd add a stable_norm unit test 2009-09-07 12:46:16 +02:00
Gael Guennebaud
bdcc0bc157 fix compilation of swap for ICC 2009-09-07 11:37:41 +02:00
Gael Guennebaud
a921292381 uncomment stuff commented for debugging (sorry for the noise) 2009-09-07 11:26:20 +02:00
Gael Guennebaud
225ec02b06 fix another .stride() issue in Cholmod support 2009-09-07 11:15:38 +02:00
Gael Guennebaud
61fe2b6a56 bug fix in SuperLU support: the meaning of Matrix::stride() changed for vectors 2009-09-07 10:55:33 +02:00
Jitse Niesen
5eea8f1824 Typos in tutorial 1. 2009-09-05 19:46:33 +01:00
Gael Guennebaud
e4f94b8c58 enable ILU in super LU only if the super version supports it 2009-09-04 18:19:34 +02:00
Thomas Capricelli
e3db42611b fix warning about unused variable 2009-08-29 02:48:44 +02:00
Thomas Capricelli
982a146a67 merge with tip 2009-08-29 02:47:12 +02:00
Thomas Capricelli
c990938415 eigenization of fcn_chkder + bugfix 2009-08-29 02:46:19 +02:00
Thomas Capricelli
c1265ebbfe fix bounds using c standard instead of fortran's 2009-08-29 02:36:13 +02:00
Thomas Capricelli
4f7daf942c fix indentation for fcn_chkder 2009-08-29 02:30:18 +02:00
John Smith
aacada1662 Force release builds on Windows machines in the test suite.
Added an IGNORE_CVS flag to the test suite (allows submitting local and modified repositories).
Fixed the EI_OFLAG for MSVC.
2009-08-28 20:14:18 +02:00
John Smith
227f6cbce0 Fixed SSE related build warning on 64-bit windows systems. 2009-08-28 00:05:44 +02:00
Jitse Niesen
76fa46c6db Typos in tutorial 2009-08-26 18:53:56 +01:00
Thomas Capricelli
16d08b2b0f check number of evaluation even in the case of *1(), now we have it.. 2009-08-26 14:47:10 +02:00
Thomas Capricelli
458947af5e move Parameters as a class member, simplify calling sequence. Convenience
methods from minpack ( "*1()" ) get their original name back : they are
only useful when porting, anyway. Still, i prefer to keep them.
2009-08-26 14:23:05 +02:00
Thomas Capricelli
c1be96967e remove printfs, they are of no use and may prevent compilation 2009-08-26 01:09:23 +02:00
Gael Guennebaud
3705498721 add coeff(int,int), coeff(int) and value() functions to the inner product specialization 2009-08-26 00:24:22 +02:00
Thomas Capricelli
a1e9e8d082 merge with tip 2009-08-25 23:49:48 +02:00
Thomas Capricelli
6de3f5f0e7 cleaning 2009-08-25 23:47:22 +02:00
Thomas Capricelli
eac9293449 split every algorithm in *Init() + while(running) { *OneStep() } 2009-08-25 23:43:33 +02:00
Thomas Capricelli
bbd44ef0ad move more stuff into Parameters 2009-08-25 23:37:27 +02:00
Thomas Capricelli
a2abb4afb6 cleaning 2009-08-25 23:26:36 +02:00
Thomas Capricelli
baec4f39ab reduce local variables so that we can split algorithms 2009-08-25 22:49:05 +02:00
Thomas Capricelli
be368c33bb cleaning 2009-08-25 22:15:09 +02:00
Thomas Capricelli
470ea55834 put nfev/njev as internal variables as well 2009-08-25 22:13:08 +02:00
Thomas Capricelli
41b6ea81db oops... fixing return values, some copy/paste was done far too quickly 2009-08-25 22:06:58 +02:00
Thomas Capricelli
3bca4bba87 if mode==2, the user is supposed to supply diag: do some basic check. 2009-08-25 22:02:19 +02:00
Thomas Capricelli
fa0183e7c7 make diag be an internal variable too 2009-08-25 21:59:10 +02:00
Thomas Capricelli
e465ea82e1 define and use struct Parameters 2009-08-25 21:50:01 +02:00
Thomas Capricelli
d13bcdc891 those are actually bools 2009-08-25 20:01:30 +02:00
Thomas Capricelli
84f2c451e5 cleaning 2009-08-25 19:57:42 +02:00
Thomas Capricelli
d38d4709bc use an enum for status reporting 2009-08-25 19:48:53 +02:00
Thomas Capricelli
d0a5da95b1 fix installation for recently added files 2009-08-25 18:57:59 +02:00
Thomas Capricelli
d59cc0ad82 merge files 2009-08-25 17:25:56 +02:00
Thomas Capricelli
493c72ac38 rename files 2009-08-25 17:21:16 +02:00
Thomas Capricelli
858acfcc64 remove the boring, old-school nprint option, we'll have a dedicated
method for 'one iteration' anyway.
2009-08-25 17:11:14 +02:00
Thomas Capricelli
613a464320 cleaning 2009-08-25 16:48:09 +02:00
Thomas Capricelli
6c1a9703b1 move most of results vectors/matrices inside respective classes. 2009-08-25 16:08:09 +02:00
Thomas Capricelli
38fc6c8553 cleaning 2009-08-25 14:28:19 +02:00
Thomas Capricelli
201f58e528 merge both c methods lmstr/lmstr1 into one class
LevenbergMarquardtOptimumStorage with two methods.
2009-08-25 14:18:38 +02:00
Thomas Capricelli
3f1b81e129 merge both c methods lmdif/lmdif1 into one class
LevenbergMarquardtNumericalDiff with two methods.
2009-08-25 14:09:19 +02:00
Thomas Capricelli
a736378331 cleaning 2009-08-25 14:03:30 +02:00
Thomas Capricelli
d880e6f774 merge both c methods hybrj1/hybrj into one class HybridNonLinearSolver with
two methods. hybrd stuff renamed to HybridNonLinearSolverNumericalDiff.
2009-08-25 13:56:25 +02:00
Thomas Capricelli
a043708e87 merge both c methods hybrd/hybrd1 into one class HybridNonLinearSolver with
two methods.
2009-08-25 13:48:25 +02:00
Thomas Capricelli
602b13815f merge both c methods lmder/lmder1 into one class LevenbergMarquardt with
two methods.
2009-08-25 13:40:45 +02:00
Thomas Capricelli
86cb9364c9 clean fortran stuff in fdjac* 2009-08-24 21:53:08 +02:00
Thomas Capricelli
45442b8d41 some more work on Functors 2009-08-24 21:48:22 +02:00
Benoit Jacob
191d5275a7 modernize HouseholderQR too, uniformize all that stuff, update tests 2009-08-24 13:46:14 -04:00
Thomas Capricelli
15d2c3af90 playing with functors 2009-08-24 19:45:35 +02:00
Thomas Capricelli
6f567f10be cleaning 2009-08-24 19:19:30 +02:00
Jitse Niesen
7e4bd70157 Fix comment which may cause latex to hang when generating docs 2009-08-24 18:01:18 +01:00
Gael Guennebaud
078a870a87 fix issue #43 2009-08-24 18:56:27 +02:00
Thomas Capricelli
4e62e29869 cleaning covar 2009-08-24 17:49:37 +02:00
Thomas Capricelli
17905c7399 eigenization of ei_covar() 2009-08-24 17:47:35 +02:00
Benoit Jacob
0eb142f559 bring the modern comfort also to ColPivotingHouseholderQR
+ some fixes in FullPivotingHouseholderQR
2009-08-24 11:11:41 -04:00
Benoit Jacob
3288e5157a finally, the correct way of dealing with zero matrices in solve() 2009-08-24 10:51:07 -04:00
Thomas Capricelli
f69869c42a covar : cleaning, removing goto's 2009-08-24 16:49:38 +02:00
Thomas Capricelli
312ab1abb3 further cleaning/ goto removing 2009-08-24 16:39:49 +02:00
Thomas Capricelli
92a5bb4539 clean debug stuff 2009-08-24 16:14:42 +02:00
Thomas Capricelli
c6d7da6edc cleaning some more 2009-08-24 16:08:13 +02:00
Thomas Capricelli
63071ac968 cleaning, removing goto's, uniformization (try to reduce diff between
hybr[dj].h  or lm[der,dif,str].h as much as possible), for future merging.
2009-08-24 16:05:57 +02:00
Benoit Jacob
b8106e97b4 add logAbsDeterminant()
move log and exp functors from Array to Core
update documentation
2009-08-24 09:46:17 -04:00
Thomas Capricelli
91a2145cb3 clean, remove goto's 2009-08-24 15:32:06 +02:00
Thomas Capricelli
d4968cd059 cleaning, fixing most goto's 2009-08-24 15:13:12 +02:00
Thomas Capricelli
e65a7c7c70 misc cleaning 2009-08-24 09:28:29 +02:00
Thomas Capricelli
6e41f15fea use a local variable for qrfac 2009-08-24 09:13:06 +02:00
Thomas Capricelli
dff5135026 merge with head 2009-08-24 08:55:27 +02:00
Thomas Capricelli
88f5d06b08 move ipvt/fortran fixing deeper 2009-08-24 08:45:06 +02:00
Thomas Capricelli
950eb4a254 various cleaning and homogeneization 2009-08-24 08:28:31 +02:00
Benoit Jacob
f31b5a7114 add test for absDeterminant() 2009-08-24 00:35:42 -04:00
Benoit Jacob
c9a307f330 give FullPivotingHouseholderQR all the modern comfort 2009-08-24 00:23:35 -04:00
Benoit Jacob
154bdac9f4 small improvements 2009-08-24 00:09:01 -04:00
Benoit Jacob
b37ab9b324 clarifications in LU::solve() and in LU documentation 2009-08-24 00:02:49 -04:00
Benoit Jacob
0926549659 fix bug: with complex matrices, the condition (ei_imag(c0)==RealScalar(0)) being wrong could bypass the other condition in the &&.
at least that's my explanation why the test_lu was often failing on complex matrices (it uses that via createRandomMatrixOfRank)
and why that's fixed by this diff.
also gcc 4.4 gave a warning about tailSqNorm potentially uninitialized
2009-08-24 00:02:22 -04:00
Benoit Jacob
d38624b1ad merge 2009-08-23 18:05:33 -04:00
Benoit Jacob
97bc1af1f1 add ColPivotingHouseholderQR
rename RRQR to fullPivotingHouseholderQR
2009-08-23 18:04:33 -04:00
Gael Guennebaud
47fda1f3b2 hm, forgot to conjugate the arguments in applyJacobiOnTheLeft 2009-08-24 00:01:02 +02:00
Gael Guennebaud
e86dbd5255 fix apply Jacobi for complexes and add documentation for some *Jacobi* functions 2009-08-23 23:49:44 +02:00
Benoit Jacob
a848ed02ad let createRandomMatrixOfRank support fixed-size! 2009-08-23 17:33:31 -04:00
Thomas Capricelli
930651ff9a dogleg, lmpar : use more eigen features 2009-08-23 21:52:39 +02:00
Thomas Capricelli
4958c53bfb trivial fixes 2009-08-23 21:47:55 +02:00
Thomas Capricelli
5e8dee7a19 eigenize dogleg() 2009-08-23 21:39:47 +02:00
Thomas Capricelli
f793dbe45c only indentation fixes (this eases porting) 2009-08-23 21:06:57 +02:00
Thomas Capricelli
feb5af3ede porting lmpar() to eigen : both api and some of the code 2009-08-23 21:04:55 +02:00
Thomas Capricelli
9a8c5cbd2c misc cleaning 2009-08-23 06:16:05 +02:00
Thomas Capricelli
264e61932c cleaning fdjac*() 2009-08-23 06:04:06 +02:00
Thomas Capricelli
f01332043b only indentation 2009-08-23 05:56:12 +02:00
Thomas Capricelli
8b9b671e83 some eigenization in main algorithms 2009-08-23 05:55:43 +02:00
Thomas Capricelli
134dea76d3 beautify functors for lmdif, lmstr, hybrj, hybrd 2009-08-23 04:57:48 +02:00
Thomas Capricelli
acd757737a beautify Functor for lmder : we now have f,df,debug methods 2009-08-23 04:39:22 +02:00
Thomas Capricelli
878f15b8a5 * use eigen object for callbacks for hybrd and lmdif
* use Functor instead of argument for ei_fdjac*()
2009-08-23 04:06:16 +02:00
Thomas Capricelli
f2fcbb0207 use eigen objects for ei_fdjac*(), this is a prerequisite before porting
hybrd/lmdif..
2009-08-23 03:54:40 +02:00
Thomas Capricelli
8a27e774f8 use eigen objects for hybrj and lmstr 2009-08-23 03:14:42 +02:00
Thomas Capricelli
3251e12258 use eigen objects for the lmder callback 2009-08-23 03:02:03 +02:00
Thomas Capricelli
2727099906 remove redundant code, fix bounds in those loops that still come from
fortran
2009-08-23 02:32:08 +02:00
Thomas Capricelli
1225704753 we do not need/use the 'void *p' parameter 2009-08-23 01:59:20 +02:00
Jitse Niesen
90735b6a9c Rewrite tutorial section on solving linear systems 2009-08-22 20:12:47 +01:00
Benoit Jacob
37dede6077 fix typo 2009-08-22 10:40:39 -04:00
Thomas Capricelli
a3e8a14e3a forgot to clean this one 2009-08-22 07:40:43 +02:00
Thomas Capricelli
c5218c7d38 ei_lmpar : use a reference for the parameter 2009-08-22 07:37:23 +02:00
Thomas Capricelli
b3f8d02df4 use const for machine constants 2009-08-22 07:31:14 +02:00
Thomas Capricelli
bb6ffafdb9 keep on cleaning f2c mess 2009-08-22 07:27:17 +02:00
Thomas Capricelli
a35586504e cleaning f2c mess / trivial stuff 2009-08-22 07:14:17 +02:00
Benoit Jacob
7bedf5e9cb add initial, rough, full-pivoting RRQR decomposition
lots of room for improvement!
and add Gael a (c) line in Householder.h
2009-08-22 01:13:21 -04:00
Thomas Capricelli
93fabbff5e use blueNorm() instead of norm() 2009-08-22 07:05:10 +02:00
Thomas Capricelli
aa3a7c3303 raw import of covar() : this is the last one, and we now do not depend on
the cminpack library anymore.
2009-08-22 06:44:41 +02:00
Thomas Capricelli
16061a46db Now that the main algorithms are imported into eigen, we import subroutines
used by those algorithms (aka "second level").

This is a row import : we copy/paste the files from cminpack and make
very few changes :
* template<Scalar> them (replace double)
* dpmpar() replaced by c++ standard equivalent
* abs/fabs/sqrt/min/max replaced by ei_* or std::*
* use eigen norms instead of enorm()

Important Notes:
* The use of stableNorm() was not enough in some cases, but using
  blueNorm() instead fixed the problems (some tests gave bad results,
  either in number of iterations or precision of the results)
* As a whole, the only test that changed is testNistMGH17() : it now takes
  some few steps less to get the same result. So this is a small improvement.

After this commit, the only remaining dependency from the cminpack
static library is 'covar', only used from the tests.
2009-08-22 06:40:22 +02:00
Thomas Capricelli
783f355904 cleaning defines from f2c (use std::min and such instead of own ones) 2009-08-22 05:32:17 +02:00
Thomas Capricelli
11c3762068 cleaning : removing #define, use std:min() and such 2009-08-22 05:29:33 +02:00
Marcus D. Hanwell
ef582933c1 Proper fix for linking to the Qt libraries (and others)
My initial fix was incorrect, the libraries must be quoted when being
passed to the add test macro, but must be unquoted when passed to the
target_link_libraries function.
2009-08-21 14:04:17 -04:00
Benoit Jacob
2f0b4e1abc fix compilation with gcc 4.1. Indeed the path for recent gcc doesn't work with gcc 4.1, and looking at the implementation of vector in g++ 4.1, it was exactly our fallback case, so use that. 2009-08-21 12:16:37 -04:00
Peter Román
80179e9549 Added support for SuperLU's ILU factorization 2009-08-21 11:14:45 +02:00
Gael Guennebaud
b0aa2520f1 * add real scalar * complex matrix, real matrix * complex scalar,
and complex scalar * real matrix overloads
* allows the inner and outer product specialisations to mix real and complex
2009-09-04 11:22:32 +02:00
Gael Guennebaud
6902ef0824 extend mixingtype test to check diagonal products and fix the later for real*complex products 2009-09-04 10:17:28 +02:00
Gael Guennebaud
a7ed998d52 bug fix in novel makeGivens for real 2009-09-04 10:05:22 +02:00
Gael Guennebaud
3fbf71d6b9 compilation fix for conservativeResize 2009-09-04 09:26:00 +02:00
Gael Guennebaud
68b28f7bfb rename the EigenSolver module to Eigenvalues 2009-09-04 09:23:38 +02:00
Hauke Heibel
7f5256f628 Added conservativeResize + unit test. 2009-09-03 17:27:51 +02:00
Gael Guennebaud
82ad37c730 implement the continuous generation algorithm of Givens rotations by Anderson (2000) 2009-09-03 17:08:38 +02:00
Hauke Heibel
41aea9508e This seems to be important for MSVC to optimize the size of empty base classes. 2009-09-03 13:46:44 +02:00
Gael Guennebaud
3eb37fe1fb update mixingtype unit test to reflect current status, but it is still clear
we should allow matrix products between complex and real ?
2009-09-03 13:03:26 +02:00
Gael Guennebaud
00f4b46908 typo in sqrt(complex) 2009-09-03 11:50:06 +02:00
Gael Guennebaud
a54b99fa72 move eigen values related stuff of the QR module to a new EigenSolver module.
- perhaps we can find a better name ?
- note that the QR module still includes the EigenSolver module for compatibility
2009-09-03 11:39:44 +02:00
Gael Guennebaud
9515b00876 remove the \addexample tags 2009-09-03 11:22:42 +02:00
Gael Guennebaud
16c7b1daab add examples for makeJacobi and makeGivens 2009-09-03 11:17:16 +02:00
Gael Guennebaud
c893917d65 Fix serious bug discovered with gcc 4.2 2009-09-03 10:45:32 +02:00
Hauke Heibel
8d449bd80e Removed debug cout.
Disabled MSVC inconsistent DLL linkage.
2009-09-02 21:23:09 +02:00
Hauke Heibel
e6c9d6c528 Remove last lazyness warnings. 2009-09-02 20:59:57 +02:00
Hauke Heibel
2abd5eeffd Added support to overwrite the generator type.
Eigen'fied the new variables.
2009-09-02 20:57:41 +02:00
Benoit Jacob
7aa6fd3625 big reorganization in JacobiSVD:
- R-SVD preconditioning now done with meta selectors to avoid compiling useless code
- SVD options now honored, with options to hint "at least as many rows as cols" etc...
- fix compilation in bad cases (rectangular and fixed-size)
- the check for termination is now done on the fly, no more goto (should have done that earlier!)
2009-09-03 02:53:51 -04:00
Benoit Jacob
89557ac41d introduce EIGEN_SIZE_MIN
now we should check if some EIGEN_ENUM_MIN usage needs to be replaced by that... potential bug when using mixed-size matrice
2009-09-03 02:50:42 -04:00
Benoit Jacob
7d18c30641 finally the first version was the good one... 2009-09-03 01:25:40 -04:00
Gael Guennebaud
7586f7f706 fix #51 (bad use of std::complex::real) 2009-09-02 15:18:11 +02:00
Gael Guennebaud
b83654b5d0 * rename JacobiRotation => PlanarRotation
* move the makeJacobi and make_givens_* to PlanarRotation
* rename applyJacobi* => apply*
2009-09-02 15:04:10 +02:00
Gael Guennebaud
496ea63972 fix wrong assert 2009-09-02 14:08:33 +02:00
Gael Guennebaud
4a8258369a much simpler fix for Matrix::swap 2009-09-02 13:37:15 +02:00
Benoit Jacob
ec20d58317 * add serious unit test for swap
* fix my stupidity in Matrix::swap()
2009-09-02 16:56:48 -04:00
Benoit Jacob
cc375e2f79 merge 2009-09-02 06:37:41 -04:00
Benoit Jacob
e6b77bcc6b JacobiSVD: implement general R-SVD using full-pivoting QR, so we now support any rectangular matrix size by reducing to the smaller of the two dimensions (which is also an optimization) 2009-09-02 06:36:55 -04:00
Benoit Jacob
c16d65f015 fix compilation errors in swap (could not swap with anything else than the exact same Matrix type) 2009-09-02 06:35:01 -04:00
Hauke Heibel
59f5bce41c fix issue #49 2009-09-01 23:15:30 +02:00
Hauke Heibel
05ddd32849 added missing JacobiRotation's ... 2009-09-01 23:12:40 +02:00
Gael Guennebaud
5b8ffa4d46 clean a bit the previous commit which came from a patch queue,
and since it was my first try of the patch queue feature I did not
managed to apply it with a good commit message, so here you go:
* Add a ComplexSchur decomposition class built on top of HessenbergDecomposition
* Add a ComplexEigenSolver built on top of ComplexSchur
There are still a couple of FIXME but at least they work for any reasonable matrices,
still have to extend the unit tests to stress them with nasty matrices...
2009-09-01 16:35:23 +02:00
Gael Guennebaud
4d91229bdc [mq]: eigensolver 2009-09-01 16:20:56 +02:00
Gael Guennebaud
67ccc6b851 I've been too fast (again) 2009-09-01 13:44:21 +02:00
Gael Guennebaud
1e7a9ea70a fix issue #47: now m.noalias() = XXX properly resize m if needed 2009-09-01 13:35:44 +02:00
Gael Guennebaud
8392373d96 add a JacobiRotation class wrapping the cosine-sine pair with
some convenient features (transpose, adjoint, product)
2009-09-01 13:18:03 +02:00
Jitse Niesen
32f95ec267 Bug fix in MatrixExponential.h
Initialize matrices for intermediate results to correct dimension
2009-09-01 10:50:54 +01:00
Benoit Jacob
6e4e94ff32 * JacobiSVD:
- support complex numbers
 - big rewrite of the 2x2 kernel, much more robust
* Jacobi:
 - fix weirdness in initial design, e.g. applyJacobiOnTheRight actually did the inverse transformation
 - fully support complex numbers
 - fix logic to decide whether to vectorize
 - remove several clumsy methods

fix for complex numbers
2009-08-31 22:26:15 -04:00
Benoit Jacob
29c6b2452d simplifications 2009-08-31 22:09:44 -04:00
Benoit Jacob
5339db6164 add VERIFY_IS_UNITARY 2009-08-31 22:08:43 -04:00
Gael Guennebaud
a16599751f fix Matrix::stride for vectors, add a unit test for Block::stride
and make use of it where it was relevant
2009-08-31 17:39:56 +02:00
Hauke Heibel
ab6eb6a1a4 Adaptions from .lazy() towards .noalias().
Added missing casts.
2009-08-31 17:29:37 +02:00
Hauke Heibel
bc7aec0ef5 ifdef removed from MapBase and warning disabled 2009-08-31 17:24:38 +02:00
Gael Guennebaud
095809edda fix issue #45 and document the .data() and .stride() functions 2009-08-31 17:07:54 +02:00
Gael Guennebaud
27c9ecc50f fix copy/paste issue 2009-08-31 16:41:13 +02:00
Hauke Heibel
0a0a805569 Fixed a cast warning in scaleAndAddTo.
Fixed lazyness in umeyama.
Added a few missing casts.
2009-08-31 15:34:57 +02:00
Hauke Heibel
32a9aee286 Added MSVC guards to assignment operators. 2009-08-31 14:40:53 +02:00
Hauke Heibel
99bfab6dcf Removed redundant assignment operators. 2009-08-31 13:47:32 +02:00
Gael Guennebaud
9005eb0788 compilation fix in AmbiVector<int> 2009-08-31 09:32:46 +02:00
Thomas Capricelli
20480a5438 merging ei_lmdif() and lmdif_template() 2009-08-21 04:24:59 +02:00
Thomas Capricelli
2e3d17c3ce be (hopefully) smarter with indices convention : we keep the c convention
(0->n-1) as much as possible, and only convert at borders with
fortran-expecting methods, that will eventually dissapear.
2009-08-21 04:16:37 +02:00
Thomas Capricelli
524e112ee5 merging ei_lmstr() and lmstr_template() 2009-08-21 03:41:19 +02:00
Thomas Capricelli
e48b6ad905 merging ei_hybrj() and hybrj_template() 2009-08-21 03:26:28 +02:00
Thomas Capricelli
f2ff0d3903 merging ei_hybrd() and hybrd_template() 2009-08-21 03:13:42 +02:00
Thomas Capricelli
1715e2cb3b merging ei_lmder and lmder_template into ei_lmder() which takes eigen
argument, but still uses f2c code inside.
2009-08-21 02:34:40 +02:00
Thomas Capricelli
6a8b52b3aa simplifying 2009-08-21 01:24:04 +02:00
Thomas Capricelli
0abb148b7d use ei_sqrt instead of sqrt 2009-08-21 00:27:11 +02:00
Thomas Capricelli
1ad042c981 rename i__ to i. i really wonder how f2c can produce such things 2009-08-21 00:26:37 +02:00
Thomas Capricelli
9294d33a11 use references intead of pointers for njev/nfev 2009-08-21 00:23:26 +02:00
Thomas Capricelli
054652b789 use math function adapted to the Scalar type instead of hardcoding float or
double
2009-08-21 00:04:41 +02:00
Thomas Capricelli
d05af200a5 some more trivial fixes to f2c generated code 2009-08-20 23:56:13 +02:00
Thomas Capricelli
9e71c2827a nothing more than indentation fixes (using vim '=' command) 2009-08-20 23:36:03 +02:00
Thomas Capricelli
b1e0662785 cleaning f2c mess 2009-08-20 23:33:45 +02:00
Thomas Capricelli
275a658ec5 porting chkder to eigen 2009-08-20 23:26:40 +02:00
Thomas Capricelli
2e3fa34b9f cleaning a little bit the f2c mess for chkder 2009-08-20 23:07:16 +02:00
Thomas Capricelli
b09ebe01da * porting lmdif1 to eigen
* qtf was missing in lmdif signature (this is an output of the method)
2009-08-20 22:59:09 +02:00
Thomas Capricelli
8d2f6ad7e1 iwa is not really an argument, but just an old fashioned 'work array' :
remove it from the eigen API
2009-08-20 22:46:38 +02:00
Thomas Capricelli
b423e640a6 porting hybrj1 to eigen 2009-08-20 22:41:56 +02:00
Thomas Capricelli
6027c4bedf porting hybrd1 to eigen 2009-08-20 22:36:24 +02:00
Thomas Capricelli
de7d14b2b3 porting lmstr1 to eigen 2009-08-20 22:16:30 +02:00
Thomas Capricelli
980c40f72c porting lmder1 to eigen (no more wrapper) 2009-08-20 22:09:05 +02:00
Thomas Capricelli
a84dc9a5c1 coherency for scalar typename : use "Scalar" everywhere 2009-08-20 21:10:28 +02:00
Thomas Capricelli
df98e66019 oops fix hardcoded typename, which is actually provided as template
parameter
2009-08-20 21:06:26 +02:00
Thomas Capricelli
9a876806e1 use eigen stableNorm() instead of cminpack 'enorm'. The results are mostly
slightly better in tests (one test needs 15 iterations intead of 16, for
the same result). Some numerical results have improved slightly, too.

If one uses blueNorm() instead, an assert for 'overflow' is raised from
blueNorm()
2009-08-20 21:04:38 +02:00
Benoit Jacob
72b002eab9 work around internal compiler error with gcc 4.1 and 4.2, reported on the forum 2009-08-20 12:19:15 -04:00
Benoit Jacob
c7ae261ac0 adapt to API changes 2009-08-20 01:29:38 -04:00
Thomas Capricelli
6953cad81d remove unneeded "Eigen::", we already 'use' Eigen namespace 2009-08-19 20:06:34 +02:00
Thomas Capricelli
369693aa1c oops, forgot those ones 2009-08-19 20:02:49 +02:00
Thomas Capricelli
01622e9855 use machine precision from eigen instead of the one from cminpack. The test
pass though they would not if using a value of 2.220e-16 (the real value
for 'double' is 2.22044604926e-16). How sensitive those tests are :)
2009-08-19 19:56:51 +02:00
Thomas Capricelli
3093e92da5 machine_epsilon is now called epsilon in latest eigen 2009-08-19 19:53:08 +02:00
Thomas Capricelli
47ac354190 merge with the main dev branch 2009-08-19 19:46:37 +02:00
Thomas Capricelli
fb54cfb013 import main files from cminpack as *.h files:
* function names are changed by appending _template
* it uses basic templating : template<typename T>
* wrappers now use those versions instead of the ones from cminpack
* lot of external methods from cminpack are still used
* tests pass though they are unchanged (they use wrappers)
2009-08-19 18:38:45 +02:00
Thomas Capricelli
703198a1a6 wrapper for chkder() : this was the last wrapper missing 2009-08-19 18:32:37 +02:00
Jitse Niesen
59a0c4a0d2 Add new unsupported modules to doc/unsupported_modules.dox 2009-08-18 15:30:38 +01:00
Jitse Niesen
7262716b78 Correct syntax error in doxygen comment. 2009-08-18 11:09:20 +01:00
Gael Guennebaud
d56be9c128 * make HessenbergDecomposition uses the Householder module
* bugfix in ei_blas_traits for .conjugate().conjugate()
2009-08-17 17:41:01 +02:00
Gael Guennebaud
ff0f005d4c change the make householder algorithm so that the remaining coefficient
is real, and make Tridiagonalization use it
2009-08-17 17:04:32 +02:00
Gael Guennebaud
e125c199bb add EIGEN_TRANSFORM_PLUGIN 2009-08-17 09:16:41 +02:00
Gael Guennebaud
737bed19c1 make HouseholderQR uses the Householder module 2009-08-16 19:22:15 +02:00
Gael Guennebaud
ef13c3e754 add normalize and normalized overloads in AlignedVector3 2009-08-16 11:51:46 +02:00
Gael Guennebaud
5274c5c326 quick update of TopicLazyEvaluation 2009-08-16 11:01:32 +02:00
Gael Guennebaud
fc9480cbb3 bugfix in compute_matrix_flags, optimization in LU,
improve doc, and workaround aliasing detection in MatrixBase_eval snippet
(not very nice but I don't know how to do it in a better way)
2009-08-16 10:55:10 +02:00
Benoit Jacob
ee982709d3 in all decs, make the compute() methods return *this
(implements feature request #18)
2009-08-15 23:12:39 -04:00
Gael Guennebaud
65fe5f76fd rename back MayAliasBit to EvalBeforeAssigningBit 2009-08-16 00:14:05 +02:00
Gael Guennebaud
f5f2b222a3 make SVD reuses applyJacobi 2009-08-16 00:02:36 +02:00
Gael Guennebaud
044dd0c1dd revert previous change in Quaternion::setFromTwoVectors 2009-08-15 23:37:20 +02:00
Benoit Jacob
03c1e79f35 svd: sort in decreasing order, remove unused code 2009-08-15 19:20:48 -04:00
Gael Guennebaud
239ada95b7 add overloads of lazyAssign to detect common aliasing issue with
transpose and adjoint
2009-08-15 22:19:29 +02:00
Benoit Jacob
a3e6047c25 fix and improve docs 2009-08-15 15:29:44 -04:00
Gael Guennebaud
50c703f0c7 As proposed on the list:
- rename EvalBeforeAssignBit to MayAliasBit
- make .lazy() remove the MayAliasBit only, and mark it as deprecated
- add a NoAlias pseudo expression, and MatrixBase::noalias() function
Todo:
- we have to decide whether += and -= assume no aliasing by default ?
- once we agree on the API: update the Sparse module and the unit tests respectively.
2009-08-15 18:35:51 +02:00
Gael Guennebaud
13a8956188 bugfix in inner-product specialization,
compilation fix in stable norm,
optimize apply householder
2009-08-15 13:12:50 +02:00
Gael Guennebaud
7b60713e87 my previous fix was not very good 2009-08-15 11:52:50 +02:00
Gael Guennebaud
0da31a6e1d bugfix and compilation fix in ProductBase 2009-08-15 10:55:11 +02:00
Gael Guennebaud
bff4238d15 fix setFromTwoVectors because of the change in sorting of the the singular values 2009-08-15 10:24:27 +02:00
Gael Guennebaud
109a4f650b fix a couple of warnings 2009-08-15 10:20:01 +02:00
Gael Guennebaud
d2becb9612 add a "rot" benchmark in BTL 2009-08-15 10:19:16 +02:00
Gael Guennebaud
846e8b49ba fix compilation of unit tests 2009-08-15 10:18:05 +02:00
Benoit Jacob
2f027b0d2c only append the changeset to the version if we're in the default branch 2009-08-14 21:58:41 -04:00
Thomas Capricelli
5fe0c30811 new script that update from mercurial, make the doc, and upload the result
to tuxfamily.org
2009-08-15 03:36:37 +02:00
Benoit Jacob
62748a0963 new script to generate and upload the docs for a given branch
needs cleanup by a better shell scripter!!
2009-08-14 19:07:01 -04:00
Benoit Jacob
8372bd12bd update snippet 2009-08-14 20:23:13 -04:00
Benoit Jacob
fe4a86443f fix warning 2009-08-14 20:16:04 -04:00
Benoit Jacob
a5f820b873 forgot to update this 2009-08-14 20:03:14 -04:00
Benoit Jacob
2f74801ca4 as discussed on list: default to align cols, reorganize parameters accordingly so that the default corresponds to 0 flag,
and implement FullPrecision output (non-default).
2009-08-14 16:31:42 -04:00
Benoit Jacob
16abc0ba7f try to support 16 bit platforms... optimistic, but can't hurt 2009-08-14 15:49:14 -04:00
Benoit Jacob
22ae236d4e machine_epsilon -> epsilon as wrapper around numeric_traits 2009-08-14 15:12:32 -04:00
Thomas Capricelli
3f63d6f97f fix BoxBOD in the first case : now all tests pass 2009-08-14 19:04:09 +02:00
Thomas Capricelli
3856c2d84d oops, i missed one : real last difficult nist test : Eckerle4 2009-08-14 18:54:28 +02:00
Thomas Capricelli
93627fefcf last 'hard' test from Nist : ratkowsky3 2009-08-14 18:31:04 +02:00
Thomas Capricelli
91f61f7679 fix bad urls 2009-08-14 17:48:04 +02:00
Thomas Capricelli
d8c671f475 yet another (difficult) Nist test : Thurber 2009-08-14 17:46:28 +02:00
Thomas Capricelli
e057d1ef47 tweak precision for Chwirut2 test 2009-08-14 17:25:39 +02:00
Thomas Capricelli
56127cfb1a add yet another easy Nist test : Chwirut2 2009-08-14 17:21:31 +02:00
Gael Guennebaud
6373c3cd00 oops bis, I forgot that SelfAdjointEigneSolver directly called the selector... 2009-08-14 13:49:29 +02:00
Gael Guennebaud
8abec72259 oops forgot to remove the #include in Core 2009-08-14 09:49:33 +02:00
Gael Guennebaud
13e95f7f68 optimize "apply Jacobi" for small sizes, and move it to Jacobi.h 2009-08-14 00:17:14 +02:00
Benoit Jacob
f2536416da * remove EIGEN_DONT_INLINE that harm performance for small sizes
* normalize left Jacobi rotations to avoid having to swap rows
* set precision to 2*machine_epsilon instead of machine_epsilon, we lose 1 bit of precision
  but gain between 10% and 100% speed, plus reduce the risk that some day we hit a bad matrix
  where it's impossible to approach machine precision
2009-08-13 14:56:39 -04:00
Thomas Capricelli
f7cd4c8923 cleaning : wa1 used in 'covar' needs not be the same as in lmder* and all.
it's just an old-fashioned way to re-use memory without allocation...
2009-08-13 16:29:17 +02:00
Benoit Jacob
76a3089a43 oops, don't set the precision to -1 !! 2009-08-13 09:56:53 -04:00
Benoit Jacob
13b191d94b apply Koldo's workaround for MSVC bug 2009-08-13 09:53:47 -04:00
Gael Guennebaud
1b257a7620 add an optimized "apply in place a rotation in the plane",
and make Jacobi and SelfAdjointEigenSolver use it
=> ~ x1.75 speedup for JacobiSVD and x2 for SelfAdjointEigenSolver
2009-08-13 11:42:02 +02:00
Benoit Jacob
1d80f561ad apply change discussed on the list :
* new default precision "-1" means use the current stream precision
* otherwise, save and restore the stream precision
2009-08-13 22:50:55 -04:00
Benoit Jacob
99802094e4 do without an empirical homemade formula that i wasn't comfortable about...
turns out it's not needed anymore and removing it seems to only increase the precision
2009-08-12 18:30:37 -04:00
Benoit Jacob
6bb6810c5e merge 2009-08-12 18:25:13 -04:00
Benoit Jacob
2b618a2c16 make jacobi SVD more robust after experimenting with very nasty matrices...
it turns out to be better to repeat the jacobi steps on a given (p,q) pair until it
is diagonal to machine precision, before going to the next (p,q) pair. it's also
an optimization as experiments show that in a majority of cases this allows to find out
that the (p,q) pair is already diagonal to machine precision.
2009-08-12 18:23:39 -04:00
Jitse Niesen
f71f878bab Add support for matrix exponential of floats and complex numbers. 2009-08-12 15:44:22 +01:00
Benoit Jacob
309d540d4a add parentheses; hopefully this solves Koldos MSVC compilation issue... 2009-08-12 10:14:15 -04:00
Benoit Jacob
22d65d47d0 finally, the good approach was two-sided Jacobi. Indeed, it allows
to guarantee the precision of the output, which is very valuable.
Here, we guarantee that the diagonal matrix returned by the SVD is
actually diagonal, to machine precision.

Performance isn't bad at all at 50% of the current householder SVD
performance for a 200x200 matrix (no vectorization) and we have
lots of room for improvement.
2009-08-12 02:35:07 -04:00
Thomas Capricelli
7b922eb634 BoxBOD : oops.. shame on me, i did a mistake in the derivative.... now we need 16
iterations instead of 7693 ;-)
the first test still fails though.
2009-08-12 02:34:22 +02:00
Thomas Capricelli
fd307b8f3f fix a bug in BoxBOD Nist test : we now get the actual value for 'start 2'
'start 1' still fails though :/
2009-08-12 02:27:44 +02:00
Thomas Capricelli
3c675609bf add another Nist test of 'hard' difficutly : Bennett5 2009-08-12 02:13:04 +02:00
Thomas Capricelli
54d09a8122 add another Nist test of 'hard' difficutly : MGH09 2009-08-12 01:50:56 +02:00
Benoit Jacob
ce033ebdfe add EIGEN_DEBUG_VAR 2009-08-11 16:12:34 -04:00
Thomas Capricelli
5ac17b4680 add another Nist test of medium difficutly : MGH17 2009-08-11 20:24:02 +02:00
Gael Guennebaud
afbd73b5cd overload operartor* with a ProductBase such that "scalar * (mat * mat)" is optimized
as one could naturally expect
2009-08-11 15:15:06 +02:00
Gael Guennebaud
a4f6642518 fix issue #36 (missing return *this in Rotation2D 2009-08-11 15:11:47 +02:00
Gael Guennebaud
ea884e6f48 remove #include Bidiagonalization, and add missing ";" 2009-08-11 15:08:03 +02:00
Thomas Capricelli
d1bc9144cb wrapper for lmstr1 and lmstr + eigenization of calling tests 2009-08-10 17:37:27 +02:00
Thomas Capricelli
bb1204a145 wrapper for lmdif1 + eigenization of calling test 2009-08-10 17:16:43 +02:00
Thomas Capricelli
80372c18ee wrapper for lmdif (+test call eigenization) 2009-08-10 16:54:53 +02:00
Thomas Capricelli
4a26baa718 wrapper for hybrj1 2009-08-10 16:32:45 +02:00
Thomas Capricelli
1d53ce8d48 wrapper for hybrj 2009-08-10 16:21:22 +02:00
Thomas Capricelli
120235deef add another (actuallY) difficult NIST test : BoxBOD.
The first try fails, the second one passes, but with a very bad accuracy
(~4 digits only).
anyway, my aim is to check we do not change cminpack while portint, so i
keep this test.
2009-08-10 14:11:55 +02:00
Thomas Capricelli
bcfe874968 add another 'difficult'-rated NIST test, which passes 2009-08-10 13:47:18 +02:00
Thomas Capricelli
7d65bd42eb fix testNistHahn1 : i had swapped x[] and y[].... :/ 2009-08-10 13:46:43 +02:00
Thomas Capricelli
b71aa34946 a Nist test rated 'difficult', which passes. 2009-08-10 13:05:30 +02:00
Thomas Capricelli
9b1130b82a another nist test with difficulty 'leverage', it passes. 2009-08-10 12:49:44 +02:00
Thomas Capricelli
7ecbbc9aa4 another nist test with difficulty 'leverage', this one passes 2009-08-10 12:34:51 +02:00
Thomas Capricelli
1045bc17f5 another nist test ('average' difficulty), which fails. It is disabled until
further notice.
2009-08-10 12:08:31 +02:00
Thomas Capricelli
c7a72958ba add an easy test from the NIST set :
http://www.itl.nist.gov/div898/strd/nls/data/misra1a.shtml
2009-08-10 10:47:55 +02:00
Thomas Capricelli
ec2b9f90a3 hybrd : wrapper + eigenize test 2009-08-10 03:39:50 +02:00
Gael Guennebaud
35b4077a5d merge 2009-08-09 23:11:25 +02:00
Gael Guennebaud
ef55e7f4ce make custom asm directive volatile 2009-08-09 23:09:46 +02:00
Benoit Jacob
216ee335ac LinearVectorization: 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
2009-08-09 22:19:12 +02:00
Benoit Jacob
1f1705868b now you can #define EIGEN_DEBUG_ASSIGN, and all the values in ei_assign_traits are printed 2009-08-09 21:35:13 +02:00
Benoit Jacob
527557672a disable the assembly for fast unaligned stores. indeed, there is a strange bug that is triggered by this code:
#include<Eigen/Core>

int main()
{
  Eigen::Matrix4f m;
  m <<1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16;
  m.col(0).swap(m.col(1));
  std::cout << m << std::endl;
}

when the fast unaligned stores are used, the column is copied instead of being swapped.
2009-08-09 20:49:55 +02:00
Benoit Jacob
8e08680119 don't depend on uninitialized value 2009-08-09 17:18:42 +02:00
Benoit Jacob
3ed83fa681 * add Jacobi transformations
* add Jacobi (Hestenes) SVD decomposition for square matrices
* add function for trivial Householder
2009-08-09 16:58:13 +02:00
Thomas Capricelli
953c37f8e5 i wonder how useful this really is, but others do this way. Probably
related to doxygen.
2009-08-09 05:14:45 +02:00
Thomas Capricelli
50c192961c eigenize lmder + some other small fixes 2009-08-09 05:07:59 +02:00
Thomas Capricelli
a6625f22d4 eigenize the test for lmder1, clean functor stuff.
(and check the tests still pass, of course, that's the whole point..)
2009-08-09 03:54:36 +02:00
Thomas Capricelli
5e4cf6cae1 oops.. use the template paramater instead of hard coding 'double' 2009-08-09 03:34:32 +02:00
Thomas Capricelli
ceeb023ff2 use template parameter Scalar instead of VectorType, fix a segfault. 2009-08-09 03:33:04 +02:00
Thomas Capricelli
7db4052749 eigenize the test a little more 2009-08-09 03:16:24 +02:00
Thomas Capricelli
f19eda7cf6 first test for a basic wrapper (and only wrapper!) for cminpack functions 2009-08-09 03:07:34 +02:00
Thomas Capricelli
2b9f110639 actually use eigen include file 2009-08-09 01:12:14 +02:00
Gael Guennebaud
fe813911f2 make LU::solve() not to crash when rank=0 2009-08-09 00:06:53 +02:00
Benoit Jacob
5f8d58f36a fix bug in sorting of singular values 2009-08-09 00:05:38 +02:00
Thomas Capricelli
b695113a81 Add all other file from cminpack/examples as tests.
Important : one test was failing because cminpack-1.0.2 does x[3]=1. on x
which is of size 3. Probably because fortran indices are shifted wrt to C
indices and someone forgot to fix this one.

This is correct in this commit and this is the only change I've done on files
from cminpack examples.

(i've also reported the bug to cminpack author)
2009-08-08 23:41:54 +02:00
Thomas Capricelli
d646d99366 Start of module "NonLinear". We start out of cminpack-1.0.2
(http://devernay.free.fr/hacks/cminpack.html)
The first test is adapted from the example/ directory.
Some stuff is hard coded for our initial tests.
2009-08-08 22:18:48 +02:00
Thomas Capricelli
b10637be50 add basic .hgignore file for most common generated/temporary files 2009-08-08 21:42:14 +02:00
Gael Guennebaud
f5e1c896c7 replace custom rank one update in LU by an expression 2009-08-08 00:01:43 +02:00
Gael Guennebaud
d1dc088ef0 * implement a second level of micro blocking (faster for small sizes)
* workaround GCC bad implementation of _mm_set1_p*
2009-08-07 11:09:34 +02:00
Gael Guennebaud
543a785756 Fix compilation in sparse module 2009-08-06 17:28:49 +02:00
Gael Guennebaud
2707a6b87c fix determinant in PartialLU 2009-08-06 17:28:31 +02:00
Gael Guennebaud
1d1e4884da oops, one more bug fix in homogeneous 2009-08-06 16:56:10 +02:00
Gael Guennebaud
9822493aaf fixes in determinant and homogeneous 2009-08-06 16:54:55 +02:00
Gael Guennebaud
3ac01b1400 compilation fix in EigenSolver,
bugfix in PartialLU
2009-08-06 16:41:54 +02:00
Gael Guennebaud
e82e30862a typo 2009-08-06 15:04:42 +02:00
Gael Guennebaud
03febf00a0 fix VS compilation issue in MapBase::operator+= and -= 2009-08-06 15:03:37 +02:00
Gael Guennebaud
2e46e9f2b4 shame on me 2009-08-06 14:57:38 +02:00
Gael Guennebaud
d34c5ef509 fix my bad fix of Hauke's fix ;) 2009-08-06 14:54:25 +02:00
Gael Guennebaud
1d4fea48b5 fix a couple of compilations issues 2009-08-06 14:10:02 +02:00
Hauke Heibel
c2861dd41a fixed inversion for AffineCompact matrices 2009-08-06 12:25:18 +02:00
Gael Guennebaud
56d00779db more product refactoring 2009-08-06 12:20:02 +02:00
Hauke Heibel
6b2ab13ac5 fix vs.net compilation issue 2009-08-06 11:40:25 +02:00
Hauke Heibel
8163757cf0 fix vs.net compilation issue 2009-08-06 11:27:25 +02:00
Gael Guennebaud
fa55cf5ce7 fix compilation and segfault issues 2009-08-06 11:19:36 +02:00
Gael Guennebaud
b9b17ea5a5 add the missing Affine Transform * set of column vectors products... 2009-08-06 11:02:03 +02:00
Benoit Jacob
0744638b6f remove remnant of MultiplierBase 2009-08-06 10:35:13 +02:00
Gael Guennebaud
84a7659bef implement the missing outer product,
and attempt to workaround a gcc internal error
2009-08-05 17:39:11 +02:00
Gael Guennebaud
88147e0a91 big refactoring in Product.h:
- all specialized products now inherits ProductBase
- the default product evaluated by Assign is still here,
  but it is currently enabled for small fixed sizes only
- => this significantly speed up compilation for large matrices
- I left the OuterProduct specialization empty as an exercise...
2009-08-05 15:23:35 +02:00
Benoit Jacob
014c581a5b fix assertions, improve docs.
we never assert on conditions that depend on the result of a computation!!
also the assertion that rank>0 amounts to matrix!=0 which we have to leave under the responsibility of the user.
2009-08-05 10:15:28 +02:00
Benoit Jacob
b183a4f879 merge 2009-08-04 17:47:27 +02:00
Gael Guennebaud
ab6302376c merge 2009-08-04 17:12:00 +02:00
Benoit Jacob
c20236ea75 remove the FORCE 2009-08-04 17:06:54 +02:00
Gael Guennebaud
7d607048a9 implement a ProductBase class and, as a proof of concept, update TriangularProduct
and SelfAdjointMatrixProduct to take advantage of it => fewer LOC
2009-08-04 16:54:17 +02:00
Gael Guennebaud
f3a6bc48c4 fix a couple of compilation issue due to the removal of MultiplierBase 2009-08-04 13:16:40 +02:00
Gael Guennebaud
2089a263f8 merge 2009-08-04 11:31:25 +02:00
Gael Guennebaud
c2a92e92a6 add ger and lu with partial pivoting in BTL 2009-08-04 11:30:33 +02:00
Gael Guennebaud
4bec101470 implement two levels of blocking in PartialLU => high speedup 2009-08-04 11:28:02 +02:00
Benoit Jacob
4436a4d68c use explicit Block/VectorBlock xprs to make sure that compile-time known sizes are used 2009-08-04 00:27:58 +02:00
Benoit Jacob
523cdedf58 make the dot product linear in the second variable, not the first variable 2009-08-03 17:20:45 +02:00
Gael Guennebaud
912da9fade merge with special_matrix branch 2009-08-03 16:17:32 +02:00
Gael Guennebaud
a8f943127c merge 2009-08-03 16:11:30 +02:00
Benoit Jacob
d10c710b15 add new Householder module 2009-08-03 16:06:57 +02:00
Gael Guennebaud
3cf5bb31f6 * Bye bye MultiplierBase, extend a bit AnyMatrixBase to allow =, +=, and -=
* This probably makes ReturnByValue needless
2009-08-03 16:05:15 +02:00
Benoit Jacob
66ee2044ce small fixes 2009-08-03 16:05:07 +02:00
Benoit Jacob
3cde9c0e35 apply Gael's idea for auto transpose in mixed fixed/dynamic case 2009-08-03 16:04:15 +02:00
Gael Guennebaud
ce1dc1ab16 implements a blocked version of PartialLU 2009-08-03 12:11:18 +02:00
Gael Guennebaud
0103de8512 bugfix in trsm 2009-08-02 15:32:43 +02:00
Benoit Jacob
cd49780143 apply patch from Marcus Hanwell: Improved quoting of tests when added to the build 2009-08-02 15:09:34 +02:00
Gael Guennebaud
48fc64458c add blocked LLT, and bugfix in trsm asserts 2009-08-01 23:42:51 +02:00
Gael Guennebaud
18429156a1 add selfadjointView from a trinagularView 2009-07-31 17:35:55 +02:00
Gael Guennebaud
2796bcabb1 some cleaning 2009-07-31 17:35:20 +02:00
Gael Guennebaud
a156f5a869 faster trsm kernel and fix a couple of issues 2009-07-31 13:18:19 +02:00
Gael Guennebaud
21f686846b s/std::atan2/ei_atan2 2009-07-31 10:08:23 +02:00
Manuel Yguel
ae5e26a363 add missing ei_atan2 without painfull warnings 2009-07-31 09:21:31 +02:00
Gael Guennebaud
2e9f7f80bf compilation fixes for sun CC 2009-07-31 10:04:34 +02:00
Benoit Jacob
d8bfd151d1 forward-port Anthony Truchet's changeset 8eab0bccbf 2009-07-30 16:05:38 +02:00
Gael Guennebaud
ff20a2ba94 add explicit "on the right" triangular solving,
=> no temporary when the rhs/unknows is row major
2009-07-30 16:03:06 +02:00
Gael Guennebaud
62d9b9b7b5 fix typo 2009-07-29 09:26:20 +02:00
Gael Guennebaud
864171df5c fix a couple of issues related to recent products 2009-07-28 18:11:30 +02:00
Gael Guennebaud
1ba35248e9 synch with main branch 2009-07-28 17:37:22 +02:00
Gael Guennebaud
54804eb626 synch with main branch 2009-07-28 17:35:07 +02:00
Gael Guennebaud
264fe82c65 add a debug mechanism to compute the number of intermediate evaluations (only for dynamic size) 2009-07-28 17:13:13 +02:00
Gael Guennebaud
508f06ac0f update doc 2009-07-28 17:11:15 +02:00
Gael Guennebaud
de8b795895 compilation fixes in BTL 2009-07-28 17:10:34 +02:00
Gael Guennebaud
7ed7ec64b5 improve the expression analyzer to bypass Transpose expression 2009-07-28 14:02:12 +02:00
Gael Guennebaud
6713c75fac update doc 2009-07-28 12:08:26 +02:00
Gael Guennebaud
7579360672 fix compilation of the doc and started a page dedicated to high performance and or BLAS users 2009-07-27 18:50:39 +02:00
Gael Guennebaud
5f3606bce9 bug fix in inverse for 1x1 matrix,
some compilation fixes in sparse_solvers
2009-07-27 18:09:56 +02:00
Gael Guennebaud
94cc30180e compilation fixes 2009-07-27 13:50:23 +02:00
Gael Guennebaud
0590c18555 various compilation and bug fixes in selfadjoint stuff 2009-07-27 13:17:39 +02:00
Gael Guennebaud
b5e4064289 cleaning and fix a perf issue 2009-07-27 12:13:53 +02:00
Gael Guennebaud
f95b77be62 trmm is now fully working and available via TriangularView::operator* 2009-07-27 11:42:54 +02:00
Gael Guennebaud
6aba84719d trmm is now working in all storage order configurations 2009-07-27 10:27:01 +02:00
Gael Guennebaud
1d4d9a37fd some cleaning 2009-07-26 13:53:24 +02:00
Gael Guennebaud
f3fde74695 finalize trsm: works in all situations, and it is now used by solve() and solveInPlace() 2009-07-26 13:01:37 +02:00
Gael Guennebaud
282e18da49 ok, now trsm works very well for upper triangular matrices
TODO: link it with the meta triangular_solve_selector and handle
the case where the rhs is row major by copying it to a col-major
temporary + handle right solving: X = B * M^-1
2009-07-26 00:49:17 +02:00
Gael Guennebaud
f4112dcff3 The new trsm is working very very well (read very fast) for
lower triangular matrix and row or col major lhs.
TODO: handle upper triangular and row major rhs cases
2009-07-25 21:41:01 +02:00
Gael Guennebaud
35927e78c2 add WIP trsm 2009-07-24 16:21:52 +02:00
Gael Guennebaud
c6d06c22ac some cleaning 2009-07-24 10:53:31 +02:00
Gael Guennebaud
6076173f0b add a simplified version of the sybb kernel built on top of gebp 2009-07-24 10:08:21 +02:00
Gael Guennebaud
82c5438c95 split and add unit tests for symm and syrk,
the .rank*update() functions now returns a reference to *this
2009-07-23 21:22:51 +02:00
Gael Guennebaud
b67abe22b3 oops,, update SYRK so that the rhs can be non-square² 2009-07-23 20:56:04 +02:00
Gael Guennebaud
a81388fae9 Implement efficient sefladjoint product (aka SYRK) : C += alpha * U U^T
It is currently available via SelfAdjointView::rankKupdate.
TODO: allows to write SelfAdjointView += u * u.adjoint()
2009-07-23 19:01:20 +02:00
Gael Guennebaud
713c92140c improve SYMV it is now faster and ready for use 2009-07-23 14:20:45 +02:00
Gael Guennebaud
eee14846e3 formating 2009-07-23 10:19:58 +02:00
Gael Guennebaud
ddb3ac98a2 addd matrix * self adjoint high level API 2009-07-23 10:05:38 +02:00
Hauke Heibel
8d2cd744b0 Added an explicit cast from int to bool to suppress MSVC warnings. 2009-07-23 00:11:25 +02:00
Gael Guennebaud
f696efc00e bugfix in SYMM 2009-07-22 23:48:42 +02:00
Gael Guennebaud
0cb4f32e12 implement high level API for SYMM and fix a couple of bugs related to complex 2009-07-22 23:12:22 +02:00
Gael Guennebaud
e7f8e939e2 * GEMM enhencement: no need to pre-transpose the rhs
=> faster a * b.transpose() product
  => this also fix a bug in a so far untested situation
* SYMM is now ready for use => still have to write the high level
  stuff to convert natural expressions into a call to SYMM
2009-07-22 18:04:16 +02:00
Gael Guennebaud
d6475ea390 more refactoring in the level3 products 2009-07-22 11:54:58 +02:00
Gael Guennebaud
d6627d540e * refactoring of the matrix product into multiple small kernels
* started an efficient selfadjoint matrix * general matrix product
  based on the generic kernels ( => need a very little LOC)
2009-07-21 16:58:35 +02:00
Gael Guennebaud
afa8f2ca95 * various fixes related to sub diagonals and band matrix
* allows 0 sized objects in Block/Map
2009-07-21 11:19:52 +02:00
Gael Guennebaud
562864bcfb enable our own ctest dashboard 2009-07-20 23:06:04 +02:00
Gael Guennebaud
a012aecbc4 bugfix in SVD 2009-07-20 13:44:52 +02:00
Gael Guennebaud
4375c043ac minor compilation fixes for Sun CC and ICC 2009-07-20 13:27:41 +02:00
Gael Guennebaud
4c85fa8c73 compilation fix (sun CC) 2009-07-20 10:57:31 +02:00
Gael Guennebaud
c10b919edb compilation fix 2009-07-20 10:56:03 +02:00
Gael Guennebaud
b3ad796d40 bugfix in operator*= (matrix product) 2009-07-20 10:44:07 +02:00
Gael Guennebaud
a551107cce bugfix for a = a * b; when a has to be resized 2009-07-20 10:35:47 +02:00
Gael Guennebaud
32b08ac971 re-implement stableNorm using a homemade blocky and
vectorization friendly algorithm (slow if no vectorization)
2009-07-17 16:22:39 +02:00
Gael Guennebaud
15ed32dd6e add other stable norm impl. in the benchmark 2009-07-16 16:21:26 +02:00
Gael Guennebaud
525da6a464 bugfix in blueNorm 2009-07-16 14:20:36 +02:00
Gael Guennebaud
65fc70b750 add a benchmark for the different norms 2009-07-16 11:33:56 +02:00
Gael Guennebaud
34490f1493 * bugfixes in Product, and test/product_selfadjoint
* speed up in the extraction of the matrix Q in Tridiagonalization
2009-07-16 00:03:17 +02:00
Gael Guennebaud
97c9445c60 synch with main devel branch 2009-07-15 19:54:31 +02:00
Gael Guennebaud
079fa81d84 add a TridiagonalMatrix wrapper arround BandMatrix, and extend this latter 2009-07-15 19:53:08 +02:00
Gael Guennebaud
4f792583c7 add BandMatrix::col() 2009-07-15 18:00:11 +02:00
Gael Guennebaud
df6561a73f change the implementation of BandMatrix to follow the BLAS/LAPACK storage scheme 2009-07-15 17:00:49 +02:00
Gael Guennebaud
1578421ed1 fix issue #25 : the problem was that we assumed Dynamic was a multiple of a packet size
(also disable the test of blueNorm)
2009-07-15 14:20:45 +02:00
Gael Guennebaud
587029a612 started an implementation of BandMatrix: at least the read/write access
to the main/sub/super diagonals seems to work well.
2009-07-14 23:27:37 +02:00
Gael Guennebaud
8120a5cecd synch with main devel branch 2009-07-14 23:06:25 +02:00
Gael Guennebaud
7a9519a9be fix typo in blue norm 2009-07-14 23:00:53 +02:00
Gael Guennebaud
279cedc1ce some cleaning/renaming is Triangular/SelfadjointView 2009-07-14 22:38:21 +02:00
Gael Guennebaud
f5d2317b12 add a blueNorm() function implementing the Blues's stable norm
algorithm. it is currently provided for experimentation
purpose only.
2009-07-13 21:14:47 +02:00
Gael Guennebaud
ddbaaebf9e one more fix of the previous commit (forgot to update ei_must_nest_by_value) 2009-07-13 15:27:01 +02:00
Gael Guennebaud
bd506d837c fix typo in previous commit 2009-07-13 15:21:32 +02:00
Gael Guennebaud
1e7b1a8a85 add a SparseNestByValue expression and fix issue in sparse adjoint evaluation 2009-07-13 14:55:03 +02:00
Gael Guennebaud
a2cf7ba955 add triangular * vector product 2009-07-13 13:17:55 +02:00
Gael Guennebaud
a2087cd7a3 Add an efficient rank2 update function (like the level2 blas xSYR2 routine).
Note that it is already used in Tridiagonalization.
2009-07-11 21:14:59 +02:00
Gael Guennebaud
ab17f92728 more sun studio fixes 2009-07-10 16:27:01 +02:00
Gael Guennebaud
ec5c608aa3 Set of fixes and workaround to make sun studio more happy.
Still remains the problem of alignment and vectorization.
2009-07-10 16:10:03 +02:00
Gael Guennebaud
b47dea8b7a add a meta unroller for the triangular solver (only for vectors as rhs) 2009-07-10 11:30:46 +02:00
Gael Guennebaud
1a1b2e9f27 finally directly calling the low-level products is faster 2009-07-10 10:41:26 +02:00
Gael Guennebaud
1c52985aa7 merge 2009-07-10 08:21:57 +02:00
Gael Guennebaud
629e083d81 slight change in the comparison to -1 2009-07-10 08:21:20 +02:00
Gael Guennebaud
8885d56928 commit woking versions of triangular solvers naturally
handling conjuagted expression. still have to bench whether it
is faster (runtime and compile time) to directly call the
cache friendly functions, whence all the commented piece of code...
2009-07-09 23:59:18 +02:00
Gael Guennebaud
fa60c72398 started to simplify the triangular solvers 2009-07-09 17:11:03 +02:00
Gael Guennebaud
96e7d9f896 ok now all the complex mat-mat and mat-vec products involving conjugate,
adjoint, -, and scalar multiple seems to be well handled. It only remains
the simpler case: C = alpha*(A*B) ... for the next commit
2009-07-08 18:24:37 +02:00
Gael Guennebaud
13b2dafb50 conjugate expressions are now properly caught by Product
=> significant speedup in expr. like a.adjoint() * b,
   for complex scalar type (~ x3)
2009-07-07 21:30:20 +02:00
Gael Guennebaud
5ed6ce90d3 started to catch scalar multiple and conjugate xpr in Product 2009-07-07 16:55:51 +02:00
Gael Guennebaud
ea23f36c78 * change the nesting order of adjoint_return_type to
1 - make it easier to catch conjugate expressions
 2 - make sure there is no unecessary copy (we had NestByValue<Derived> which seems to be very bad)
* update eigensolver wrt recent changes
2009-07-07 15:56:13 +02:00
Gael Guennebaud
79877a9917 * take advantage of new possibilies in LLT (mat -= product)
* fix Block::operator+= product which was not optimized
* fix some compilation issues
2009-07-07 15:32:21 +02:00
Gael Guennebaud
92a35c93b2 * extended the cache friendly products to support C = alpha * A * M and C += alpha * A * B
* this allows to optimize xpr like C -= lazy_product, still have to catch "scalar_product_of_lazy_product"
* started to support conjugate in cache friendly products (very useful to evaluate A * B.adjoint() without
  evaluating B.adjoint() into a temporary
* compilation fix
2009-07-07 11:39:19 +02:00
Gael Guennebaud
544888e342 add a generic mechanism to copy a special matrix to a dense matrix so that
we don't need to add other specialization of MatrixBase::operator=, Matrix::=,
and Matrix::Matrix(...)
2009-07-07 09:05:20 +02:00
Gael Guennebaud
1aea45335f * bybye Part, welcome TriangularView and SelfAdjointView.
* move solveTriangular*() to TriangularView::solve*()
* move .llt() to SelfAdjointView
* add a high level wrapper to the efficient selfadjoint * vector product
* improve LLT so that we can specify which triangular part is meaningless
=> there are still many things to do (doc, cleaning, improve the matrix products, etc.)
2009-07-06 23:43:20 +02:00
Benoit Jacob
889726bf7c add matrixQR() method exposing the storage. that's where the householder thing impacts the API. 2009-07-06 17:24:11 +02:00
Benoit Jacob
e057beee4e fix some search-and-replace damage 2009-07-06 17:20:07 +02:00
Benoit Jacob
e093b43b2c * rename QR to HouseholderQR because really that impacts the API, not just the impl.
* rename qr() to householderQr(), for same reason.
* clarify that it's non-pivoting, non-rank-revealing, so remove all the rank API, make solve() be void instead of bool, update the docs/test, etc.
* fix warning in SVD
2009-07-06 17:12:10 +02:00
Gael Guennebaud
f84bd3e7b1 include the fixes of the third edition 2009-07-06 15:01:30 +02:00
Gael Guennebaud
0c2232e5d9 quick reimplementation of SVD from the numeral recipes book:
this is still not Eigen style code but at least it works for
n>m and it is more accurate than the JAMA based version. (I needed
it now, this is why I did that)
2009-07-06 13:47:41 +02:00
Gael Guennebaud
0cd158820c switch from eigensolver to SVD which seems to be more accurate with float 2009-07-06 11:15:38 +02:00
Gael Guennebaud
90f1e24579 significantly improve the accuracy of setFromTwoVectors (fixes #21) 2009-07-06 10:35:20 +02:00
Gael Guennebaud
ecc4f07af5 fix doc of Quaternion::setFromTwoVectors 2009-07-06 09:17:25 +02:00
Gael Guennebaud
c6f610093b add a VectorBlock expr as a specialization of Block 2009-07-05 11:33:55 +02:00
Gael Guennebaud
eec334c604 fixes a segfault 2009-07-05 10:48:57 +02:00
Benoit Jacob
60467e54a5 some docs improvements 2009-07-05 01:52:42 +02:00
Manuel Yguel
c398d0edcf another test in the non invertible case 2009-07-04 14:55:25 +02:00
Gael Guennebaud
08e419dcb1 * update sparse module wrt new diagonal matrix impl
* fix a bug is SparseMatrix
2009-07-04 11:16:27 +02:00
Gael Guennebaud
d457ec5810 fix #20: SVD::solve() now resize the result 2009-07-04 09:28:11 +02:00
Benoit Jacob
7b750182f2 * polish computeInverseWithCheck to share more code, fix documentation, fix coding style
* add snippet for computeInverseWithCheck documentation
* expand unit-tests to cover computeInverseWithCheck
2009-06-29 22:07:37 +02:00
Manuel Yguel
126a031a39 computeInverseWithCheck method added to matrix base (specialization for 1D to 4D) 2009-06-29 20:47:37 +02:00
Benoit Jacob
632cb7a4a1 patch by Myguel from the forum: fix documentation 2009-06-29 19:26:20 +02:00
Benoit Jacob
2de9b7f537 fully vectorize DiagonalProduct
(it used to be partially vectorized and that had been lost in the big changes from the previous commit)
2009-06-29 04:01:31 +02:00
Benoit Jacob
bf91003d37 FreeBSD: determine precisely when malloc is 16-byte aligned 2009-06-29 00:08:34 +02:00
Benoit Jacob
5eabf2b75d double precision() : change to 1e-12 instead of 1e-11 (as discussed several times on the list) 2009-06-29 00:00:29 +02:00
Benoit Jacob
6809f7b1cd new implementation of diagonal matrices and diagonal matrix expressions 2009-06-28 21:27:37 +02:00
Benoit Jacob
fc9000f23e only disable the inline ASM if we're NEITHER gcc nor icc. right ?? 2009-06-26 05:32:21 +02:00
Benoit Jacob
6ccb97620a patch by Patrick Mihelich: use empty struct + anonymous namespace for NoChange 2009-06-25 03:33:47 +02:00
Benoit Jacob
60e6ac3178 use system variable instead of custom one 2009-06-25 01:06:53 +02:00
Benoit Jacob
903acf0d5c add missing code snippets for newer Matrix methods and PartialLU::solve() 2009-06-25 00:57:51 +02:00
Benoit Jacob
03ad303d14 * add resize(int, NoChange) and resize(NoChange, int)
* add missing assert in resize(int)
* add examples for all resize variants
* expand docs (part of which is from Tim Hutt's e-mail)
2009-06-24 22:07:03 +02:00
Benoit Jacob
96dca681b0 use <...> for system headers 2009-06-24 16:35:02 +02:00
Gael Guennebaud
a44f7cf440 re-enable the fast unaligned loads for gcc and icc using inline assembly
(this allows to avoid incompatible pointer casts and to specify the dependency to the data explicitely)
2009-06-24 10:48:36 +02:00
Gael Guennebaud
aa17b5b514 use the slower unaligned load intrinsics in ei_ploadu because GCC mess up with my tricks 2009-06-23 23:28:34 +02:00
Benoit Jacob
3934a8b5e8 check version number using newer cmake functionality, instead of kde macro 2009-06-23 15:39:46 +02:00
Gael Guennebaud
ec8596f863 update the stack alignment doc 2009-06-22 10:44:09 +02:00
Benoit Jacob
ac9680fb20 document the "wrong stack alignment" issue. 2009-06-21 17:25:57 +02:00
Benoit Jacob
7d48ed4be3 refine the check to disable alignment. now it's disabled on gcc3 (where we don't vectorize anyway) 2009-06-21 04:56:01 +02:00
Benoit Jacob
8be088bfb0 add Eigen/Eigen 2009-06-19 20:46:55 +02:00
Benoit Jacob
fe8ab0147b add "Dense" header 2009-06-19 19:09:35 +02:00
Benoit Jacob
032594cee2 forward port fix to #12 2009-06-19 18:51:15 +02:00
Benoit Jacob
a57325e971 fix #14: make llt::solve() and also ldlt::solve() work with uninitialized result 2009-06-19 17:01:32 +02:00
Moritz Lenz
c6e81869d0 fixed typo in SuperLUSupport.h 2009-06-17 11:55:57 +02:00
Mark Borgerding
fb9a15e451 added copyright notice 2009-06-17 00:09:18 -04:00
Mark Borgerding
e577c70e49 candidate header for Eigen/Complex 2009-06-16 23:54:58 -04:00
Mark Borgerding
218711e18b example file 2009-06-10 23:25:27 -04:00
Mark Borgerding
4d6b962ba4 added FindFFTW, but I don't think it's right yet 2009-06-10 22:16:32 -04:00
Gael Guennebaud
627595ad19 * rename PartialRedux to VectorwiseOp
* add VectorwiseOp's +, -, +=, -= operators
2009-06-10 11:20:30 +02:00
Gael Guennebaud
f3fd7fd22b fix #11: now the default Transform ctor set the last row in Affine mode. 2009-06-10 09:35:04 +02:00
Gael Guennebaud
d97d307fcf SparseMatrix::resize() always resets the matrix to an empty one 2009-06-08 14:12:11 +02:00
Gael Guennebaud
55de162cf6 fix #10: the reallocateSparse function was half coded 2009-06-08 14:05:23 +02:00
Gael Guennebaud
c49d1fd2b5 add a partial LU bench in BTL 2009-06-04 18:16:54 +02:00
Hauke Heibel
f26c691678 Renamed internal helper functions from the Memory header. 2009-06-04 17:25:15 +02:00
Hauke Heibel
5f04f8eb6b Fixes #9. Thanks to the (unknown) bug contributor. 2009-06-04 09:11:35 +02:00
Hauke Heibel
6530c8f5b4 A much simplified version of the earlier commit introducing way fewer changes compared to changeset f292d2352e
.
The reason of the previous commit was incorrect. The smart pointers issues were actually a result of issue 9.
2009-06-03 22:22:15 +02:00
Hauke Heibel
71e5cbcbc4 Added specializations for DontAlign when using Dynamic matrices.
This allows users to store Matrices in smart pointers without the
need for a specialized allocator/de-allocator.
2009-06-03 16:47:38 +02:00
Mark Borgerding
1c54340174 more work on ei_fftw_impl 2009-05-31 15:44:57 -04:00
Mark Borgerding
1fd6dfe428 added ei_fftw_impl 2009-05-30 17:55:47 -04:00
Hauke Heibel
f292d2352e Relaxed checks againts _MaxRows and _MaxCols in Matrix::_check_template_params(). 2009-05-29 09:09:48 +02:00
Mark Borgerding
f13e000b45 various comment changes 2009-05-27 21:32:42 -04:00
Benoit Jacob
ee92009fd8 make Umeyama, and its unit-test, work for me on gcc 4.3 2009-05-27 23:10:24 +02:00
Benoit Jacob
86be59124d fix the static assert checking the size template parameters. 2009-05-27 23:07:29 +02:00
Hauke Heibel
4d1e492c00 * Umeyama has now similar performance for RowMajor and ColMajor layouts.
* Fixed a bug in umeyama for fixed size matrices.
* Fixed the umeyama unit test for fixed size matrices.
* Added XprHelper::ei_plain_matrix_type_row_major.
2009-05-27 19:24:05 +02:00
Ingmar Vanhassel
7a7a3f3570 Fix out of source build 2009-05-27 17:36:46 +02:00
Hauke Heibel
db5647abae Added Umeyama implementation. 2009-05-26 19:22:25 +02:00
Mark Borgerding
09b4733255 added real-optimized inverse FFT (NFFT must be multiple of 4) 2009-05-25 23:52:21 -04:00
Mark Borgerding
03ed6f9bfb refactored ei_kissfft_impl to maintain a cache of cpx fft plans 2009-05-25 23:06:49 -04:00
Mark Borgerding
210092d16c changed name from simple_fft_traits to ei_kissfft_impl 2009-05-25 20:35:24 -04:00
Mark Borgerding
326ea77390 added FFT inverse complex-to-scalar interface (not yet optimized) 2009-05-23 22:50:07 -04:00
Mark Borgerding
3047988172 scalar forward FFT optimized for even size, converts to cpx for odd 2009-05-23 12:50:07 -04:00
Mark Borgerding
9c0fcd0f62 started real optimization, added benchmark for FFT 2009-05-23 10:09:48 -04:00
Gael Guennebaud
9d5728c511 fix #4
and also improve performance of Tridiag::diag/subDiag at the same time
2009-05-23 13:31:20 +00:00
Mark Borgerding
8b4afe3deb added non-optimized real forward fft (no inverse yet) 2009-05-22 22:37:59 -04:00
Benoit Jacob
42848498aa fixes #5 : freebsd really has aligned malloc 2009-05-22 23:54:52 +02:00
Benoit Jacob
7667a93cbe merge 2009-05-22 20:31:26 +02:00
Benoit Jacob
6347b1db5b remove sentence "Eigen itself is part of the KDE project."
it never made very precise sense. but now does it still make any?
2009-05-22 20:25:33 +02:00
Thomas Capricelli
0ed7c2f6d7 fix typo 2009-05-22 19:46:29 +02:00
Hauke Heibel
c7303a876f Oops, here the actual LLT and LDLT patch. 2009-05-22 15:58:20 +02:00
Hauke Heibel
0523b64fe9 Eigensolver decomposition interface unification.
Added default ctor and public compute method as
well as safe-guards against uninitialized usage.
Added unit tests for the safe-guards.
2009-05-22 14:27:58 +02:00
Hauke Heibel
7435d5c079 LLT and LDLT decomposition interface unification.
Added default ctor and public compute method as
well as safe-guards against uninitialized usage.
Added unit tests for the safe-guards.
2009-05-22 14:27:58 +02:00
Hauke Heibel
2c247fc8a8 LU and PartialLU decomposition interface unification.
Added default ctor and public compute method as well
as safe-guards against uninitialized usage.
Added unit tests for the safe-guards.
2009-05-22 14:27:58 +02:00
Hauke Heibel
5c5789cf0f QR and SVD decomposition interface unification.
Added default ctor and public compute method as
well as safe-guards against uninitialized usage.
Added unit tests for the safe-guards.
2009-05-22 14:27:58 +02:00
Benoit Jacob
c7baddb132 add internal comment (mostly a pretext to test the eigen-commits list) 2009-05-20 16:54:40 +02:00
Gael Guennebaud
dd45c4805c * add a writable generic coeff wise expression (CwiseUnaryView)
* add writable .real() and .imag() functions
2009-05-20 15:41:23 +02:00
Gael Guennebaud
6ecd02d7ec merge 2009-05-20 00:05:28 +02:00
Gael Guennebaud
56aad5aafb * add a FindEigen2.cmake file for reference
* parse the version number from the Macro.h header file
2009-05-20 00:04:08 +02:00
Benoit Jacob
a697cb4094 fix comments (old comments that were copied from LU) 2009-05-19 21:54:29 +02:00
Rhys Ulerich
066acca179 Added pkgconfig support 2009-05-19 11:48:50 -05:00
Gael Guennebaud
65181df1f9 update CTestConfig file for my.cdash.org 2009-05-19 10:21:24 +02:00
Gael Guennebaud
93123bc021 merge 2009-05-19 09:41:27 +02:00
Gael Guennebaud
510029f2bc * optimize sum() for sparse matrices and vectors
* fix the row()/col() functions of some InnerVector
2009-05-19 09:40:00 +02:00
Gael Guennebaud
f47c4b5da8 update cdash testsuite file to use mercurial 2009-05-19 09:24:22 +02:00
Mark Borgerding
68cad98bc9 indent level change 2009-05-19 00:34:38 -04:00
Mark Borgerding
be1b2ad4ec removed unused code 2009-05-19 00:26:19 -04:00
Mark Borgerding
92ca9fc032 initial pass of FFT module -- includes complex 1-d case only 2009-05-19 00:21:04 -04:00
Jitse Niesen
72f66d717d Evaluate argument of matrix exponential only once. 2009-05-18 23:14:53 +01:00
Gael Guennebaud
b83d9b48fa fix compilation with ICC 2009-05-18 18:26:45 +02:00
Gael Guennebaud
c8629e12f4 fix #3, remove inline keywords in QtAlignedMalloc (MSVC fix) 2009-05-18 18:09:21 +02:00
Gael Guennebaud
e186728867 fix #1 : need to nest by value the affine part in homogeneous product 2009-05-18 17:55:50 +02:00
Gael Guennebaud
e0832d5d93 fix bug reported by Moritz Lenz about random setter 2009-05-18 17:26:01 +02:00
Jitse Niesen
e3d64cb418 Fix compilation error in createRandomMatrixOfRank() 2009-05-17 21:17:45 +01:00
Hauke Heibel
6358c12998 * introduced method createRandomMatrixOfRank (R = U*D*V where U,V unitary, D r-by-c diag. with rank non-zero values)
* switched lu/qr tests to be using createRandomMatrixOfRank
* removed unused methods doSomeRankPreservingOperations
* removed NOTE about doSomeRankPreservingOperations
2009-05-17 16:07:12 +02:00
Benoit Jacob
934d6b4749 fix #2, bug in Diagonal::MaxRowsAtCompileTime when Index==Dynamic 2009-05-17 16:00:56 +02:00
Hauke Heibel
6ea7cbdc87 * added missing project definition (see doc of add_subdirectory and EXCLUDE_FROM_ALL) to fix a win build issue
* commented out non-existing unsupported-snippets and -examples
2009-05-17 12:12:39 +02:00
Thomas Capricelli
36c9c2597f Added tag after-hg-migration for changeset cd6c258f44 2009-05-16 17:23:50 +02:00
Thomas Capricelli
cd6c258f44 Fix a previous mistake in moving the 2.0-beta5 in svn for some last-minute
fixes.
2009-05-16 17:23:42 +02:00
Thomas Capricelli
bd9c32e2f1 Remove this old file. It was stalling in history because of a bug in svn,
which did not prevent the commit (svn r722564) to 'svn copy' a directory
called 'Core/' on top of an existing file 'Core'

see http://websvn.kde.org/?view=rev&revision=722564
2009-05-16 17:20:44 +02:00
convert-repo
e0554752d8 update tags 2009-05-16 14:05:54 +00:00
Benoit Jacob
dd390470e1 simplification (no reason anymore to write that in that convoluted way) 2009-05-15 16:05:45 +00:00
Benoit Jacob
5ee9f1a705 argh, forgot to re-add the throw() 2009-05-15 15:54:52 +00:00
Benoit Jacob
126284d08b * fix bugs in EigenTesting.cmake: it didn't work with -DEIGEN_NO_ASSERTION_CHECKING=ON
* only try...catch if exceptions are enabled
2009-05-15 15:53:26 +00:00
Benoit Jacob
7c14e1eac4 add partial-pivoting LU decomposition
the name 'PartialLU' is not meant to be definitive!
make inverse() and determinant() use it, so it's *almost* considered
well tested.
2009-05-13 02:02:22 +00:00
Gael Guennebaud
877c3c00a2 enable testing of complex numbers for taucs 2009-05-12 13:43:40 +00:00
Gael Guennebaud
159c99a288 fix adolc unit test for dynamic sizes 2009-05-12 07:38:46 +00:00
Gael Guennebaud
f5b5571a5a compilation fixes 2009-05-12 07:32:34 +00:00
Gael Guennebaud
9b256d997e various minor updates of some unit tests 2009-05-11 11:09:41 +00:00
Gael Guennebaud
6a4e94f349 bugfix from Jens Mueller (s/RowMajor/IsRowMajor) 2009-05-11 10:59:27 +00:00
Benoit Jacob
9afd1324fd constant Diagonal ---> DiagonalBits
introduce ei_is_diagonal to check for it
DiagonalCoeffs ---> Diagonal and allow Index to by Dynamic
-> add MatrixBase::diagonal(int) with unittest and doc
2009-05-10 16:24:39 +00:00
Benoit Jacob
eac79b6d2e CREDIT Hauke Heibel, fix MSVC warnings 2009-05-09 03:41:17 +00:00
Benoit Jacob
3b79d99f71 *make coeff() return a const reference (required with the recent change with CoeffReturnType)
*fix a unused variable warning
2009-05-09 03:39:31 +00:00
Benoit Jacob
c500415e18 result of our experiments with LU tuning: implement very simple formula, that
turns out to be similar to Higham's formula already in use in LDLt
2009-05-07 20:35:26 +00:00
Gael Guennebaud
b6c76c30cd apply patch from Hauke Heibel cleaning overloaded operator new/detete 2009-05-07 20:33:48 +00:00
Benoit Jacob
47fc3858b9 oops, didn't want to commit that 2009-05-07 18:40:06 +00:00
Benoit Jacob
c8a22dbc08 CREDIT Hauke Heibel, more std::vector::insert fixes 2009-05-07 18:38:07 +00:00
Benoit Jacob
159ab4a043 CREDIT Hauke Heibel, windows compatibility fixes in MatrixExponential 2009-05-07 18:11:49 +00:00
Gael Guennebaud
7080282a6d forgot a svn add CMakeLists.txt 2009-05-07 14:49:56 +00:00
Gael Guennebaud
6dffdca123 fix realloc when initial size was 0 (bug reported by Jens Mueller) 2009-05-07 13:13:42 +00:00
Benoit Jacob
4f0af00e51 *add missing overloads of setZero, etc... that were mentioned in the tutorial
--->they go into Matrix as they resize.
*add isConstant() alias to isApproxToConstant()
*extend unit-test
*change an assert into a static assert
2009-05-06 21:40:24 +00:00
Benoit Jacob
0c0d38272e add copyright on two public headers that are not so trivial... 2009-05-06 15:48:28 +00:00
Benoit Jacob
e1abffa513 add missing function, thanks to Hauke Heibel 2009-05-06 13:33:35 +00:00
Gael Guennebaud
3361ad4589 one more gcc 3.3 fix 2009-05-06 10:51:46 +00:00
Gael Guennebaud
db079f3a8c fix internal error with gcc 3.3 (all tests are now ok with 3.3 !) 2009-05-06 09:37:30 +00:00
Gael Guennebaud
1e286464ab * compilation fixes for gcc 3.3
* test Part::swap
2009-05-06 08:43:38 +00:00
Gael Guennebaud
23f073625d add -Wextra only if compiler supports it 2009-05-06 08:15:54 +00:00
Benoit Jacob
834eb5bfc8 new unsupported module by Jitse Niesen: matrix exponential 2009-05-05 20:46:55 +00:00
Benoit Jacob
66f059b99d remove unused member remean that was just initialized 2009-05-05 17:29:44 +00:00
Benoit Jacob
46e1162a39 reimplement linearRegression on top of fitHyperplane which is much better 2009-05-05 17:15:35 +00:00
Benoit Jacob
2b2f0c0220 fix linearRegression, fix doc, add unit test (it was untested since the change
making fitHyperplane no longer use it)
2009-05-05 16:50:58 +00:00
Gael Guennebaud
5b364a68cb oops 2009-05-04 14:53:21 +00:00
Gael Guennebaud
2829314284 new simplified API to fill sparse matrices (the old functions are
deprecated). Basically there are now only 2 functions to set a
coefficient:
1) mat.coeffRef(row,col) = value;
2) mat.insert(row,col) = value;
coeffRef has no limitation, insert assumes the coeff has not already
been set, and raises an assert otherwise.
In addition I added a much lower level, but more efficient filling
mechanism for
internal use only.
2009-05-04 14:25:12 +00:00
Thomas Capricelli
ddb6e96d48 fix warnings with recent gcc 2009-05-04 13:55:21 +00:00
Benoit Jacob
dec09a618d fix warning, unused variable dummy 2009-05-04 13:01:23 +00:00
Benoit Jacob
b60571a193 fix warnings with unused static functions 2009-05-04 12:49:56 +00:00
Benoit Jacob
8aa8854bbf fix SSE2 detection on win64, reported by 'kajala' 2009-05-04 12:13:37 +00:00
Gael Guennebaud
c25fc50d54 add an AlignedVector3 module suitable for vectorization of 3D vectors 2009-05-03 17:19:19 +00:00
Gael Guennebaud
469b8aa380 "forgot to commit the required changes in stdvector unit test" 2009-05-03 15:39:37 +00:00
Benoit Jacob
95bda5e6ab let the user disable alignment altogether by #defining EIGEN_DONT_ALIGN.
Until now, the user had to edit the source code to do that.
Internally, add EIGEN_ALIGN that takes into account both EIGEN_DONT_ALIGN.and
EIGEN_ARCH_WANTS_ALIGNMENT. From now on, only EIGEN_ALIGN should be used to
test whether we want to align.
2009-05-03 13:50:56 +00:00
Gael Guennebaud
facee57b8d add auto transposition for vectors 2009-04-30 12:09:45 +00:00
Gael Guennebaud
7029ed6b88 ok, this time cast should really work ; sorry for the noise 2009-04-29 17:39:39 +00:00
Gael Guennebaud
428a12902a fixed my mistake in cast 2009-04-29 17:05:19 +00:00
Benoit Jacob
746079f75d gni, forgot to call the new subtest 2009-04-29 17:01:10 +00:00
Gael Guennebaud
9e9e99a42e casting to the same type no longer generates a CwiseUnaryOp 2009-04-29 14:57:18 +00:00
Benoit Jacob
8b1e7c2792 add cast<>() tests. including a vectorization_logic test that currently fails (casting to same type should not prevent vectorization) 2009-04-29 14:51:19 +00:00
Gael Guennebaud
e722f55382 fix the Matrix(int,int)/vector 2D ctors issue so that we really
have a Matrix(Scalar,Scalar) ctor. (useful for std::complex, user
defined types, etc.
2009-04-24 14:38:40 +00:00
Benoit Jacob
32e9801890 CREDIT Ross Smith: fix posix_memalign detection 2009-04-24 13:26:36 +00:00
Gael Guennebaud
e201091d89 remove unsupported/doc from make's "all" target 2009-04-23 12:22:10 +00:00
Gael Guennebaud
acb32c69d4 * update BVH to explicitely use aligned_allocator
* fix warning in StdVector
2009-04-23 11:33:36 +00:00
Gael Guennebaud
c7bb7436f9 make the ei_p* math functions overloads instead of template
specializations
2009-04-22 21:35:50 +00:00
Gael Guennebaud
e0904a70ce update STL vector doc 2009-04-22 21:29:42 +00:00
Gael Guennebaud
6f6b5ad016 add a generic version of std::vector::resize for other stl
implementations
2009-04-21 21:40:33 +00:00
Gael Guennebaud
2697877fac std::vector now explicitely requires the use of Eigen::aligned_allocator
CREDIT Hauke Heibel
2009-04-21 21:30:38 +00:00
Gael Guennebaud
c5c384cf06 add missing vector ctor reported by Markus Moll on the ML 2009-04-21 11:52:25 +00:00
Gael Guennebaud
5e5bac52d7 this should fix the linking issue with StdVector without any user
changes... I cross my fingers...
2009-04-21 11:44:58 +00:00
Gael Guennebaud
4efcc14b91 fix ctor issues with ei_workaround_msvc_std_vector 2009-04-21 08:12:07 +00:00
Christian Ehrlicher
b14d1139df not compilable with msvc :( 2009-04-15 17:13:23 +00:00
Gael Guennebaud
c744960984 patch from Ilya Baran: This small patch fixes a potential initialization
bug in BVAlgorithms and slightly corrects the BVH doc.
2009-04-15 05:54:07 +00:00
Benoit Jacob
6ee4eb94fb fix the 4x4 inverse -- unit test passes again 2009-04-14 13:42:23 +00:00
Benoit Jacob
2bb1c9e8dc finally commit Rohit's work as the start of a new (currently
unsupported) module, MoreVectorization.

CCMAIL:rpg.314@gmail.com
2009-04-14 13:15:53 +00:00
Gael Guennebaud
804a239d30 patch from Moritz Lenz to allow solving transposed problem with superlu 2009-04-10 19:54:43 +00:00
Gael Guennebaud
fb3078fb62 fix memory leak in superlu backend 2009-04-10 18:49:38 +00:00
Gael Guennebaud
7254201632 bugfix when the diagonal is not stored and assumed to be 1 2009-04-10 18:13:37 +00:00
Gael Guennebaud
22edf77470 add a 4x4 inverse case which is not handled by the current
ei_compute_inverse_in_size4_case (reported by mikola on IRC)
2009-04-09 21:55:29 +00:00
Gael Guennebaud
ea41a18b80 clean asm comments 2009-04-09 21:29:31 +00:00
Gael Guennebaud
d78eb02627 add aligned_allocator operator == and != as suggested by Hauke Heibel 2009-04-09 21:22:02 +00:00
Benoit Jacob
0c99de5a17 more patches from Hauke Heibel: compilation/warning fixes from VC++ 2009-04-09 17:19:17 +00:00
Benoit Jacob
e6332cba4b forward-port r951449: patch by Hauke Heibel: compile fix with VS 9 2009-04-09 12:06:13 +00:00
Gael Guennebaud
e8329f9f45 relicence Julien Pommier's SSE code to Eigen's licenses 2009-04-09 06:03:51 +00:00
Gael Guennebaud
aabca5a44f stupid typo 2009-04-06 13:35:48 +00:00
Benoit Jacob
502bf4a81d * fix the binary bloat issue, Rohit's idea was the good one
* a few dox fixes (alloc routines do return 0 on error) and forgot to update version number in CMakeLists
2009-04-06 13:33:42 +00:00
Gael Guennebaud
38f501a596 fix computation of aligned_bit (has been broken by the change of
AutoAlign/DontAlign)
2009-04-05 17:34:59 +00:00
Gael Guennebaud
5b1d0cebc5 sparse module: new API proposal for triangular solves and experimental
solver support with a sparse matrix as the rhs.
2009-04-05 16:30:10 +00:00
Jos van den Oever
5a628567b0 Compile fix. 2009-04-05 14:26:47 +00:00
Kenneth Frank Riddile
9a8096dd1d * fixed truncation warnings caused by MatrixBase::CoeffReturnType under MSVC 2009-04-03 20:19:07 +00:00
Gael Guennebaud
ff3a3209ca add an assertion in sparse LLT for invalid input matrix 2009-04-03 08:30:15 +00:00
Gael Guennebaud
adf5104bae oops, bad copy paste in ei_psqrt, thanks to Jitse Niesen 2009-04-02 06:29:05 +00:00
Benoit Jacob
40432c84b9 CwiseUnaryOp -> SparseCwiseUnaryOp 2009-04-01 14:47:56 +00:00
Gael Guennebaud
0170eb0dbe add an auto-diff module in unsupported. it is similar to adolc's forward
mode but the advantage of using Eigen's expression template to compute
the derivatives (unless you nest an AutoDiffScalar into an Eigen's
matrix).
2009-04-01 14:43:37 +00:00
Benoit Jacob
0f8e692b3f * Find SuperLU also when it is installed without a superlu/ prefix
* Some more CoeffReturnType changes
2009-04-01 14:07:38 +00:00
Benoit Jacob
113fc3a260 now if Derived has the DirectAccess flag, then MatrixBase<Derived>::coeff() const returns a const Scalar& and not a Scalar as before.
useful for people doing direct access. + 1 bugfix thanks to Patrick Mihelich, forgot a & in MapBase::coeff(int).
2009-04-01 00:39:56 +00:00
Benoit Jacob
2f45eeb0c6 More Cholesky fixes.
* Cholesky decs are NOT rank revealing so remove all the rank/isPositiveDefinite etc stuff.
* fix bug in LLT: s/return/continue/
* introduce machine_epsilon constants, they are actually needed for Higman's formula determining
  the cutoff in Cholesky. Btw fix the page reference to his book (chat with Keir).
* solve methods always return true, since this isn't a rank revealing dec. Actually... they already did always return true!! Now it's explicit.
* updated dox and unit-test
2009-04-01 00:21:16 +00:00
Benoit Jacob
8e2b191acf fix typo found by noir.sender from KDE forums 2009-03-31 17:00:30 +00:00
Benoit Jacob
1e6097a810 fix mistake in static assertion, patch by Markus Moll. 2009-03-31 16:07:12 +00:00
Benoit Jacob
bf596d0b3a add adjointInPlace() and add documentation warnings on adjoint() and transpose() about aliasing effects. 2009-03-31 13:55:40 +00:00
Benoit Jacob
a1ba995f05 Many improvements in LLT and LDLT:
* in LDLT, support the negative semidefinite case
* fix bad floating-point comparisons, improves greatly the accuracy of methods like
  isPositiveDefinite() and rank()
* simplifications
* identify (but not resolve) bug: claim that only triangular part is used, is inaccurate
* expanded unit-tests
2009-03-30 21:45:45 +00:00
Gael Guennebaud
df9dfa1455 fix superLU backend: missing operator= 2009-03-27 19:25:22 +00:00
Gael Guennebaud
e9f6167485 make special ei_p functions static to avoid linking issues (they are too
complex to be inlined)
2009-03-27 14:55:46 +00:00
Gael Guennebaud
49fc1e3e84 add vectorization of sqrt for float 2009-03-27 14:41:46 +00:00
Gael Guennebaud
3499f6eccd fix Taucs support (it appears Taucs does not return sorted matrices) 2009-03-26 17:11:43 +00:00
Benoit Jacob
1b7b538e05 The ABI break:
* set AutoAlign=0, DontAlign!=0
* set Dynamic=33331
* add check on fixed sizes
* bump version to 2.0.52
2009-03-26 16:30:54 +00:00
Gael Guennebaud
ce5669dbf9 * enable vectorization of sin, cos, etc. by default with an option to
disable them (-DEIGEN_FAST_MATH=0)
* add a specialization of MatrixBase::operator*(RealScalar) for fast
  "matrix of complex" times scalar products (even more useful for
  autodiff scalar types)
2009-03-26 12:50:24 +00:00
Gael Guennebaud
62de40f8bb oops forgot to include a file in previous commit (I had other local
changes I did not want to commit yet...)
2009-03-26 07:10:59 +00:00
Gael Guennebaud
a22ef7e1f3 for some reason passing the argument by const reference killed the perf
(in the packet version of sin, cos, exp, lop), so let's pass them by
value. Also, improve the perf of ei_plog by reducing dependencies.
2009-03-25 18:33:36 +00:00
Gael Guennebaud
17860e578c add SSE2 versions of sin, cos, log, exp using code from Julien
Pommier. They are for float only, and they return exactly the same
result as the standard versions in about 90% of the cases. Otherwise the max error
is below 1e-7. However, for very large values (>1e3) the accuracy of sin and cos
slighlty decrease. They are about 3 or 4 times faster than 4 calls to their respective
standard versions. So, is it ok to enable them by default in their respective functors ?
2009-03-25 12:26:13 +00:00
Andrew Coles
64fbd93cd9 As values may be used uninitialised, they have now been given
sensible defaults; or, in other words, if worse comes to worst,
we'll get a guaranteed segfault rather than a heisenburg.
2009-03-23 21:15:33 +00:00
Gael Guennebaud
70c0174bf9 * allows fixed size matrix with size==0 (via a specialization of
MatrixStorage returning a null pointer). For instance this is very
  useful to make Tridiagonalization compile for 1x1 matrices
* fix LLT and eigensolver for 1x1 matrix
2009-03-23 14:44:44 +00:00
Gael Guennebaud
f4cf5e9b26 split and extend eigen-solver tests 2009-03-23 14:38:59 +00:00
Konstantinos A. Margaritis
fe00e864a1 ei_pnegate implemented for AltiVec 2009-03-20 17:26:50 +00:00
Gael Guennebaud
fbf415c547 add vectorization of unary operator-() (the AltiVec version is probably
broken)
2009-03-20 10:03:24 +00:00
Gael Guennebaud
4bb5221d22 Add BVH module in unsupported (patch from Ilya Baran)
(I thought I committed it a week ago but it seems the command failed)
2009-03-18 20:06:06 +00:00
Gael Guennebaud
3d385ae968 angle-axis doc: make it more clear the axis must be normalized 2009-03-18 19:38:55 +00:00
Gael Guennebaud
dcf49e5a28 more MSVC fixes: restrict keywords (sorry for all these commits) 2009-03-17 13:32:26 +00:00
Gael Guennebaud
718af05517 more MSVC fixes (asm comments...) 2009-03-17 13:25:26 +00:00
Gael Guennebaud
497d77b08c fix compilation MSVC 2009-03-17 13:18:53 +00:00
Gael Guennebaud
312994fa98 opengl demo: add aligned operator new where appropriate and remove my
mess...
2009-03-13 13:17:19 +00:00
Gael Guennebaud
c6264d9b7e add affine * homogeneous vector for backward compatibility (e.g.,
kgllib)
2009-03-11 14:32:03 +00:00
Gael Guennebaud
02e97ac0ae minor changes in AlignedBox needed for BVH module 2009-03-11 14:21:55 +00:00
Gael Guennebaud
b8f46090ff add optimized cross3 function (code from Rohit Garg) 2009-03-11 14:20:36 +00:00
Gael Guennebaud
3298320007 fix doxygen generation of unsupported modules 2009-03-11 13:11:38 +00:00
Gael Guennebaud
f697ea6d30 fix a few compilation errors and warnings (ICC) 2009-03-11 08:45:53 +00:00
Gael Guennebaud
14691d6836 fix compilation with old, and future gcc 2009-03-10 11:55:50 +00:00
Gael Guennebaud
3e4307d8a8 compilation fix in MapBase 2009-03-10 09:06:38 +00:00
Gael Guennebaud
caa1ef7515 various BTL updates (disable Cholesky for MTL, add new plot settings,
etc)
2009-03-09 23:28:46 +00:00
Gael Guennebaud
8aa5aa269a add "slice vectorization" of redux (eg. m.block().minCoeff() is now
vectorized)
2009-03-09 23:16:39 +00:00
Gael Guennebaud
c087373968 because of a missing specialization, operator/(scalar) was not vectorized 2009-03-09 23:14:53 +00:00
Gael Guennebaud
db6c3d0197 fix MapBase's ForceAligned concept which was not working at all.... 2009-03-09 19:23:31 +00:00
Gael Guennebaud
3f80c68be5 add the vectorization of abs 2009-03-09 18:40:09 +00:00
Gael Guennebaud
bd8107c90c forgot to include a file in previous commit 2009-03-09 14:18:29 +00:00
Gael Guennebaud
8a424efb11 add an option to bench eigen without GCC's auto vec (might conflict with
Eigen's auto vec)
2009-03-09 14:16:05 +00:00
Gael Guennebaud
314aff875e fix warning in Tridiag 2009-03-09 10:41:37 +00:00
Gael Guennebaud
44f218988c add a small note in Transform doc. 2009-03-08 11:38:45 +00:00
Gael Guennebaud
3ac42fed94 big rework of the Transform class:
* add Projective and AffineCompact modes as an optional third template
  argument
* extend Transform::operator* to support more use cases
2009-03-08 11:35:30 +00:00
Gael Guennebaud
7718a8ed83 slight optimization of SSE base integer mul (thanks to Rohit Garg) 2009-03-08 10:14:07 +00:00
Jure Repinc
f9790a649c Install the newly added eigen2/Eigen/src/Geometry/arch/Geometry_SSE.h 2009-03-08 06:21:21 +00:00
Gael Guennebaud
e4f64ce098 add optimized quaternion * quaternion product specialization for
float/SSE using code from Rohit Garg
2009-03-07 13:52:44 +00:00
Gael Guennebaud
6f95270ede significantly reduce the default stack allocation limit which was much
too high
2009-03-06 16:52:43 +00:00
Gael Guennebaud
2c78ca62a6 patch from Stjepan Rajko (MSVC fix in RotationBase) 2009-03-06 11:45:39 +00:00
Andrew Coles
093e3cd5b5 Commented out duplicate definition of TransformTraits - was causing
compile-time errors.
2009-03-05 22:35:06 +00:00
Gael Guennebaud
fa9f7708d4 add efficient matrix product specializations for Homogeneous 2009-03-05 16:40:56 +00:00
Gael Guennebaud
31332fca0b remove bad #include of SelfadjointRank2Update.h 2009-03-05 10:29:20 +00:00
Gael Guennebaud
0be89a4796 big addons:
* add Homogeneous expression for vector and set of vectors (aka matrix)
  => the next step will be to overload operator*
* add homogeneous normalization (again for vector and set of vectors)
* add a Replicate expression (with uni-directional replication
  facilities)
=> for all of them I'll add examples once we agree on the API
* fix gcc-4.4 warnings
* rename reverse.cpp array_reverse.cpp
2009-03-05 10:25:22 +00:00
Gael Guennebaud
d710ccd41e BTL: add syr2 action 2009-03-05 08:15:32 +00:00
Gael Guennebaud
a72ff5abc1 BTL: - patch from Victor (add ACML support)
- fix overflow issues
2009-03-05 08:11:47 +00:00
Gael Guennebaud
6a26506341 add ReturnByValue pseudo expression for in-place evaluation with a
return-by-value API style (will soon use it for the transform products)
2009-03-04 13:00:00 +00:00
Gael Guennebaud
45136ac3b6 various update of of BTL 2009-03-04 07:21:17 +00:00
Gael Guennebaud
3288e9e168 add much faster versions of unaligned stores (and slightly faster
unaligned loads)
2009-03-03 14:01:30 +00:00
Gael Guennebaud
c4601314be cleaned Tridiagonalization impl, with improved performance 2009-03-02 15:07:39 +00:00
Gael Guennebaud
ed134a0ce5 performance improvement: rewrite of the matrix-matrix product following
Goto's paper => x1.4 speedup with more consistent perf results
2009-03-02 13:15:15 +00:00
Gael Guennebaud
8ed186b9ab improve WIP new matrix product 2009-02-27 17:18:52 +00:00
Gael Guennebaud
40774c625e add a proof of concept autodiff jacobian helper class based on adolc
with unit test and FindAdolc cmake module
2009-02-27 16:19:13 +00:00
Gael Guennebaud
170128770a compilation fix + test orho methods for complex 2009-02-26 10:09:23 +00:00
Gael Guennebaud
91af389a9a fix unitOrthogonal() for size > 3 2009-02-25 09:23:09 +00:00
Laurent Montel
2d6d14a3d3 Add COMPONENT Devel 2009-02-23 07:50:56 +00:00
Laurent Montel
8e7c4df0db Fix install header 2009-02-22 10:28:31 +00:00
Gael Guennebaud
de014efdaf * split CacheFriendlyProduct into multiple smaller files
* add an efficient selfadjoint * vector implementation (= blas symv)
  perf are inbetween MKL and GOTO
  => the interface is still missing (have to be rethougth)
2009-02-21 20:20:38 +00:00
Gael Guennebaud
3d86dcf473 oops, got confused by the preprocessor directives around
posix_memalign...
2009-02-21 16:35:57 +00:00
Gael Guennebaud
7c4f9ecf0c fix posix_memalign return value warning 2009-02-21 16:23:18 +00:00
Benoit Jacob
177500f37e fix typo found by markusfroeb (forum) 2009-02-21 14:30:49 +00:00
Daniel Gomez Ferro
032880074e Added new product implementation.
Just works for square, power of 2 matrices of floats.
2009-02-20 22:23:25 +00:00
Gael Guennebaud
7485aa6d57 add symv bench 2009-02-20 21:05:19 +00:00
Keir Mierle
22b9de1849 Fix some formatting in quick ref. Add references to headers. 2009-02-19 16:46:35 +00:00
Gael Guennebaud
e2ee7a6a58 increase version number for step 2009-02-19 15:46:10 +00:00
Gael Guennebaud
752d95c20e eventually c++ does not provide any optimized pow(int,int) function,
so here you go :) (should also fix Timothy's troubles)
2009-02-18 18:24:31 +00:00
Gael Guennebaud
747d83a05a add size, rows, cols, (), (,) functions in ASCII ref 2009-02-18 16:35:16 +00:00
Gael Guennebaud
eb2cc8f502 patch from Jitse Niesen: fix ascii quick ref matlab operator ' 2009-02-18 16:24:15 +00:00
Gael Guennebaud
8f83b37b2a fix install of IterativeSolvers module 2009-02-18 13:11:29 +00:00
Gael Guennebaud
23f543ee5e add the ASCII quick reference made by Kier 2009-02-18 10:27:18 +00:00
Gael Guennebaud
21161d8bcf fix typo in FindTaucs.cmake 2009-02-17 10:34:17 +00:00
Gael Guennebaud
ee04c5c874 add tests showing bug in unitOrthogonal such that we don't forget it! 2009-02-17 09:57:32 +00:00
Gael Guennebaud
e6f1104b57 * fix Quaternion::setFromTwoVectors (thanks to "benv" from the forum)
* extend PartialRedux::cross() to any matrix sizes with automatic
  vectorization when possible
* unit tests: add "geo_" prefix to all unit tests related to the
  geometry module and start splitting the big "geometry.cpp" tests to
  multiple smaller ones (also include new tests)
2009-02-17 09:53:05 +00:00
Gael Guennebaud
67b4fab4e3 fix assertion issue in slice vectorization 2009-02-16 10:17:21 +00:00
Gael Guennebaud
c5245a3388 update vectorization_logic unit test wrt previous sum/redux change 2009-02-13 08:45:19 +00:00
Konstantinos A. Margaritis
349557db9a no reason for 3 vec_mins, 2 are enough apparently in ei_predux_min 2009-02-12 22:03:30 +00:00
Konstantinos A. Margaritis
ad2bf14dbb modified ei_predux_min/max to actually use altivec instructions 2009-02-12 21:58:44 +00:00
Gael Guennebaud
3b12f48aa3 compilation fix for SuperLU 3.1 2009-02-12 17:50:51 +00:00
Gael Guennebaud
20a8bb96eb fix m = m*m with m sparse (gug found by Frederik Heinz) 2009-02-12 15:57:13 +00:00
Gael Guennebaud
59a1ed0932 fix bug in MapBase found by myguel 2009-02-12 15:29:20 +00:00
Gael Guennebaud
51c991af45 * exit Sum.h, exit Prod.h, welcome vectorization of redux() !
* add vectorization for minCoeff and maxCoeff
2009-02-12 15:18:59 +00:00
Gael Guennebaud
dc97d483fd update of the Array module doc 2009-02-12 07:55:35 +00:00
Gael Guennebaud
deb6254702 some ICC fixes 2009-02-12 07:55:03 +00:00
Gael Guennebaud
7954f7709a add ei_predux_mul for AltiVec 2009-02-10 18:26:59 +00:00
Gael Guennebaud
cbbc6d940b * add ei_predux_mul internal function
* apply Ricard Marxer's prod() patch with fixes for the vectorized path
2009-02-10 18:06:05 +00:00
Gael Guennebaud
a0cc5fba0a fix ICC internal compilation error 2009-02-10 14:15:32 +00:00
Gael Guennebaud
40ad661183 added an experimental IterativeSolvers module (currently in unsupported)
with a constrained conjugate gradient algorithm adapted from GMM++/ITL.
This algorithm is needed for Step.
2009-02-10 10:02:41 +00:00
Gael Guennebaud
e75bef9523 various minor fixes in Sparse module 2009-02-10 10:00:00 +00:00
Gael Guennebaud
169696a078 fix doxygen \ingroup for the array module 2009-02-09 10:13:06 +00:00
Gael Guennebaud
9c14d20656 add select snippet 2009-02-09 10:01:42 +00:00
Gael Guennebaud
a9688f0b71 - add diagonal * sparse product as an expression
- split sparse_basic unit test
- various fixes in sparse module
2009-02-09 09:59:30 +00:00
Gael Guennebaud
e0be020622 add DiagonalMatrix setZero and resize functions 2009-02-09 09:55:54 +00:00
Gael Guennebaud
666ade0c93 add "remap" snippet using placement new 2009-02-09 09:54:48 +00:00
Thomas Capricelli
5b4c3b21f3 documentation about inheriting from Eigen::Matrix 2009-02-08 22:36:28 +00:00
Konstantinos A. Margaritis
15e40b1099 fixed preserve_mask definition for AltiVec (needed __vector keyword) 2009-02-08 18:43:57 +00:00
Konstantinos A. Margaritis
505bdbb9ef should be __powerpc__ instead of __ppc__ 2009-02-08 18:22:34 +00:00
Gael Guennebaud
d8b7283a98 remove remaining debug stuff in Reverse.h 2009-02-08 12:56:47 +00:00
Vincenzo Di Massa
a385de080d fix build 2009-02-07 16:14:46 +00:00
Gael Guennebaud
6c4b6c2da8 forgot to commit the deletion of StdVector directory 2009-02-07 15:47:13 +00:00
Gael Guennebaud
17fd619430 more fixes in StdVector, sorry for the noise 2009-02-07 12:51:58 +00:00
Gael Guennebaud
365ec0744c disable vector::resize() workaround for gcc < 4.1 (they already use a const
reference)
2009-02-07 12:46:04 +00:00
Gael Guennebaud
671398372b arf... s/_MSVC_VER/_MSC_VER 2009-02-07 11:49:33 +00:00
Gael Guennebaud
4dd2efa113 little fix in new StdVector 2009-02-07 11:30:19 +00:00
Gael Guennebaud
3009d79a1f * allow Matrix to be resized to 0 (solve a lot of troubles with
some containers)
* new workaround for std::vector which is supposed to work for any
  classes having EIGEN_MAKE_ALIGNED_OPERATOR_NEW as discussed on ML
2009-02-07 11:16:15 +00:00
Gael Guennebaud
24808dc090 force the use of debug version of QtCore unless it is not available 2009-02-06 21:50:18 +00:00
Gael Guennebaud
1c24f5bbc5 eventually MSVC does not like my /O2 flags (incompatibility with other option set by default) 2009-02-06 15:29:40 +00:00
Gael Guennebaud
19b035ee11 s/cholesky/llt in precompiled lib and BTL 2009-02-06 14:01:01 +00:00
Gael Guennebaud
cc90495e30 add bench_reverse, draft of a reverse vectorization for AltiVec, make
global Scaling function static
2009-02-06 13:28:55 +00:00
Gael Guennebaud
f5d96df800 Add vectorization of Reverse (was more tricky than I thought) and
simplify the index based functions
2009-02-06 12:40:38 +00:00
Gael Guennebaud
4dc4ab3abb Reverse::coeff*(int) functions are for vector only 2009-02-06 09:13:04 +00:00
Gael Guennebaud
6fbca94803 apply Ricard patch for Reverse with minor modifications 2009-02-06 09:01:50 +00:00
Gael Guennebaud
dc97079905 add optimization flag for MSVC and heavy tests
remove unsupported namespace
2009-02-05 22:13:50 +00:00
Gael Guennebaud
a4487ef198 add snippet for sub/super diagonal
fix a few doc issues
2009-02-05 21:19:40 +00:00
Gael Guennebaud
e80f0b6c4e update doc of DiagonalCoeffs 2009-02-05 18:39:23 +00:00
Gael Guennebaud
910b387438 Add sub/super-diagonal expression (read/write) as a trivial extension of
DiagonalCoeffs. The current API is simply:
  m.diagonal<1>() => 1st super diagonal
  m.diagonal<-2>() => the 2nd sub diagonal
I'll add a code snippet once we agree on this API.
2009-02-05 18:37:21 +00:00
Gael Guennebaud
9637af5ecf undo an unecessary change in cache-friendly product made for MSVC 2009-02-05 11:37:57 +00:00
Gael Guennebaud
7c374394ee remove explicit fortran dependency in FindCholmod 2009-02-05 10:34:41 +00:00
Gael Guennebaud
8a6f38c638 forgot to commit changes in main CMakeLists.txt
(add unsupported folder)
2009-02-05 09:37:53 +00:00
Gael Guennebaud
da45184635 add custom FindBLAS FindLAPACK working for c++ compiler
fix issues in Cholmod/Taucs supports
2009-02-05 09:36:52 +00:00
Gael Guennebaud
1119f846cf fix various Taucs and Cholmod issues (they have not been tested for a while) 2009-02-04 22:14:09 +00:00
Gael Guennebaud
41f80b26cb bugfix in LDLt for size==1 2009-02-04 20:20:34 +00:00
Gael Guennebaud
5e6707d7f7 forgot to add EigenTesting.cmake file 2009-02-04 17:11:04 +00:00
Benoit Jacob
5d69c5102b oops, #ifdef instead of #if ---> bug 2009-02-04 16:57:28 +00:00
Benoit Jacob
f81479d392 forgot to update this unit test... 2009-02-04 16:55:38 +00:00
Benoit Jacob
93a089adc8 disable alignment altogether outside of the platforms which potentially have SSE or AltiVec
This should remove most portability issues to other platforms where data alignment issues (including
overloading operator new and new[]) can be tricky, and where data alignment is not needed in the first place.
2009-02-04 16:53:03 +00:00
Gael Guennebaud
c26dc9ab1b nothing interesting to see 2009-02-04 16:22:56 +00:00
Gael Guennebaud
82e0cbbac5 extend unsupported/README.txt file 2009-02-04 15:44:59 +00:00
Gael Guennebaud
95db32fcdc setup the unsupported directory structure.
The unsupported module documentation is automatically generated in:
  build/doc/unsupported/
with bidirectional cross references.
I leave a class Foo in AdolcForward module to illustrate the
cross-reference behavior. I will remove it in the next commit.
2009-02-04 15:37:00 +00:00
Gael Guennebaud
44a527dfa5 * classify and sort the doxygen "related pages"
by tweaking the filename and adding 2 categories:
   Troubleshooting and Advanced
* use the EXCLUDE_SYMBOLS to clean the class list
  (insteaded of a homemade bash script)
* remove the broken "exemple list"
* re-structure the unsupported directory as mentionned in the ML and
  integrate the doc as follow:
  - snippets of the unsupported directory are directly imported from the
    main snippets/CMakefile.txt (no need to duplicate code)
  - add a top level "Unsupported modules" group
  - unsupported modules have to defined their own sub group and nest it
    using \ingroup Unsupported_modules
  - then a pair of //@{ //@} will put everything in the submodule
  - this is just a proposal !
2009-02-04 09:44:44 +00:00
Gael Guennebaud
b0dd22cc72 update cholesky benchmark 2009-02-03 19:05:10 +00:00
Keir Mierle
b9a82be727 Add full pivoting to LDLT decomposition. 2009-02-03 17:50:35 +00:00
Gael Guennebaud
6c5868cc99 add a short unsupported/readme file 2009-02-03 09:02:55 +00:00
Gael Guennebaud
42fa03948c add unsupported/ directory with a first contribution from myself:
a header file providing support for adolc's adouble type in forward
mode. (adolc is an automatic differentiation library)
2009-02-03 08:34:09 +00:00
Keir Mierle
b4777379d4 Add Matrix::resizeLike(other) convenience function and test. 2009-02-03 01:43:59 +00:00
Benoit Jacob
bc9a276b78 call it "Eigen 2.0.50-unstable" to make things clear, and update EIGEN_MINOR_VERSION to 50 2009-02-02 17:15:01 +00:00
Benoit Jacob
61e45ed500 * label Cholesky and solveTriangular.* as experimental
* improve Experimental.dox
* update urls from /api/ to /dox/
2009-02-02 14:21:35 +00:00
Benoit Jacob
f3d5ba0c1f the BSD's don't have aligned malloc after all 2009-02-02 13:22:19 +00:00
Gael Guennebaud
42c4bc0ecf fix tutorial abs/abs2 (thanks to Keir) 2009-02-01 22:38:51 +00:00
Gael Guennebaud
4111316104 forgot to commit QR_solve snippet 2009-02-01 20:47:19 +00:00
Benoit Jacob
37cceeeaca add missing inline keywords 2009-01-30 23:08:47 +00:00
Gael Guennebaud
82e70fbcae fix duplicated geometry module in the doc 2009-01-29 23:10:16 +00:00
Gael Guennebaud
13d0a310fd fix MSVC internal compilation error 2009-01-29 22:49:24 +00:00
Gael Guennebaud
8e0ec3c62b reduce epsilon in QR 2009-01-29 16:11:46 +00:00
Gael Guennebaud
cf0857c44d fix MSVC stupid warnings 2009-01-29 09:45:25 +00:00
Gael Guennebaud
1752a3a677 more MSVC fixes, and more code factorization in Geometry module 2009-01-29 09:36:48 +00:00
Gael Guennebaud
36c8a64923 add MatrixBase::stableNorm() avoiding over/under-flow
using it in QR reduced the error of Keir test from 1e-12 to 1e-24 but
that's much more expensive !
2009-01-28 22:11:56 +00:00
Gael Guennebaud
42b237b83a * make sum and redux honor EvalBeforeNestingBit too
* fix MSVC issues (hopefully)
2009-01-28 21:09:08 +00:00
Gael Guennebaud
cc6159743d make dot() honor EvalBeforeNestingBit 2009-01-28 20:53:27 +00:00
Gael Guennebaud
dde729379a various updates in the (still messy) sparse benchmarks 2009-01-28 20:32:28 +00:00
Gael Guennebaud
9b594ab0fb fix overflow in sparse product 2009-01-28 18:21:38 +00:00
Benoit Jacob
9bc44094c5 add EIGEN_NO_AUTOMATIC_RESIZING
if defined, already initialized matrices won't be automatically resized in assignments
uninitialized matrices may still be initialized
2009-01-28 16:44:03 +00:00
Gael Guennebaud
1b194193ef Big change in DiagonalMatrix and Geometry/Scaling:
* previous DiagonalMatrix expression is now DiagonalMatrixWrapper
* DiagonalMatrix class is now for storage
* add the DiagonalMatrixBase class to factorize code of the
  two previous classes
* remove Scaling class (it is now a global function)
* add UniformScaling helper class
  (don't use it directly, use the Scaling function)
* add the Scaling global function to simplify the creation
  of scaling objects
There is still a lot to do, in particular about DiagonalProduct for which
the goal is to get rid of the "if()" in the coeff() function. At least
it is not worse than before ! Also need to uptade the tutorial and add more doc.
2009-01-28 16:26:06 +00:00
Gael Guennebaud
da555585e2 Patch from Frank fixing stupid MSVC internal crash 2009-01-28 12:52:26 +00:00
Gael Guennebaud
22bfc77124 move EIGEN_DEPRECATED to the begining of the function (pb with MSVC) 2009-01-28 12:48:19 +00:00
Gael Guennebaud
0f15a8d829 QR: add isInjective(), isSurjective(),
mark isFullRank() deprecated,
    add solve() (mix of Keir's patch and LU::solve())
=> there is big problem with complex which are not working
2009-01-28 09:45:53 +00:00
Gael Guennebaud
cf89d9371a LLT: makes the non positive definite test less strict, but we still need
something better.
2009-01-27 23:01:53 +00:00
Gael Guennebaud
8ce4503494 add support for read/write sub sets of inner vectors (sparse module) 2009-01-27 22:48:17 +00:00
Benoit Jacob
d384671793 now these tests succeed with 10,000 repeats 2009-01-27 20:47:12 +00:00
Gael Guennebaud
4ac8cabf8a fix my previous commit with EIGEN_EMPTY macro bug 2009-01-27 19:08:20 +00:00
Benoit Jacob
9b06e072a5 fix type mismatch caught by new static assert 2009-01-27 17:42:04 +00:00
Gael Guennebaud
d700343632 fix "empty macro arguments are undefined in ISO C90 and ISO C++98"
warning found by gcc-svn
2009-01-27 17:40:14 +00:00
1108 changed files with 148658 additions and 23371 deletions

3
.hgeol Normal file
View File

@@ -0,0 +1,3 @@
[patterns]
**.* = native
eigen_autoexp_part.dat = CRLF

32
.hgignore Normal file
View File

@@ -0,0 +1,32 @@
syntax: glob
qrc_*cxx
*.orig
*.pyc
*.diff
diff
*.save
save
*.old
*.gmo
*.qm
core
core.*
*.bak
*~
build*
*.moc.*
*.moc
ui_*
CMakeCache.txt
tags
.*.swp
activity.png
*.out
*.php*
*.log
*.orig
*.rej
log
patch
a
a.*

View File

@@ -1,102 +1,393 @@
project(Eigen)
set(EIGEN_VERSION_NUMBER "2.0-rc1")
#if the svnversion program is absent, this will leave the SVN_REVISION string empty,
#but won't stop CMake.
execute_process(COMMAND svnversion -n ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE EIGEN_SVNVERSION_OUTPUT)
#we only want EIGEN_SVN_REVISION if it is an actual revision number, not a string like "exported"
string(REGEX MATCH "^[0-9]+.*" EIGEN_SVN_REVISION "${EIGEN_SVNVERSION_OUTPUT}")
if(EIGEN_SVN_REVISION)
set(EIGEN_VERSION "${EIGEN_VERSION_NUMBER} (SVN revision ${EIGEN_SVN_REVISION})")
else(EIGEN_SVN_REVISION)
set(EIGEN_VERSION "${EIGEN_VERSION_NUMBER}")
endif(EIGEN_SVN_REVISION)
cmake_minimum_required(VERSION 2.6.2)
# guard against in-source builds
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. You may need to remove CMakeCache.txt. ")
endif()
# guard against bad build-type strings
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_tolower)
if( NOT cmake_build_type_tolower STREQUAL "debug"
AND NOT cmake_build_type_tolower STREQUAL "release"
AND NOT cmake_build_type_tolower STREQUAL "relwithdebinfo")
message(FATAL_ERROR "Unknown build type \"${CMAKE_BUILD_TYPE}\". Allowed values are Debug, Release, RelWithDebInfo (case-insensitive).")
endif()
#############################################################################
# retrieve version infomation #
#############################################################################
# automatically parse the version number
file(READ "${PROJECT_SOURCE_DIR}/Eigen/src/Core/util/Macros.h" _eigen_version_header)
string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen_world_version_match "${_eigen_version_header}")
set(EIGEN_WORLD_VERSION "${CMAKE_MATCH_1}")
string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen_major_version_match "${_eigen_version_header}")
set(EIGEN_MAJOR_VERSION "${CMAKE_MATCH_1}")
string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen_minor_version_match "${_eigen_version_header}")
set(EIGEN_MINOR_VERSION "${CMAKE_MATCH_1}")
set(EIGEN_VERSION_NUMBER ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})
# if the mercurial program is absent, this will leave the EIGEN_HG_CHANGESET string empty,
# but won't stop CMake.
execute_process(COMMAND hg tip -R ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE EIGEN_HGTIP_OUTPUT)
execute_process(COMMAND hg branch -R ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE EIGEN_BRANCH_OUTPUT)
# if this is the default (aka development) branch, extract the mercurial changeset number from the hg tip output...
if(EIGEN_BRANCH_OUTPUT MATCHES "default")
string(REGEX MATCH "^changeset: *[0-9]*:([0-9;a-f]+).*" EIGEN_HG_CHANGESET_MATCH "${EIGEN_HGTIP_OUTPUT}")
set(EIGEN_HG_CHANGESET "${CMAKE_MATCH_1}")
endif(EIGEN_BRANCH_OUTPUT MATCHES "default")
#...and show it next to the version number
if(EIGEN_HG_CHANGESET)
set(EIGEN_VERSION "${EIGEN_VERSION_NUMBER} (mercurial changeset ${EIGEN_HG_CHANGESET})")
else(EIGEN_HG_CHANGESET)
set(EIGEN_VERSION "${EIGEN_VERSION_NUMBER}")
endif(EIGEN_HG_CHANGESET)
include(CheckCXXCompilerFlag)
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
option(EIGEN_BUILD_TESTS "Build tests" OFF)
option(EIGEN_BUILD_DEMOS "Build demos" OFF)
if(NOT WIN32)
option(EIGEN_BUILD_LIB "Build the binary shared library" OFF)
endif(NOT WIN32)
option(EIGEN_BUILD_BTL "Build benchmark suite" OFF)
#############################################################################
# find how to link to the standard libraries #
#############################################################################
if(EIGEN_BUILD_LIB)
option(EIGEN_TEST_LIB "Build the unit tests using the library (disable -pedantic)" OFF)
endif(EIGEN_BUILD_LIB)
find_package(StandardMathLibrary)
set(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO "")
if(NOT STANDARD_MATH_LIBRARY_FOUND)
message(FATAL_ERROR
"Can't link to the standard math library. Please report to the Eigen developers, telling them about your platform.")
else()
if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)
set(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO "${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO} ${STANDARD_MATH_LIBRARY}")
else()
set(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO "${STANDARD_MATH_LIBRARY}")
endif()
endif()
if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)
message(STATUS "Standard libraries to link to explicitly: ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO}")
else()
message(STATUS "Standard libraries to link to explicitly: none")
endif()
option(EIGEN_BUILD_BTL "Build benchmark suite" OFF)
if(NOT WIN32)
option(EIGEN_BUILD_PKGCONFIG "Build pkg-config .pc file for Eigen" ON)
endif(NOT WIN32)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
option(EIGEN_SPLIT_LARGE_TESTS "Split large tests into smaller executables" ON)
option(EIGEN_DEFAULT_TO_ROW_MAJOR "Use row-major as default matrix storage order" OFF)
if(EIGEN_DEFAULT_TO_ROW_MAJOR)
add_definitions("-DEIGEN_DEFAULT_TO_ROW_MAJOR")
endif()
add_definitions("-DEIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS")
if(CMAKE_COMPILER_IS_GNUCXX)
if(CMAKE_SYSTEM_NAME MATCHES Linux)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -Wextra -fno-exceptions -fno-check-new -fno-common -fstrict-aliasing")
if(NOT EIGEN_TEST_LIB)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
endif(NOT EIGEN_TEST_LIB)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -fexceptions -fno-check-new -fno-common -fstrict-aliasing")
set(CMAKE_CXX_FLAGS_DEBUG "-g3")
set(CMAKE_CXX_FLAGS_RELEASE "-g0 -O2")
option(EIGEN_TEST_SSE2 "Enable/Disable SSE2 in tests/examples" OFF)
if(EIGEN_TEST_SSE2)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2")
message("Enabling SSE2 in tests/examples")
endif(EIGEN_TEST_SSE2)
check_cxx_compiler_flag("-Wno-variadic-macros" COMPILER_SUPPORT_WNOVARIADICMACRO)
if(COMPILER_SUPPORT_WNOVARIADICMACRO)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-variadic-macros")
endif()
option(EIGEN_TEST_SSE3 "Enable/Disable SSE3 in tests/examples" OFF)
if(EIGEN_TEST_SSE3)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse3")
message("Enabling SSE3 in tests/examples")
endif(EIGEN_TEST_SSE3)
check_cxx_compiler_flag("-Wextra" COMPILER_SUPPORT_WEXTRA)
if(COMPILER_SUPPORT_WEXTRA)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra")
endif()
option(EIGEN_TEST_SSSE3 "Enable/Disable SSSE3 in tests/examples" OFF)
if(EIGEN_TEST_SSSE3)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mssse3")
message("Enabling SSSE3 in tests/examples")
endif(EIGEN_TEST_SSSE3)
option(EIGEN_TEST_ALTIVEC "Enable/Disable altivec in tests/examples" OFF)
if(EIGEN_TEST_ALTIVEC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maltivec -mabi=altivec")
message("Enabling AltiVec in tests/examples")
endif(EIGEN_TEST_ALTIVEC)
endif(CMAKE_SYSTEM_NAME MATCHES Linux)
endif(CMAKE_COMPILER_IS_GNUCXX)
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
option(EIGEN_TEST_SSE2 "Enable/Disable SSE2 in tests/examples" OFF)
if(EIGEN_TEST_SSE2)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE2")
message("Enabling SSE2 in tests/examples")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2")
message(STATUS "Enabling SSE2 in tests/examples")
endif()
option(EIGEN_TEST_SSE3 "Enable/Disable SSE3 in tests/examples" OFF)
if(EIGEN_TEST_SSE3)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse3")
message(STATUS "Enabling SSE3 in tests/examples")
endif()
option(EIGEN_TEST_SSSE3 "Enable/Disable SSSE3 in tests/examples" OFF)
if(EIGEN_TEST_SSSE3)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mssse3")
message(STATUS "Enabling SSSE3 in tests/examples")
endif()
option(EIGEN_TEST_SSE4_1 "Enable/Disable SSE4.1 in tests/examples" OFF)
if(EIGEN_TEST_SSE4_1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1")
message(STATUS "Enabling SSE4.1 in tests/examples")
endif()
option(EIGEN_TEST_SSE4_2 "Enable/Disable SSE4.2 in tests/examples" OFF)
if(EIGEN_TEST_SSE4_2)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.2")
message(STATUS "Enabling SSE4.2 in tests/examples")
endif()
option(EIGEN_TEST_ALTIVEC "Enable/Disable AltiVec in tests/examples" OFF)
if(EIGEN_TEST_ALTIVEC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maltivec -mabi=altivec")
message(STATUS "Enabling AltiVec in tests/examples")
endif()
option(EIGEN_TEST_NEON "Enable/Disable Neon in tests/examples" OFF)
if(EIGEN_TEST_NEON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfloat-abi=softfp -mfpu=neon -mcpu=cortex-a8")
message(STATUS "Enabling NEON in tests/examples")
endif()
check_cxx_compiler_flag("-fopenmp" COMPILER_SUPPORT_OPENMP)
if(COMPILER_SUPPORT_OPENMP)
option(EIGEN_TEST_OPENMP "Enable/Disable OpenMP in tests/examples" OFF)
if(EIGEN_TEST_OPENMP)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
message(STATUS "Enabling OpenMP in tests/examples")
endif()
endif()
endif(CMAKE_COMPILER_IS_GNUCXX)
if(MSVC)
# C4127 - conditional expression is constant
# C4714 - marked as __forceinline not inlined (I failed to deactivate it selectively)
# We can disable this warning in the unit tests since it is clear that it occurs
# because we are oftentimes returning objects that have a destructor or may
# throw exceptions - in particular in the unit tests we are throwing extra many
# exceptions to cover indexing errors.
# C4505 - unreferenced local function has been removed (impossible to deactive selectively)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /wd4127 /wd4505 /wd4714")
# replace all /Wx by /W4
string(REGEX REPLACE "/W[0-9]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
check_cxx_compiler_flag("/openmp" COMPILER_SUPPORT_OPENMP)
if(COMPILER_SUPPORT_OPENMP)
option(EIGEN_TEST_OPENMP "Enable/Disable OpenMP in tests/examples" OFF)
if(EIGEN_TEST_OPENMP)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /openmp")
message(STATUS "Enabling OpenMP in tests/examples")
endif()
endif()
option(EIGEN_TEST_SSE2 "Enable/Disable SSE2 in tests/examples" OFF)
if(EIGEN_TEST_SSE2)
if(NOT CMAKE_CL_64)
# arch is not supported on 64 bit systems, SSE is enabled automatically.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE2")
endif(NOT CMAKE_CL_64)
message(STATUS "Enabling SSE2 in tests/examples")
endif(EIGEN_TEST_SSE2)
endif(MSVC)
option(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION "Disable explicit vectorization in tests/examples" OFF)
option(EIGEN_TEST_X87 "Force using X87 instructions. Implies no vectorization." OFF)
option(EIGEN_TEST_32BIT "Force generating 32bit code." OFF)
if(EIGEN_TEST_X87)
set(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION ON)
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=387")
message(STATUS "Forcing use of x87 instructions in tests/examples")
else()
message(STATUS "EIGEN_TEST_X87 ignored on your compiler")
endif()
endif()
if(EIGEN_TEST_32BIT)
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
message(STATUS "Forcing generation of 32-bit code in tests/examples")
else()
message(STATUS "EIGEN_TEST_32BIT ignored on your compiler")
endif()
endif()
if(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)
add_definitions(-DEIGEN_DONT_VECTORIZE=1)
message("Disabling vectorization in tests/examples")
endif(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)
message(STATUS "Disabling vectorization in tests/examples")
endif()
option(EIGEN_TEST_NO_EXPLICIT_ALIGNMENT "Disable explicit alignment (hence vectorization) in tests/examples" OFF)
if(EIGEN_TEST_NO_EXPLICIT_ALIGNMENT)
add_definitions(-DEIGEN_DONT_ALIGN=1)
message(STATUS "Disabling alignment in tests/examples")
endif()
option(EIGEN_TEST_C++0x "Enables all C++0x features." OFF)
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
# the user modifiable install path for header files
set(EIGEN_INCLUDE_INSTALL_DIR ${EIGEN_INCLUDE_INSTALL_DIR} CACHE PATH "The directory where we install the header files (optional)")
# set the internal install path for header files which depends on wether the user modifiable
# EIGEN_INCLUDE_INSTALL_DIR has been set by the user or not.
if(EIGEN_INCLUDE_INSTALL_DIR)
set(INCLUDE_INSTALL_DIR
${EIGEN_INCLUDE_INSTALL_DIR}
CACHE INTERNAL
"The directory where we install the header files (internal)"
)
else()
set(INCLUDE_INSTALL_DIR
"${CMAKE_INSTALL_PREFIX}/include/eigen3"
CACHE INTERNAL
"The directory where we install the header files (internal)"
)
endif()
# similar to set_target_properties but append the property instead of overwriting it
macro(ei_add_target_property target prop value)
get_target_property(previous ${target} ${prop})
# if the property wasn't previously set, ${previous} is now "previous-NOTFOUND" which cmake allows catching with plain if()
if(NOT previous)
set(previous "")
endif(NOT previous)
set_target_properties(${target} PROPERTIES ${prop} "${previous} ${value}")
endmacro(ei_add_target_property)
install(FILES
signature_of_eigen3_matrix_library
DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel
)
if(EIGEN_BUILD_PKGCONFIG)
configure_file(eigen3.pc.in eigen3.pc)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/eigen3.pc
DESTINATION share/pkgconfig
)
endif(EIGEN_BUILD_PKGCONFIG)
add_subdirectory(Eigen)
if(EIGEN_BUILD_TESTS)
include(CTest)
add_subdirectory(test)
endif(EIGEN_BUILD_TESTS)
add_subdirectory(doc EXCLUDE_FROM_ALL)
add_subdirectory(doc)
add_custom_target(buildtests)
add_custom_target(check COMMAND "ctest")
add_dependencies(check buildtests)
if(EIGEN_BUILD_DEMOS)
add_subdirectory(demos)
endif(EIGEN_BUILD_DEMOS)
# CMake/Ctest does not allow us to change the build command,
# so we have to workaround by directly editing the generated DartConfiguration.tcl file
# save CMAKE_MAKE_PROGRAM
set(CMAKE_MAKE_PROGRAM_SAVE ${CMAKE_MAKE_PROGRAM})
# and set a fake one
set(CMAKE_MAKE_PROGRAM "@EIGEN_MAKECOMMAND_PLACEHOLDER@")
include(CTest)
enable_testing() # must be called from the root CMakeLists, see man page
include(EigenTesting)
ei_init_testing()
# overwrite default DartConfiguration.tcl
# The worarounds are different for each version of the MSVC IDE
if(MSVC_IDE)
if(MSVC_VERSION EQUAL 1600) # MSVC 2010
set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} buildtests.vcxproj /p:Configuration=\${CTEST_CONFIGURATION_TYPE} \n # ")
else() # MSVC 2008 (TODO check MSVC 2005)
set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} /project buildtests")
endif()
else()
# for make and nmake
set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} buildtests")
endif()
configure_file(${CMAKE_BINARY_DIR}/DartConfiguration.tcl ${CMAKE_BINARY_DIR}/DartConfiguration.tcl)
# restore default CMAKE_MAKE_PROGRAM
set(CMAKE_MAKE_PROGRAM ${CMAKE_MAKE_PROGRAM_SAVE})
# un-set temporary variables so that it is like they never existed.
# CMake 2.6.3 introduces the more logical unset() syntax for this.
set(CMAKE_MAKE_PROGRAM_SAVE)
set(EIGEN_MAKECOMMAND_PLACEHOLDER)
configure_file(${CMAKE_SOURCE_DIR}/CTestCustom.cmake.in ${CMAKE_BINARY_DIR}/CTestCustom.cmake)
if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
add_subdirectory(test) # can't do EXCLUDE_FROM_ALL here, breaks CTest
else()
add_subdirectory(test EXCLUDE_FROM_ALL)
endif()
if(NOT MSVC)
if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
add_subdirectory(blas)
add_subdirectory(lapack)
else()
add_subdirectory(blas EXCLUDE_FROM_ALL)
add_subdirectory(lapack EXCLUDE_FROM_ALL)
endif()
endif(NOT MSVC)
add_subdirectory(unsupported)
add_subdirectory(demos EXCLUDE_FROM_ALL)
# must be after test and unsupported, for configuring buildtests.in
add_subdirectory(scripts EXCLUDE_FROM_ALL)
# TODO: consider also replacing EIGEN_BUILD_BTL by a custom target "make btl"?
if(EIGEN_BUILD_BTL)
add_subdirectory(bench/btl)
add_subdirectory(bench/btl EXCLUDE_FROM_ALL)
endif(EIGEN_BUILD_BTL)
ei_testing_print_summary()
message(STATUS "")
message(STATUS "Configured Eigen ${EIGEN_VERSION_NUMBER}")
message(STATUS "")
option(EIGEN_FAILTEST "Enable failtests." OFF)
if(EIGEN_FAILTEST)
add_subdirectory(failtest)
endif()
string(TOLOWER "${CMAKE_GENERATOR}" cmake_generator_tolower)
if(cmake_generator_tolower MATCHES "makefile")
message(STATUS "Some things you can do now:")
message(STATUS "--------------+--------------------------------------------------------------")
message(STATUS "Command | Description")
message(STATUS "--------------+--------------------------------------------------------------")
message(STATUS "make install | Install to ${CMAKE_INSTALL_PREFIX}. To change that:")
message(STATUS " | cmake . -DCMAKE_INSTALL_PREFIX=yourpath")
message(STATUS " | Eigen headers will then be installed to:")
message(STATUS " | ${INCLUDE_INSTALL_DIR}")
message(STATUS " | To install Eigen headers to a separate location, do:")
message(STATUS " | cmake . -DEIGEN_INCLUDE_INSTALL_DIR=yourpath")
message(STATUS "make doc | Generate the API documentation, requires Doxygen & LaTeX")
message(STATUS "make check | Build and run the unit-tests. Read this page:")
message(STATUS " | http://eigen.tuxfamily.org/index.php?title=Tests")
message(STATUS "make blas | Build BLAS library (not the same thing as Eigen)")
message(STATUS "--------------+--------------------------------------------------------------")
else()
message(STATUS "To build/run the unit tests, read this page:")
message(STATUS " http://eigen.tuxfamily.org/index.php?title=Tests")
endif()
message(STATUS "")

View File

@@ -1,4 +1,4 @@
GNU LESSER GENERAL PUBLIC LICENSE
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>

View File

@@ -3,11 +3,11 @@
## project to incorporate the testing dashboard.
## # The following are required to uses Dart and the Cdash dashboard
## ENABLE_TESTING()
## INCLUDE(Dart)
## INCLUDE(CTest)
set(CTEST_PROJECT_NAME "Eigen")
set(CTEST_NIGHTLY_START_TIME "05:00:00 UTC")
set(CTEST_NIGHTLY_START_TIME "00:00:00 UTC")
set(CTEST_DROP_METHOD "http")
set(CTEST_DROP_SITE "www.cdash.org")
set(CTEST_DROP_LOCATION "/CDashPublic/submit.php?project=Eigen")
set(CTEST_DROP_SITE "eigen.tuxfamily.org")
set(CTEST_DROP_LOCATION "/CDash/submit.php?project=Eigen")
set(CTEST_DROP_SITE_CDASH TRUE)

4
CTestCustom.cmake.in Normal file
View File

@@ -0,0 +1,4 @@
## A tribute to Dynamic!
set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS "33331")
set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS "33331")

281
Doxyfile
View File

@@ -1,281 +0,0 @@
# Doxyfile 1.5.3
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = Eigen
PROJECT_NUMBER = 2.0
OUTPUT_DIRECTORY = ./
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF = "The $name class" \
"The $name widget" \
"The $name file" \
is \
provides \
specifies \
contains \
represents \
a \
an \
the
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = NO
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO
HIDE_UNDOC_MEMBERS = YES
HIDE_UNDOC_CLASSES = YES
HIDE_FRIEND_COMPOUNDS = YES
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = YES
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = NO
FILE_VERSION_FILTER =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = ./
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.c \
*.cc \
*.cxx \
*.cpp \
*.c++ \
*.d \
*.java \
*.ii \
*.ixx \
*.ipp \
*.i++ \
*.inl \
*.h \
*.hh \
*.hxx \
*.hpp \
*.h++ \
*.idl \
*.odl \
*.cs \
*.php \
*.php3 \
*.inc \
*.m \
*.mm \
*.dox \
*.py \
*.C \
*.CC \
*.C++ \
*.II \
*.I++ \
*.H \
*.HH \
*.H++ \
*.CS \
*.PHP \
*.PHP3 \
*.M \
*.MM \
*.PY
RECURSIVE = NO
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
EXAMPLE_PATH = doc/examples/
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
HTML_DYNAMIC_SECTIONS = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = YES
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
MSCGEN_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = YES
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 1000
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO

View File

@@ -1,39 +1,11 @@
#ifndef EIGEN_ARRAY_MODULE_H
#define EIGEN_ARRAY_MODULE_H
// include Core first to handle Eigen2 support macros
#include "Core"
#include "src/Core/util/DisableMSVCWarnings.h"
namespace Eigen {
/** \defgroup Array_Module Array module
* This module provides several handy features to manipulate matrices as simple array of values.
* In addition to listed classes, it defines various methods of the Cwise interface
* (accessible from MatrixBase::cwise()), including:
* - matrix-scalar sum,
* - coeff-wise comparison operators,
* - sin, cos, sqrt, pow, exp, log, square, cube, inverse (reciprocal).
*
* This module also provides various MatrixBase methods, including:
* - \ref MatrixBase::all() "all", \ref MatrixBase::any() "any",
* - \ref MatrixBase::Random() "random matrix initialization"
*
* \code
* #include <Eigen/Array>
* \endcode
*/
#include "src/Array/CwiseOperators.h"
#include "src/Array/Functors.h"
#include "src/Array/BooleanRedux.h"
#include "src/Array/Select.h"
#include "src/Array/PartialRedux.h"
#include "src/Array/Random.h"
#include "src/Array/Norms.h"
} // namespace Eigen
#include "src/Core/util/EnableMSVCWarnings.h"
#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

View File

@@ -1,34 +1,19 @@
set(Eigen_HEADERS Core LU Cholesky QR Geometry Sparse Array SVD LeastSquares QtAlignedMalloc StdVector)
include(RegexUtils)
test_escape_string_as_regex()
if(EIGEN_BUILD_LIB)
set(Eigen_SRCS
src/Core/CoreInstantiations.cpp
src/Cholesky/CholeskyInstantiations.cpp
src/QR/QrInstantiations.cpp
)
file(GLOB Eigen_directory_files "*")
add_library(Eigen2 SHARED ${Eigen_SRCS})
escape_string_as_regex(ESCAPED_CMAKE_CURRENT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
install(TARGETS Eigen2
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
endif(EIGEN_BUILD_LIB)
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g1 -O2")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g1 -O2")
endif(CMAKE_COMPILER_IS_GNUCXX)
set(INCLUDE_INSTALL_DIR
"${CMAKE_INSTALL_PREFIX}/include/eigen2"
CACHE PATH
"The directory where we install the header files"
FORCE)
foreach(f ${Eigen_directory_files})
if(NOT f MATCHES "\\.txt" AND NOT f MATCHES "${ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/[.].+" AND NOT f MATCHES "${ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/src")
list(APPEND Eigen_directory_files_to_install ${f})
endif()
endforeach(f ${Eigen_directory_files})
install(FILES
${Eigen_HEADERS}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen
${Eigen_directory_files_to_install}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen COMPONENT Devel
)
add_subdirectory(src)

View File

@@ -3,20 +3,14 @@
#include "Core"
#include "src/Core/util/DisableMSVCWarnings.h"
// Note that EIGEN_HIDE_HEAVY_CODE has to be defined per module
#if (defined EIGEN_EXTERN_INSTANTIATIONS) && (EIGEN_EXTERN_INSTANTIATIONS>=2)
#ifndef EIGEN_HIDE_HEAVY_CODE
#define EIGEN_HIDE_HEAVY_CODE
#endif
#elif defined EIGEN_HIDE_HEAVY_CODE
#undef EIGEN_HIDE_HEAVY_CODE
#endif
#include "src/Core/util/DisableStupidWarnings.h"
namespace Eigen {
/** \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(),
@@ -27,36 +21,13 @@ namespace Eigen {
* \endcode
*/
#include "src/Array/CwiseOperators.h"
#include "src/Array/Functors.h"
#include "src/misc/Solve.h"
#include "src/Cholesky/LLT.h"
#include "src/Cholesky/LDLT.h"
} // namespace Eigen
#define EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(MATRIXTYPE,PREFIX) \
PREFIX template class Cholesky<MATRIXTYPE>; \
PREFIX template class CholeskyWithoutSquareRoot<MATRIXTYPE>
#define EIGEN_CHOLESKY_MODULE_INSTANTIATE(PREFIX) \
EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(Matrix2f,PREFIX); \
EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(Matrix2d,PREFIX); \
EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(Matrix3f,PREFIX); \
EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(Matrix3d,PREFIX); \
EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(Matrix4f,PREFIX); \
EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(Matrix4d,PREFIX); \
EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(MatrixXf,PREFIX); \
EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(MatrixXd,PREFIX); \
EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(MatrixXcf,PREFIX); \
EIGEN_CHOLESKY_MODULE_INSTANTIATE_TYPE(MatrixXcd,PREFIX)
#ifdef EIGEN_EXTERN_INSTANTIATIONS
namespace Eigen {
EIGEN_CHOLESKY_MODULE_INSTANTIATE(extern);
} // namespace Eigen
#endif
#include "src/Core/util/EnableMSVCWarnings.h"
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_CHOLESKY_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */

View File

@@ -1,44 +1,116 @@
// 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>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_CORE_H
#define EIGEN_CORE_H
// first thing Eigen does: prevent MSVC from committing suicide
#include "src/Core/util/DisableMSVCWarnings.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"
// 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
#ifdef _M_IX86_FP
#if _M_IX86_FP >= 2
#define EIGEN_SSE2_ON_MSVC_2008_OR_LATER
#endif
#endif
// 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
#endif
#ifdef __GNUC__
#define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__>=x && __GNUC_MINOR__>=y) || __GNUC__>x)
#else
#define EIGEN_GNUC_AT_LEAST(x,y) 0
#endif
// Remember that usage of defined() in a #define is undefined by the standard
#if (defined __SSE2__) && ( (!defined __GNUC__) || EIGEN_GNUC_AT_LEAST(4,2) )
#define EIGEN_SSE2_BUT_NOT_OLD_GCC
#endif
#ifndef EIGEN_DONT_VECTORIZE
#if defined (EIGEN_SSE2_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
#include <emmintrin.h>
#include <xmmintrin.h>
#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__
#include <pmmintrin.h>
#define EIGEN_VECTORIZE_SSE3
#endif
#ifdef __SSSE3__
#include <tmmintrin.h>
#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
@@ -48,18 +120,51 @@
#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))
#define EIGEN_HAS_ERRNO
#endif
#ifdef EIGEN_HAS_ERRNO
#include <cerrno>
#endif
#include <cstdlib>
#include <cmath>
#include <complex>
#include <cassert>
#include <functional>
#include <iostream>
#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)) && !defined(EIGEN_NO_EXCEPTIONS)
#define EIGEN_EXCEPTIONS
@@ -76,8 +181,65 @@
#error The preprocessor symbols 'min' or 'max' are defined. If you are compiling on Windows, do #define NOMINMAX to prevent windows.h from defining these symbols.
#endif
// defined in bits/termios.h
#undef B0
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
}
#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;
/** \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
@@ -88,7 +250,6 @@ namespace Eigen {
* \endcode
*/
#include "src/Core/util/Macros.h"
#include "src/Core/util/Constants.h"
#include "src/Core/util/ForwardDeclarations.h"
#include "src/Core/util/Meta.h"
@@ -102,54 +263,101 @@ namespace Eigen {
#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
#ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
#define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 16
#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/Coeffs.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/MatrixStorage.h"
#include "src/Core/util/BlasUtil.h"
#include "src/Core/DenseStorage.h"
#include "src/Core/NestByValue.h"
#include "src/Core/Flagged.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/Cwise.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/Product.h"
#include "src/Core/DiagonalProduct.h"
#include "src/Core/SolveTriangular.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/Minor.h"
#include "src/Core/VectorBlock.h"
#include "src/Core/Transpose.h"
#include "src/Core/DiagonalMatrix.h"
#include "src/Core/DiagonalCoeffs.h"
#include "src/Core/Sum.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/Part.h"
#include "src/Core/CacheFriendlyProduct.h"
#include "src/Core/Flagged.h"
#include "src/Core/ProductBase.h"
#include "src/Core/Product.h"
#include "src/Core/TriangularMatrix.h"
#include "src/Core/SelfAdjointView.h"
#include "src/Core/SolveTriangular.h"
#include "src/Core/products/Parallelizer.h"
#include "src/Core/products/CoeffBasedProduct.h"
#include "src/Core/products/GeneralBlockPanelKernel.h"
#include "src/Core/products/GeneralMatrixVector.h"
#include "src/Core/products/GeneralMatrixMatrix.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"
} // namespace Eigen
#include "src/Core/util/EnableMSVCWarnings.h"
#include "src/Core/GlobalFunctions.h"
#include "src/Core/util/ReenableStupidWarnings.h"
#ifdef EIGEN2_SUPPORT
#include "Eigen2Support"
#endif
#endif // EIGEN_CORE_H

7
Eigen/Dense Normal file
View File

@@ -0,0 +1,7 @@
#include "Core"
#include "LU"
#include "Cholesky"
#include "QR"
#include "SVD"
#include "Geometry"
#include "Eigenvalues"

2
Eigen/Eigen Normal file
View File

@@ -0,0 +1,2 @@
#include "Dense"
//#include "Sparse"

82
Eigen/Eigen2Support Normal file
View 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>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef 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"
namespace Eigen {
/** \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"
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
// Eigen2 used to include iostream
#include<iostream>
#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

44
Eigen/Eigenvalues Normal file
View File

@@ -0,0 +1,44 @@
#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"
namespace Eigen {
/** \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"
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_EIGENVALUES_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */

View File

@@ -3,9 +3,10 @@
#include "Core"
#include "src/Core/util/DisableMSVCWarnings.h"
#include "src/Core/util/DisableStupidWarnings.h"
#include "Array"
#include "SVD"
#include "LU"
#include <limits>
#ifndef M_PI
@@ -16,7 +17,7 @@ namespace Eigen {
/** \defgroup Geometry_Module Geometry module
*
* \nonstableyet
*
*
* This module provides support for:
* - fixed-size homogeneous transformations
@@ -32,20 +33,35 @@ namespace Eigen {
*/
#include "src/Geometry/OrthoMethods.h"
#include "src/Geometry/RotationBase.h"
#include "src/Geometry/Rotation2D.h"
#include "src/Geometry/Quaternion.h"
#include "src/Geometry/AngleAxis.h"
#include "src/Geometry/EulerAngles.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"
#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
} // namespace Eigen
#include "src/Core/util/EnableMSVCWarnings.h"
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_GEOMETRY_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */

27
Eigen/Householder Normal file
View File

@@ -0,0 +1,27 @@
#ifndef EIGEN_HOUSEHOLDER_MODULE_H
#define EIGEN_HOUSEHOLDER_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
namespace Eigen {
/** \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"
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_HOUSEHOLDER_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */

30
Eigen/Jacobi Normal file
View File

@@ -0,0 +1,30 @@
#ifndef EIGEN_JACOBI_MODULE_H
#define EIGEN_JACOBI_MODULE_H
#include "Core"
#include "src/Core/util/DisableStupidWarnings.h"
namespace Eigen {
/** \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"
} // namespace Eigen
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_JACOBI_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */

View File

@@ -3,7 +3,7 @@
#include "Core"
#include "src/Core/util/DisableMSVCWarnings.h"
#include "src/Core/util/DisableStupidWarnings.h"
namespace Eigen {
@@ -18,12 +18,25 @@ namespace Eigen {
* \endcode
*/
#include "src/LU/LU.h"
#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"
#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
} // namespace Eigen
#include "src/Core/util/EnableMSVCWarnings.h"
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_LU_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */

View File

@@ -1,12 +1,18 @@
#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/DisableMSVCWarnings.h"
#include "src/Core/util/DisableStupidWarnings.h"
#include "LU"
#include "QR"
#include "Eigenvalues"
#include "Geometry"
namespace Eigen {
@@ -19,10 +25,12 @@ namespace Eigen {
* \endcode
*/
#include "src/LeastSquares/LeastSquares.h"
#include "src/Eigen2Support/LeastSquares.h"
} // namespace Eigen
#include "src/Core/util/EnableMSVCWarnings.h"
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN2_SUPPORT
#endif // EIGEN_REGRESSION_MODULE_H

View File

@@ -3,71 +3,43 @@
#include "Core"
#include "src/Core/util/DisableMSVCWarnings.h"
#include "src/Core/util/DisableStupidWarnings.h"
#include "Cholesky"
// Note that EIGEN_HIDE_HEAVY_CODE has to be defined per module
#if (defined EIGEN_EXTERN_INSTANTIATIONS) && (EIGEN_EXTERN_INSTANTIATIONS>=2)
#ifndef EIGEN_HIDE_HEAVY_CODE
#define EIGEN_HIDE_HEAVY_CODE
#endif
#elif defined EIGEN_HIDE_HEAVY_CODE
#undef EIGEN_HIDE_HEAVY_CODE
#endif
#include "Jacobi"
#include "Householder"
namespace Eigen {
/** \defgroup QR_Module QR module
*
* \nonstableyet
*
* This module mainly provides QR decomposition and an eigen value solver.
*
* This module provides various QR decompositions
* This module also provides some MatrixBase methods, including:
* - MatrixBase::qr(),
* - MatrixBase::eigenvalues(),
* - MatrixBase::operatorNorm()
*
* \code
* #include <Eigen/QR>
* \endcode
*/
#include "src/QR/QR.h"
#include "src/QR/Tridiagonalization.h"
#include "src/QR/EigenSolver.h"
#include "src/QR/SelfAdjointEigenSolver.h"
#include "src/QR/HessenbergDecomposition.h"
#include "src/misc/Solve.h"
#include "src/QR/HouseholderQR.h"
#include "src/QR/FullPivHouseholderQR.h"
#include "src/QR/ColPivHouseholderQR.h"
// declare all classes for a given matrix type
#define EIGEN_QR_MODULE_INSTANTIATE_TYPE(MATRIXTYPE,PREFIX) \
PREFIX template class QR<MATRIXTYPE>; \
PREFIX template class Tridiagonalization<MATRIXTYPE>; \
PREFIX template class HessenbergDecomposition<MATRIXTYPE>; \
PREFIX template class SelfAdjointEigenSolver<MATRIXTYPE>
// removed because it does not support complex yet
// PREFIX template class EigenSolver<MATRIXTYPE>
// declare all class for all types
#define EIGEN_QR_MODULE_INSTANTIATE(PREFIX) \
EIGEN_QR_MODULE_INSTANTIATE_TYPE(Matrix2f,PREFIX); \
EIGEN_QR_MODULE_INSTANTIATE_TYPE(Matrix2d,PREFIX); \
EIGEN_QR_MODULE_INSTANTIATE_TYPE(Matrix3f,PREFIX); \
EIGEN_QR_MODULE_INSTANTIATE_TYPE(Matrix3d,PREFIX); \
EIGEN_QR_MODULE_INSTANTIATE_TYPE(Matrix4f,PREFIX); \
EIGEN_QR_MODULE_INSTANTIATE_TYPE(Matrix4d,PREFIX); \
EIGEN_QR_MODULE_INSTANTIATE_TYPE(MatrixXf,PREFIX); \
EIGEN_QR_MODULE_INSTANTIATE_TYPE(MatrixXd,PREFIX); \
EIGEN_QR_MODULE_INSTANTIATE_TYPE(MatrixXcf,PREFIX); \
EIGEN_QR_MODULE_INSTANTIATE_TYPE(MatrixXcd,PREFIX)
#ifdef EIGEN_EXTERN_INSTANTIATIONS
EIGEN_QR_MODULE_INSTANTIATE(extern);
#endif // EIGEN_EXTERN_INSTANTIATIONS
#ifdef EIGEN2_SUPPORT
#include "src/Eigen2Support/QR.h"
#endif
} // namespace Eigen
#include "src/Core/util/EnableMSVCWarnings.h"
#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: */

View File

@@ -6,24 +6,29 @@
#if (!EIGEN_MALLOC_ALREADY_ALIGNED)
inline void *qMalloc(size_t size)
#include "src/Core/util/DisableStupidWarnings.h"
void *qMalloc(size_t size)
{
return Eigen::ei_aligned_malloc(size);
return Eigen::internal::aligned_malloc(size);
}
inline void qFree(void *ptr)
void qFree(void *ptr)
{
Eigen::ei_aligned_free(ptr);
Eigen::internal::aligned_free(ptr);
}
inline void *qRealloc(void *ptr, size_t size)
void *qRealloc(void *ptr, size_t size)
{
void* newPtr = Eigen::ei_aligned_malloc(size);
void* newPtr = Eigen::internal::aligned_malloc(size);
memcpy(newPtr, ptr, size);
Eigen::ei_aligned_free(ptr);
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: */

View File

@@ -1,15 +1,17 @@
#ifndef EIGEN_SVD_MODULE_H
#define EIGEN_SVD_MODULE_H
#include "Core"
#include "QR"
#include "Householder"
#include "Jacobi"
#include "src/Core/util/DisableMSVCWarnings.h"
#include "src/Core/util/DisableStupidWarnings.h"
namespace Eigen {
/** \defgroup SVD_Module SVD module
*
* \nonstableyet
*
*
* This module provides SVD decomposition for (currently) real matrices.
* This decomposition is accessible via the following MatrixBase method:
@@ -20,10 +22,17 @@ namespace Eigen {
* \endcode
*/
#include "src/SVD/SVD.h"
#include "src/misc/Solve.h"
#include "src/SVD/JacobiSVD.h"
#include "src/SVD/UpperBidiagonalization.h"
#ifdef EIGEN2_SUPPORT
#include "src/Eigen2Support/SVD.h"
#endif
} // namespace Eigen
#include "src/Core/util/EnableMSVCWarnings.h"
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_SVD_MODULE_H
/* vim: set filetype=cpp et sw=2 ts=2 ai: */

View File

@@ -3,7 +3,7 @@
#include "Core"
#include "src/Core/util/DisableMSVCWarnings.h"
#include "src/Core/util/DisableStupidWarnings.h"
#include <vector>
#include <map>
@@ -11,120 +11,59 @@
#include <cstring>
#include <algorithm>
#ifdef EIGEN_GOOGLEHASH_SUPPORT
#include <google/dense_hash_map>
#ifdef EIGEN2_SUPPORT
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
#endif
#ifdef EIGEN_CHOLMOD_SUPPORT
extern "C" {
#include "cholmod.h"
}
#endif
#ifdef EIGEN_TAUCS_SUPPORT
// taucs.h declares a lot of mess
#define isnan
#define finite
#define isinf
extern "C" {
#include "taucs.h"
}
#undef isnan
#undef finite
#undef isinf
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
#endif
#ifdef EIGEN_SUPERLU_SUPPORT
typedef int int_t;
#include "superlu/slu_Cnames.h"
#include "superlu/supermatrix.h"
#include "superlu/slu_util.h"
namespace SuperLU_S {
#include "superlu/slu_sdefs.h"
}
namespace SuperLU_D {
#include "superlu/slu_ddefs.h"
}
namespace SuperLU_C {
#include "superlu/slu_cdefs.h"
}
namespace SuperLU_Z {
#include "superlu/slu_zdefs.h"
}
namespace Eigen { struct SluMatrix; }
#endif
#ifdef EIGEN_UMFPACK_SUPPORT
#include "umfpack.h"
#ifndef EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
#error The sparse module API is not stable yet. To use it anyway, please define the EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET preprocessor token.
#endif
namespace Eigen {
/** \defgroup Sparse_Module Sparse module
*
* \nonstableyet
*
*
* See the \ref TutorialSparse "Sparse tutorial"
*
* \code
* #include <Eigen/QR>
* #include <Eigen/Sparse>
* \endcode
*/
/** The type used to identify a general sparse storage. */
struct Sparse {};
#include "src/Sparse/SparseUtil.h"
#include "src/Sparse/SparseMatrixBase.h"
#include "src/Sparse/CompressedStorage.h"
#include "src/Sparse/AmbiVector.h"
#include "src/Sparse/RandomSetter.h"
#include "src/Sparse/SparseBlock.h"
#include "src/Sparse/SparseMatrix.h"
#include "src/Sparse/DynamicSparseMatrix.h"
#include "src/Sparse/MappedSparseMatrix.h"
#include "src/Sparse/SparseVector.h"
#include "src/Sparse/CoreIterators.h"
#include "src/Sparse/SparseBlock.h"
#include "src/Sparse/SparseTranspose.h"
#include "src/Sparse/SparseCwise.h"
#include "src/Sparse/SparseCwiseUnaryOp.h"
#include "src/Sparse/SparseCwiseBinaryOp.h"
#include "src/Sparse/SparseDot.h"
#include "src/Sparse/SparseAssign.h"
#include "src/Sparse/SparseRedux.h"
#include "src/Sparse/SparseFuzzy.h"
#include "src/Sparse/SparseFlagged.h"
#include "src/Sparse/SparseProduct.h"
#include "src/Sparse/SparseSparseProduct.h"
#include "src/Sparse/SparseDenseProduct.h"
#include "src/Sparse/SparseDiagonalProduct.h"
#include "src/Sparse/SparseTriangularView.h"
#include "src/Sparse/SparseSelfAdjointView.h"
#include "src/Sparse/TriangularSolver.h"
#include "src/Sparse/SparseLLT.h"
#include "src/Sparse/SparseLDLT.h"
#include "src/Sparse/SparseLU.h"
#ifdef EIGEN_CHOLMOD_SUPPORT
# include "src/Sparse/CholmodSupport.h"
#endif
#ifdef EIGEN_TAUCS_SUPPORT
# include "src/Sparse/TaucsSupport.h"
#endif
#ifdef EIGEN_SUPERLU_SUPPORT
# include "src/Sparse/SuperLUSupport.h"
#endif
#ifdef EIGEN_UMFPACK_SUPPORT
# include "src/Sparse/UmfPackSupport.h"
#endif
#include "src/Sparse/SparseView.h"
} // namespace Eigen
#include "src/Core/util/EnableMSVCWarnings.h"
#include "src/Core/util/ReenableStupidWarnings.h"
#endif // EIGEN_SPARSE_MODULE_H

42
Eigen/StdDeque Normal file
View File

@@ -0,0 +1,42 @@
// 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>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_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

41
Eigen/StdList Normal file
View File

@@ -0,0 +1,41 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_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

View File

@@ -1,15 +1,42 @@
// 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>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_STDVECTOR_MODULE_H
#define EIGEN_STDVECTOR_MODULE_H
#include "Core"
#include <vector>
namespace Eigen {
#include "src/StdVector/UnalignedType.h"
} // namespace Eigen
#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */
namespace std {
#include "src/StdVector/StdVector.h"
} // namespace std
#define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...)
#else
#include "src/StlSupport/StdVector.h"
#endif
#endif // EIGEN_STDVECTOR_MODULE_H

View File

@@ -1,6 +0,0 @@
FILE(GLOB Eigen_Array_SRCS "*.h")
INSTALL(FILES
${Eigen_Array_SRCS}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Array
)

View File

@@ -1,453 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_ARRAY_CWISE_OPERATORS_H
#define EIGEN_ARRAY_CWISE_OPERATORS_H
// -- unary operators --
/** \array_module
*
* \returns an expression of the coefficient-wise square root of *this.
*
* Example: \include Cwise_sqrt.cpp
* Output: \verbinclude Cwise_sqrt.out
*
* \sa pow(), square()
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_sqrt_op)
Cwise<ExpressionType>::sqrt() const
{
return _expression();
}
/** \array_module
*
* \returns an expression of the coefficient-wise exponential of *this.
*
* Example: \include Cwise_exp.cpp
* Output: \verbinclude Cwise_exp.out
*
* \sa pow(), log(), sin(), cos()
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_exp_op)
Cwise<ExpressionType>::exp() const
{
return _expression();
}
/** \array_module
*
* \returns an expression of the coefficient-wise logarithm of *this.
*
* Example: \include Cwise_log.cpp
* Output: \verbinclude Cwise_log.out
*
* \sa exp()
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_log_op)
Cwise<ExpressionType>::log() const
{
return _expression();
}
/** \array_module
*
* \returns an expression of the coefficient-wise cosine of *this.
*
* Example: \include Cwise_cos.cpp
* Output: \verbinclude Cwise_cos.out
*
* \sa sin(), exp()
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_cos_op)
Cwise<ExpressionType>::cos() const
{
return _expression();
}
/** \array_module
*
* \returns an expression of the coefficient-wise sine of *this.
*
* Example: \include Cwise_sin.cpp
* Output: \verbinclude Cwise_sin.out
*
* \sa cos(), exp()
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_sin_op)
Cwise<ExpressionType>::sin() const
{
return _expression();
}
/** \array_module
*
* \returns an expression of the coefficient-wise power of *this to the given exponent.
*
* Example: \include Cwise_pow.cpp
* Output: \verbinclude Cwise_pow.out
*
* \sa exp(), log()
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_pow_op)
Cwise<ExpressionType>::pow(const Scalar& exponent) const
{
return EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_pow_op)(_expression(), ei_scalar_pow_op<Scalar>(exponent));
}
/** \array_module
*
* \returns an expression of the coefficient-wise inverse of *this.
*
* Example: \include Cwise_inverse.cpp
* Output: \verbinclude Cwise_inverse.out
*
* \sa operator/(), operator*()
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_inverse_op)
Cwise<ExpressionType>::inverse() const
{
return _expression();
}
/** \array_module
*
* \returns an expression of the coefficient-wise square of *this.
*
* Example: \include Cwise_square.cpp
* Output: \verbinclude Cwise_square.out
*
* \sa operator/(), operator*(), abs2()
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_square_op)
Cwise<ExpressionType>::square() const
{
return _expression();
}
/** \array_module
*
* \returns an expression of the coefficient-wise cube of *this.
*
* Example: \include Cwise_cube.cpp
* Output: \verbinclude Cwise_cube.out
*
* \sa square(), pow()
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_cube_op)
Cwise<ExpressionType>::cube() const
{
return _expression();
}
// -- binary operators --
/** \array_module
*
* \returns an expression of the coefficient-wise \< operator of *this and \a other
*
* Example: \include Cwise_less.cpp
* Output: \verbinclude Cwise_less.out
*
* \sa MatrixBase::all(), MatrixBase::any(), operator>(), operator<=()
*/
template<typename ExpressionType>
template<typename OtherDerived>
inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::less)
Cwise<ExpressionType>::operator<(const MatrixBase<OtherDerived> &other) const
{
return EIGEN_CWISE_BINOP_RETURN_TYPE(std::less)(_expression(), other.derived());
}
/** \array_module
*
* \returns an expression of the coefficient-wise \<= operator of *this and \a other
*
* Example: \include Cwise_less_equal.cpp
* Output: \verbinclude Cwise_less_equal.out
*
* \sa MatrixBase::all(), MatrixBase::any(), operator>=(), operator<()
*/
template<typename ExpressionType>
template<typename OtherDerived>
inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::less_equal)
Cwise<ExpressionType>::operator<=(const MatrixBase<OtherDerived> &other) const
{
return EIGEN_CWISE_BINOP_RETURN_TYPE(std::less_equal)(_expression(), other.derived());
}
/** \array_module
*
* \returns an expression of the coefficient-wise \> operator of *this and \a other
*
* Example: \include Cwise_greater.cpp
* Output: \verbinclude Cwise_greater.out
*
* \sa MatrixBase::all(), MatrixBase::any(), operator>=(), operator<()
*/
template<typename ExpressionType>
template<typename OtherDerived>
inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater)
Cwise<ExpressionType>::operator>(const MatrixBase<OtherDerived> &other) const
{
return EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater)(_expression(), other.derived());
}
/** \array_module
*
* \returns an expression of the coefficient-wise \>= operator of *this and \a other
*
* Example: \include Cwise_greater_equal.cpp
* Output: \verbinclude Cwise_greater_equal.out
*
* \sa MatrixBase::all(), MatrixBase::any(), operator>(), operator<=()
*/
template<typename ExpressionType>
template<typename OtherDerived>
inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater_equal)
Cwise<ExpressionType>::operator>=(const MatrixBase<OtherDerived> &other) const
{
return EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater_equal)(_expression(), other.derived());
}
/** \array_module
*
* \returns an expression of the coefficient-wise == operator of *this and \a other
*
* \warning this performs an exact comparison, which is generally a bad idea with floating-point types.
* In order to check for equality between two vectors or matrices with floating-point coefficients, it is
* generally a far better idea to use a fuzzy comparison as provided by MatrixBase::isApprox() and
* MatrixBase::isMuchSmallerThan().
*
* Example: \include Cwise_equal_equal.cpp
* Output: \verbinclude Cwise_equal_equal.out
*
* \sa MatrixBase::all(), MatrixBase::any(), MatrixBase::isApprox(), MatrixBase::isMuchSmallerThan()
*/
template<typename ExpressionType>
template<typename OtherDerived>
inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::equal_to)
Cwise<ExpressionType>::operator==(const MatrixBase<OtherDerived> &other) const
{
return EIGEN_CWISE_BINOP_RETURN_TYPE(std::equal_to)(_expression(), other.derived());
}
/** \array_module
*
* \returns an expression of the coefficient-wise != operator of *this and \a other
*
* \warning this performs an exact comparison, which is generally a bad idea with floating-point types.
* In order to check for equality between two vectors or matrices with floating-point coefficients, it is
* generally a far better idea to use a fuzzy comparison as provided by MatrixBase::isApprox() and
* MatrixBase::isMuchSmallerThan().
*
* Example: \include Cwise_not_equal.cpp
* Output: \verbinclude Cwise_not_equal.out
*
* \sa MatrixBase::all(), MatrixBase::any(), MatrixBase::isApprox(), MatrixBase::isMuchSmallerThan()
*/
template<typename ExpressionType>
template<typename OtherDerived>
inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::not_equal_to)
Cwise<ExpressionType>::operator!=(const MatrixBase<OtherDerived> &other) const
{
return EIGEN_CWISE_BINOP_RETURN_TYPE(std::not_equal_to)(_expression(), other.derived());
}
// comparisons to scalar value
/** \array_module
*
* \returns an expression of the coefficient-wise \< operator of *this and a scalar \a s
*
* \sa operator<(const MatrixBase<OtherDerived> &) const
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less)
Cwise<ExpressionType>::operator<(Scalar s) const
{
return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less)(_expression(),
typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s));
}
/** \array_module
*
* \returns an expression of the coefficient-wise \<= operator of *this and a scalar \a s
*
* \sa operator<=(const MatrixBase<OtherDerived> &) const
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less_equal)
Cwise<ExpressionType>::operator<=(Scalar s) const
{
return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less_equal)(_expression(),
typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s));
}
/** \array_module
*
* \returns an expression of the coefficient-wise \> operator of *this and a scalar \a s
*
* \sa operator>(const MatrixBase<OtherDerived> &) const
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater)
Cwise<ExpressionType>::operator>(Scalar s) const
{
return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater)(_expression(),
typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s));
}
/** \array_module
*
* \returns an expression of the coefficient-wise \>= operator of *this and a scalar \a s
*
* \sa operator>=(const MatrixBase<OtherDerived> &) const
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater_equal)
Cwise<ExpressionType>::operator>=(Scalar s) const
{
return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater_equal)(_expression(),
typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s));
}
/** \array_module
*
* \returns an expression of the coefficient-wise == operator of *this and a scalar \a s
*
* \warning this performs an exact comparison, which is generally a bad idea with floating-point types.
* In order to check for equality between two vectors or matrices with floating-point coefficients, it is
* generally a far better idea to use a fuzzy comparison as provided by MatrixBase::isApprox() and
* MatrixBase::isMuchSmallerThan().
*
* \sa operator==(const MatrixBase<OtherDerived> &) const
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::equal_to)
Cwise<ExpressionType>::operator==(Scalar s) const
{
return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::equal_to)(_expression(),
typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s));
}
/** \array_module
*
* \returns an expression of the coefficient-wise != operator of *this and a scalar \a s
*
* \warning this performs an exact comparison, which is generally a bad idea with floating-point types.
* In order to check for equality between two vectors or matrices with floating-point coefficients, it is
* generally a far better idea to use a fuzzy comparison as provided by MatrixBase::isApprox() and
* MatrixBase::isMuchSmallerThan().
*
* \sa operator!=(const MatrixBase<OtherDerived> &) const
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::not_equal_to)
Cwise<ExpressionType>::operator!=(Scalar s) const
{
return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::not_equal_to)(_expression(),
typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s));
}
// scalar addition
/** \array_module
*
* \returns an expression of \c *this with each coeff incremented by the constant \a scalar
*
* Example: \include Cwise_plus.cpp
* Output: \verbinclude Cwise_plus.out
*
* \sa operator+=(), operator-()
*/
template<typename ExpressionType>
inline const typename Cwise<ExpressionType>::ScalarAddReturnType
Cwise<ExpressionType>::operator+(const Scalar& scalar) const
{
return typename Cwise<ExpressionType>::ScalarAddReturnType(m_matrix, ei_scalar_add_op<Scalar>(scalar));
}
/** \array_module
*
* Adds the given \a scalar to each coeff of this expression.
*
* Example: \include Cwise_plus_equal.cpp
* Output: \verbinclude Cwise_plus_equal.out
*
* \sa operator+(), operator-=()
*/
template<typename ExpressionType>
inline ExpressionType& Cwise<ExpressionType>::operator+=(const Scalar& scalar)
{
return m_matrix.const_cast_derived() = *this + scalar;
}
/** \array_module
*
* \returns an expression of \c *this with each coeff decremented by the constant \a scalar
*
* Example: \include Cwise_minus.cpp
* Output: \verbinclude Cwise_minus.out
*
* \sa operator+(), operator-=()
*/
template<typename ExpressionType>
inline const typename Cwise<ExpressionType>::ScalarAddReturnType
Cwise<ExpressionType>::operator-(const Scalar& scalar) const
{
return *this + (-scalar);
}
/** \array_module
*
* Substracts the given \a scalar from each coeff of this expression.
*
* Example: \include Cwise_minus_equal.cpp
* Output: \verbinclude Cwise_minus_equal.out
*
* \sa operator+=(), operator-()
*/
template<typename ExpressionType>
inline ExpressionType& Cwise<ExpressionType>::operator-=(const Scalar& scalar)
{
return m_matrix.const_cast_derived() = *this - scalar;
}
#endif // EIGEN_ARRAY_CWISE_OPERATORS_H

View File

@@ -1,305 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_ARRAY_FUNCTORS_H
#define EIGEN_ARRAY_FUNCTORS_H
/** \internal
* \array_module
*
* \brief Template functor to add a scalar to a fixed other one
*
* \sa class CwiseUnaryOp, Array::operator+
*/
/* If you wonder why doing the ei_pset1() in packetOp() is an optimization check ei_scalar_multiple_op */
template<typename Scalar>
struct ei_scalar_add_op {
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
// FIXME default copy constructors seems bugged with std::complex<>
inline ei_scalar_add_op(const ei_scalar_add_op& other) : m_other(other.m_other) { }
inline ei_scalar_add_op(const Scalar& other) : m_other(other) { }
inline Scalar operator() (const Scalar& a) const { return a + m_other; }
inline const PacketScalar packetOp(const PacketScalar& a) const
{ return ei_padd(a, ei_pset1(m_other)); }
const Scalar m_other;
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_add_op<Scalar> >
{ enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = ei_packet_traits<Scalar>::size>1 }; };
/** \internal
*
* \array_module
*
* \brief Template functor to compute the square root of a scalar
*
* \sa class CwiseUnaryOp, Cwise::sqrt()
*/
template<typename Scalar> struct ei_scalar_sqrt_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a) const { return ei_sqrt(a); }
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_sqrt_op<Scalar> >
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
/** \internal
*
* \array_module
*
* \brief Template functor to compute the exponential of a scalar
*
* \sa class CwiseUnaryOp, Cwise::exp()
*/
template<typename Scalar> struct ei_scalar_exp_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a) const { return ei_exp(a); }
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_exp_op<Scalar> >
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
/** \internal
*
* \array_module
*
* \brief Template functor to compute the logarithm of a scalar
*
* \sa class CwiseUnaryOp, Cwise::log()
*/
template<typename Scalar> struct ei_scalar_log_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a) const { return ei_log(a); }
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_log_op<Scalar> >
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
/** \internal
*
* \array_module
*
* \brief Template functor to compute the cosine of a scalar
*
* \sa class CwiseUnaryOp, Cwise::cos()
*/
template<typename Scalar> struct ei_scalar_cos_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a) const { return ei_cos(a); }
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_cos_op<Scalar> >
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
/** \internal
*
* \array_module
*
* \brief Template functor to compute the sine of a scalar
*
* \sa class CwiseUnaryOp, Cwise::sin()
*/
template<typename Scalar> struct ei_scalar_sin_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a) const { return ei_sin(a); }
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_sin_op<Scalar> >
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
/** \internal
*
* \array_module
*
* \brief Template functor to raise a scalar to a power
*
* \sa class CwiseUnaryOp, Cwise::pow
*/
template<typename Scalar>
struct ei_scalar_pow_op {
// FIXME default copy constructors seems bugged with std::complex<>
inline ei_scalar_pow_op(const ei_scalar_pow_op& other) : m_exponent(other.m_exponent) { }
inline ei_scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {}
inline Scalar operator() (const Scalar& a) const { return ei_pow(a, m_exponent); }
const Scalar m_exponent;
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_pow_op<Scalar> >
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
/** \internal
*
* \array_module
*
* \brief Template functor to compute the inverse of a scalar
*
* \sa class CwiseUnaryOp, Cwise::inverse()
*/
template<typename Scalar>
struct ei_scalar_inverse_op {
inline Scalar operator() (const Scalar& a) const { return Scalar(1)/a; }
template<typename PacketScalar>
inline const PacketScalar packetOp(const PacketScalar& a) const
{ return ei_pdiv(ei_pset1(Scalar(1)),a); }
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_inverse_op<Scalar> >
{ enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = int(ei_packet_traits<Scalar>::size)>1 }; };
/** \internal
*
* \array_module
*
* \brief Template functor to compute the square of a scalar
*
* \sa class CwiseUnaryOp, Cwise::square()
*/
template<typename Scalar>
struct ei_scalar_square_op {
inline Scalar operator() (const Scalar& a) const { return a*a; }
template<typename PacketScalar>
inline const PacketScalar packetOp(const PacketScalar& a) const
{ return ei_pmul(a,a); }
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_square_op<Scalar> >
{ enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = int(ei_packet_traits<Scalar>::size)>1 }; };
/** \internal
*
* \array_module
*
* \brief Template functor to compute the cube of a scalar
*
* \sa class CwiseUnaryOp, Cwise::cube()
*/
template<typename Scalar>
struct ei_scalar_cube_op {
inline Scalar operator() (const Scalar& a) const { return a*a*a; }
template<typename PacketScalar>
inline const PacketScalar packetOp(const PacketScalar& a) const
{ return ei_pmul(a,ei_pmul(a,a)); }
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_cube_op<Scalar> >
{ enum { Cost = 2*NumTraits<Scalar>::MulCost, PacketAccess = int(ei_packet_traits<Scalar>::size)>1 }; };
// default ei_functor_traits for STL functors:
template<typename T>
struct ei_functor_traits<std::multiplies<T> >
{ enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
template<typename T>
struct ei_functor_traits<std::divides<T> >
{ enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
template<typename T>
struct ei_functor_traits<std::plus<T> >
{ enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
template<typename T>
struct ei_functor_traits<std::minus<T> >
{ enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
template<typename T>
struct ei_functor_traits<std::negate<T> >
{ enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
template<typename T>
struct ei_functor_traits<std::logical_or<T> >
{ enum { Cost = 1, PacketAccess = false }; };
template<typename T>
struct ei_functor_traits<std::logical_and<T> >
{ enum { Cost = 1, PacketAccess = false }; };
template<typename T>
struct ei_functor_traits<std::logical_not<T> >
{ enum { Cost = 1, PacketAccess = false }; };
template<typename T>
struct ei_functor_traits<std::greater<T> >
{ enum { Cost = 1, PacketAccess = false }; };
template<typename T>
struct ei_functor_traits<std::less<T> >
{ enum { Cost = 1, PacketAccess = false }; };
template<typename T>
struct ei_functor_traits<std::greater_equal<T> >
{ enum { Cost = 1, PacketAccess = false }; };
template<typename T>
struct ei_functor_traits<std::less_equal<T> >
{ enum { Cost = 1, PacketAccess = false }; };
template<typename T>
struct ei_functor_traits<std::equal_to<T> >
{ enum { Cost = 1, PacketAccess = false }; };
template<typename T>
struct ei_functor_traits<std::not_equal_to<T> >
{ enum { Cost = 1, PacketAccess = false }; };
template<typename T>
struct ei_functor_traits<std::binder2nd<T> >
{ enum { Cost = ei_functor_traits<T>::Cost, PacketAccess = false }; };
template<typename T>
struct ei_functor_traits<std::binder1st<T> >
{ enum { Cost = ei_functor_traits<T>::Cost, PacketAccess = false }; };
template<typename T>
struct ei_functor_traits<std::unary_negate<T> >
{ enum { Cost = 1 + ei_functor_traits<T>::Cost, PacketAccess = false }; };
template<typename T>
struct ei_functor_traits<std::binary_negate<T> >
{ enum { Cost = 1 + ei_functor_traits<T>::Cost, PacketAccess = false }; };
#ifdef EIGEN_STDEXT_SUPPORT
template<typename T0,typename T1>
struct ei_functor_traits<std::project1st<T0,T1> >
{ enum { Cost = 0, PacketAccess = false }; };
template<typename T0,typename T1>
struct ei_functor_traits<std::project2nd<T0,T1> >
{ enum { Cost = 0, PacketAccess = false }; };
template<typename T0,typename T1>
struct ei_functor_traits<std::select2nd<std::pair<T0,T1> > >
{ enum { Cost = 0, PacketAccess = false }; };
template<typename T0,typename T1>
struct ei_functor_traits<std::select1st<std::pair<T0,T1> > >
{ enum { Cost = 0, PacketAccess = false }; };
template<typename T0,typename T1>
struct ei_functor_traits<std::unary_compose<T0,T1> >
{ enum { Cost = ei_functor_traits<T0>::Cost + ei_functor_traits<T1>::Cost, PacketAccess = false }; };
template<typename T0,typename T1,typename T2>
struct ei_functor_traits<std::binary_compose<T0,T1,T2> >
{ enum { Cost = ei_functor_traits<T0>::Cost + ei_functor_traits<T1>::Cost + ei_functor_traits<T2>::Cost, PacketAccess = false }; };
#endif // EIGEN_STDEXT_SUPPORT
#endif // EIGEN_ARRAY_FUNCTORS_H

View File

@@ -1,80 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_ARRAY_NORMS_H
#define EIGEN_ARRAY_NORMS_H
template<typename Derived, int p>
struct ei_lpNorm_selector
{
typedef typename NumTraits<typename ei_traits<Derived>::Scalar>::Real RealScalar;
inline static RealScalar run(const MatrixBase<Derived>& m)
{
return ei_pow(m.cwise().abs().cwise().pow(p).sum(), RealScalar(1)/p);
}
};
template<typename Derived>
struct ei_lpNorm_selector<Derived, 1>
{
inline static typename NumTraits<typename ei_traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
{
return m.cwise().abs().sum();
}
};
template<typename Derived>
struct ei_lpNorm_selector<Derived, 2>
{
inline static typename NumTraits<typename ei_traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
{
return m.norm();
}
};
template<typename Derived>
struct ei_lpNorm_selector<Derived, Infinity>
{
inline static typename NumTraits<typename ei_traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
{
return m.cwise().abs().maxCoeff();
}
};
/** \array_module
*
* \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^p\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 ei_traits<Derived>::Scalar>::Real MatrixBase<Derived>::lpNorm() const
{
return ei_lpNorm_selector<Derived, p>::run(*this);
}
#endif // EIGEN_ARRAY_NORMS_H

View File

@@ -1,338 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_PARTIAL_REDUX_H
#define EIGEN_PARTIAL_REDUX_H
/** \array_module \ingroup Array
*
* \class PartialReduxExpr
*
* \brief Generic expression of a partially reduxed matrix
*
* \param MatrixType the type of the matrix we are applying the redux operation
* \param MemberOp type of the member functor
* \param 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 PartialRedux functions,
* and most of the time this is the only way it is used.
*
* \sa class PartialRedux
*/
template< typename MatrixType, typename MemberOp, int Direction>
class PartialReduxExpr;
template<typename MatrixType, typename MemberOp, int Direction>
struct ei_traits<PartialReduxExpr<MatrixType, MemberOp, Direction> >
{
typedef typename MemberOp::result_type Scalar;
typedef typename MatrixType::Scalar InputScalar;
typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
typedef typename ei_cleantype<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,
Flags = (unsigned int)_MatrixTypeNested::Flags & HereditaryBits,
TraversalSize = Direction==Vertical ? RowsAtCompileTime : ColsAtCompileTime
};
typedef typename MemberOp::template Cost<InputScalar,int(TraversalSize)> CostOpType;
enum {
CoeffReadCost = TraversalSize * ei_traits<_MatrixTypeNested>::CoeffReadCost + int(CostOpType::value)
};
};
template< typename MatrixType, typename MemberOp, int Direction>
class PartialReduxExpr : ei_no_assignment_operator,
public MatrixBase<PartialReduxExpr<MatrixType, MemberOp, Direction> >
{
public:
EIGEN_GENERIC_PUBLIC_INTERFACE(PartialReduxExpr)
typedef typename ei_traits<PartialReduxExpr>::MatrixTypeNested MatrixTypeNested;
typedef typename ei_traits<PartialReduxExpr>::_MatrixTypeNested _MatrixTypeNested;
PartialReduxExpr(const MatrixType& mat, const MemberOp& func = MemberOp())
: m_matrix(mat), m_functor(func) {}
int rows() const { return (Direction==Vertical ? 1 : m_matrix.rows()); }
int cols() const { return (Direction==Horizontal ? 1 : m_matrix.cols()); }
const Scalar coeff(int i, int j) const
{
if (Direction==Vertical)
return m_functor(m_matrix.col(j));
else
return m_functor(m_matrix.row(i));
}
protected:
const MatrixTypeNested m_matrix;
const MemberOp m_functor;
};
#define EIGEN_MEMBER_FUNCTOR(MEMBER,COST) \
template <typename ResultType> \
struct ei_member_##MEMBER EIGEN_EMPTY_STRUCT { \
typedef ResultType result_type; \
template<typename Scalar, int Size> struct Cost \
{ enum { value = COST }; }; \
template<typename Derived> \
inline ResultType operator()(const MatrixBase<Derived>& mat) const \
{ return mat.MEMBER(); } \
}
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(sum, (Size-1)*NumTraits<Scalar>::AddCost);
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);
/** \internal */
template <typename BinaryOp, typename Scalar>
struct ei_member_redux {
typedef typename ei_result_of<
BinaryOp(Scalar)
>::type result_type;
template<typename _Scalar, int Size> struct Cost
{ enum { value = (Size-1) * ei_functor_traits<BinaryOp>::Cost }; };
ei_member_redux(const BinaryOp func) : m_functor(func) {}
template<typename Derived>
inline result_type operator()(const MatrixBase<Derived>& mat) const
{ return mat.redux(m_functor); }
const BinaryOp m_functor;
};
/** \array_module \ingroup Array
*
* \class PartialRedux
*
* \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 MatrixBase::colwise() and MatrixBase::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 MatrixBase::colwise(), MatrixBase::rowwise(), class PartialReduxExpr
*/
template<typename ExpressionType, int Direction> class PartialRedux
{
public:
typedef typename ei_traits<ExpressionType>::Scalar Scalar;
typedef typename ei_meta_if<ei_must_nest_by_value<ExpressionType>::ret,
ExpressionType, const ExpressionType&>::ret ExpressionTypeNested;
template<template<typename _Scalar> class Functor> struct ReturnType
{
typedef PartialReduxExpr<ExpressionType,
Functor<typename ei_traits<ExpressionType>::Scalar>,
Direction
> Type;
};
template<typename BinaryOp> struct ReduxReturnType
{
typedef PartialReduxExpr<ExpressionType,
ei_member_redux<BinaryOp,typename ei_traits<ExpressionType>::Scalar>,
Direction
> Type;
};
typedef typename ExpressionType::PlainMatrixType CrossReturnType;
inline PartialRedux(const ExpressionType& matrix) : m_matrix(matrix) {}
/** \internal */
inline const ExpressionType& _expression() const { return m_matrix; }
template<typename BinaryOp>
const typename ReduxReturnType<BinaryOp>::Type
redux(const BinaryOp& func = BinaryOp()) const;
/** \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 MatrixBase::minCoeff() */
const typename ReturnType<ei_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 MatrixBase::maxCoeff() */
const typename ReturnType<ei_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 MatrixBase::squaredNorm() */
const typename ReturnType<ei_member_squaredNorm>::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 MatrixBase::norm() */
const typename ReturnType<ei_member_norm>::Type norm() 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 MatrixBase::sum() */
const typename ReturnType<ei_member_sum>::Type sum() 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 MatrixBase::all() */
const typename ReturnType<ei_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 MatrixBase::any() */
const typename ReturnType<ei_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 MatrixBase::count() */
const PartialReduxExpr<ExpressionType, ei_member_count<int>, Direction> count() const
{ return _expression(); }
/** \returns a 3x3 matrix expression of the cross product
* of each column or row of the referenced expression with the \a other vector.
*
* \geometry_module
*
* \sa MatrixBase::cross() */
template<typename OtherDerived>
const CrossReturnType cross(const MatrixBase<OtherDerived>& other) const
{
EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(CrossReturnType,3,3)
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,3)
EIGEN_STATIC_ASSERT((ei_is_same_type<Scalar, typename OtherDerived::Scalar>::ret),
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
if(Direction==Vertical)
return (CrossReturnType()
<< _expression().col(0).cross(other),
_expression().col(1).cross(other),
_expression().col(2).cross(other)).finished();
else
return (CrossReturnType()
<< _expression().row(0).cross(other),
_expression().row(1).cross(other),
_expression().row(2).cross(other)).finished();
}
protected:
ExpressionTypeNested m_matrix;
};
/** \array_module
*
* \returns a PartialRedux wrapper of *this providing additional partial reduction operations
*
* Example: \include MatrixBase_colwise.cpp
* Output: \verbinclude MatrixBase_colwise.out
*
* \sa rowwise(), class PartialRedux
*/
template<typename Derived>
inline const PartialRedux<Derived,Vertical>
MatrixBase<Derived>::colwise() const
{
return derived();
}
/** \array_module
*
* \returns a PartialRedux wrapper of *this providing additional partial reduction operations
*
* Example: \include MatrixBase_rowwise.cpp
* Output: \verbinclude MatrixBase_rowwise.out
*
* \sa colwise(), class PartialRedux
*/
template<typename Derived>
inline const PartialRedux<Derived,Horizontal>
MatrixBase<Derived>::rowwise() const
{
return derived();
}
/** \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 PartialRedux, MatrixBase::colwise(), MatrixBase::rowwise()
*/
template<typename ExpressionType, int Direction>
template<typename BinaryOp>
const typename PartialRedux<ExpressionType,Direction>::template ReduxReturnType<BinaryOp>::Type
PartialRedux<ExpressionType,Direction>::redux(const BinaryOp& func) const
{
return typename ReduxReturnType<BinaryOp>::Type(_expression(), func);
}
#endif // EIGEN_PARTIAL_REDUX_H

View File

@@ -1,121 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_RANDOM_H
#define EIGEN_RANDOM_H
template<typename Scalar> struct ei_scalar_random_op EIGEN_EMPTY_STRUCT {
inline ei_scalar_random_op(void) {}
inline const Scalar operator() (int, int) const { return ei_random<Scalar>(); }
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_random_op<Scalar> >
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false, IsRepeatable = false }; };
/** \array_module
*
* \returns a random matrix (not an expression, the matrix is immediately evaluated).
*
* 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 ei_random() should be used
* instead.
*
* \addexample RandomExample \label How to create a matrix with random coefficients
*
* Example: \include MatrixBase_random_int_int.cpp
* Output: \verbinclude MatrixBase_random_int_int.out
*
* \sa MatrixBase::setRandom(), MatrixBase::Random(int), MatrixBase::Random()
*/
template<typename Derived>
inline const CwiseNullaryOp<ei_scalar_random_op<typename ei_traits<Derived>::Scalar>, Derived>
MatrixBase<Derived>::Random(int rows, int cols)
{
return NullaryExpr(rows, cols, ei_scalar_random_op<Scalar>());
}
/** \array_module
*
* \returns a random vector (not an expression, the vector is immediately evaluated).
*
* 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 ei_random() should be used
* instead.
*
* Example: \include MatrixBase_random_int.cpp
* Output: \verbinclude MatrixBase_random_int.out
*
* \sa MatrixBase::setRandom(), MatrixBase::Random(int,int), MatrixBase::Random()
*/
template<typename Derived>
inline const CwiseNullaryOp<ei_scalar_random_op<typename ei_traits<Derived>::Scalar>, Derived>
MatrixBase<Derived>::Random(int size)
{
return NullaryExpr(size, ei_scalar_random_op<Scalar>());
}
/** \array_module
*
* \returns a fixed-size random matrix or vector
* (not an expression, the matrix is immediately evaluated).
*
* 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
*
* \sa MatrixBase::setRandom(), MatrixBase::Random(int,int), MatrixBase::Random(int)
*/
template<typename Derived>
inline const CwiseNullaryOp<ei_scalar_random_op<typename ei_traits<Derived>::Scalar>, Derived>
MatrixBase<Derived>::Random()
{
return NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, ei_scalar_random_op<Scalar>());
}
/** \array_module
*
* Sets all coefficients in this expression to random values.
*
* Example: \include MatrixBase_setRandom.cpp
* Output: \verbinclude MatrixBase_setRandom.out
*
* \sa class CwiseNullaryOp, MatrixBase::setRandom(int,int)
*/
template<typename Derived>
inline Derived& MatrixBase<Derived>::setRandom()
{
return *this = Random(rows(), cols());
}
#endif // EIGEN_RANDOM_H

View File

@@ -1,10 +1,7 @@
ADD_SUBDIRECTORY(Core)
ADD_SUBDIRECTORY(LU)
ADD_SUBDIRECTORY(QR)
ADD_SUBDIRECTORY(SVD)
ADD_SUBDIRECTORY(Cholesky)
ADD_SUBDIRECTORY(Array)
ADD_SUBDIRECTORY(Geometry)
ADD_SUBDIRECTORY(LeastSquares)
ADD_SUBDIRECTORY(Sparse)
ADD_SUBDIRECTORY(StdVector)
file(GLOB Eigen_src_subdirectories "*")
escape_string_as_regex(ESCAPED_CMAKE_CURRENT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
foreach(f ${Eigen_src_subdirectories})
if(NOT f MATCHES "\\.txt" AND NOT f MATCHES "${ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/[.].+" )
add_subdirectory(${f})
endif()
endforeach()

View File

@@ -2,5 +2,5 @@ FILE(GLOB Eigen_Cholesky_SRCS "*.h")
INSTALL(FILES
${Eigen_Cholesky_SRCS}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Cholesky
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Cholesky COMPONENT Devel
)

View File

@@ -1,7 +1,9 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2009 Keir Mierle <mierle@gmail.com>
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -25,174 +27,435 @@
#ifndef EIGEN_LDLT_H
#define EIGEN_LDLT_H
namespace internal {
template<typename MatrixType, int UpLo> struct LDLT_Traits;
}
/** \ingroup cholesky_Module
*
* \class LDLT
*
* \brief Robust Cholesky decomposition of a matrix and associated features
* \brief Robust Cholesky decomposition of a matrix with pivoting
*
* \param MatrixType the type of the matrix of which we are computing the LDL^T Cholesky decomposition
* \param MatrixType the type of the matrix of which to compute the LDL^T Cholesky decomposition
*
* This class performs a Cholesky decomposition without square root of a symmetric, positive definite
* matrix A such that A = L D L^* = U^* D U, where L is lower triangular with a unit diagonal
* and D is a diagonal matrix.
* 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.
*
* Compared to a standard Cholesky decomposition, avoiding the square roots allows for faster and more
* stable computation.
* 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.
*
* 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.
* 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> class LDLT
/* THIS PART OF THE DOX IS CURRENTLY DISABLED BECAUSE INACCURATE BECAUSE OF BUG IN THE DECOMPOSITION CODE
* 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 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 Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;
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)
{}
LDLT(const MatrixType& matrix)
: m_matrix(matrix.rows(), matrix.cols())
: m_matrix(matrix.rows(), matrix.cols()),
m_transpositions(matrix.rows()),
m_temporary(matrix.rows()),
m_isInitialized(false)
{
compute(matrix);
}
/** \returns the lower triangular matrix L */
inline Part<MatrixType, UnitLowerTriangular> matrixL(void) const { return m_matrix; }
/** \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 DiagonalCoeffs<MatrixType> vectorD(void) const { return m_matrix.diagonal(); }
inline Diagonal<const MatrixType> vectorD(void) const
{
eigen_assert(m_isInitialized && "LDLT is not initialized.");
return m_matrix.diagonal();
}
/** \returns true if the matrix is positive definite */
inline bool isPositiveDefinite(void) const { return m_isPositiveDefinite; }
/** \returns true if the matrix is positive (semidefinite) */
inline bool isPositive(void) const
{
eigen_assert(m_isInitialized && "LDLT is not initialized.");
return m_sign == 1;
}
#ifdef EIGEN2_SUPPORT
inline bool isPositiveDefinite() const
{
return isPositive();
}
#endif
template<typename RhsDerived, typename ResDerived>
bool solve(const MatrixBase<RhsDerived> &b, MatrixBase<ResDerived> *result) const;
/** \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.
*
* \note_about_checking_solutions
*
* \sa solveInPlace(), 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;
void compute(const MatrixType& matrix);
LDLT& compute(const MatrixType& matrix);
/** \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(); }
protected:
/** \internal
* Used to compute and store the cholesky decomposition A = L D L^* = U^* D U.
* 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;
bool m_isPositiveDefinite;
TranspositionType m_transpositions;
TmpMatrixType m_temporary;
int m_sign;
bool m_isInitialized;
};
/** Compute / recompute the LLT decomposition A = L D L^* = U^* D U of \a matrix
*/
template<typename MatrixType>
void LDLT<MatrixType>::compute(const MatrixType& a)
namespace internal {
template<int UpLo> struct ldlt_inplace;
template<> struct ldlt_inplace<Lower>
{
assert(a.rows()==a.cols());
const int size = a.rows();
m_matrix.resize(size, size);
m_isPositiveDefinite = true;
const RealScalar eps = ei_sqrt(precision<Scalar>());
if (size<=1)
template<typename MatrixType, typename TranspositionType, typename Workspace>
static bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, int* sign=0)
{
m_matrix = a;
return;
}
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();
// Let's preallocate a temporay vector to evaluate the matrix-vector product into it.
// Unlike the standard LLT decomposition, here we cannot evaluate it to the destination
// matrix because it a sub-row which is not compatible suitable for efficient packet evaluation.
// (at least if we assume the matrix is col-major)
Matrix<Scalar,MatrixType::RowsAtCompileTime,1> _temporary(size);
// Note that, in this algorithm the rows of the strict upper part of m_matrix is used to store
// column vector, thus the strange .conjugate() and .transpose()...
m_matrix.row(0) = a.row(0).conjugate();
m_matrix.col(0).end(size-1) = m_matrix.row(0).end(size-1) / m_matrix.coeff(0,0);
for (int j = 1; j < size; ++j)
{
RealScalar tmp = ei_real(a.coeff(j,j) - (m_matrix.row(j).start(j) * m_matrix.col(j).start(j).conjugate()).coeff(0,0));
m_matrix.coeffRef(j,j) = tmp;
if (tmp < eps)
if (size <= 1)
{
m_isPositiveDefinite = false;
return;
transpositions.setIdentity();
if(sign)
*sign = real(mat.coeff(0,0))>0 ? 1:-1;
return true;
}
int endSize = size-j-1;
if (endSize>0)
RealScalar cutoff = 0, biggest_in_corner;
for (Index k = 0; k < size; ++k)
{
_temporary.end(endSize) = ( m_matrix.block(j+1,0, endSize, j)
* m_matrix.col(j).start(j).conjugate() ).lazy();
// 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;
m_matrix.row(j).end(endSize) = a.row(j).end(endSize).conjugate()
- _temporary.end(endSize).transpose();
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);
m_matrix.col(j).end(endSize) = m_matrix.row(j).end(endSize) / tmp;
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;
}
}
};
/** Computes the solution x of \f$ A x = b \f$ using the current decomposition of A.
* The result is stored in \a result
*
* \returns true in case of success, false otherwise.
*
* In other words, it computes \f$ b = A^{-1} b \f$ with
* \f$ {L^{*}}^{-1} D^{-1} L^{-1} b \f$ from right to left.
*
* \sa LDLT::solveInPlace(), MatrixBase::ldlt()
*/
template<typename MatrixType>
template<typename RhsDerived, typename ResDerived>
bool LDLT<MatrixType>
::solve(const MatrixBase<RhsDerived> &b, MatrixBase<ResDerived> *result) const
template<> struct ldlt_inplace<Upper>
{
const int size = m_matrix.rows();
ei_assert(size==b.rows() && "LLT::solve(): invalid number of rows of the right hand side matrix b");
*result = b;
return solveInPlace(*result);
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> struct LDLT_Traits<MatrixType,Lower>
{
typedef TriangularView<MatrixType, UnitLower> MatrixL;
typedef TriangularView<typename MatrixType::AdjointReturnType, UnitUpper> MatrixU;
inline static MatrixL getL(const MatrixType& m) { return m; }
inline static MatrixU getU(const MatrixType& m) { return m.adjoint(); }
};
template<typename MatrixType> struct LDLT_Traits<MatrixType,Upper>
{
typedef TriangularView<typename MatrixType::AdjointReturnType, UnitLower> MatrixL;
typedef TriangularView<MatrixType, UnitUpper> MatrixU;
inline static MatrixL getL(const MatrixType& m) { return m.adjoint(); }
inline static 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;
}
/** This is the \em in-place version of solve().
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)
dst = dec().vectorD().asDiagonal().inverse() * dst;
// 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>
template<typename MatrixType,int _UpLo>
template<typename Derived>
bool LDLT<MatrixType>::solveInPlace(MatrixBase<Derived> &bAndX) const
bool LDLT<MatrixType,_UpLo>::solveInPlace(MatrixBase<Derived> &bAndX) const
{
const int size = m_matrix.rows();
ei_assert(size==bAndX.rows());
if (!m_isPositiveDefinite)
return false;
matrixL().solveTriangularInPlace(bAndX);
bAndX = (m_matrix.cwise().inverse().template part<Diagonal>() * bAndX).lazy();
m_matrix.adjoint().template part<UnitUpperTriangular>().solveTriangularInPlace(bAndX);
eigen_assert(m_isInitialized && "LDLT is not initialized.");
const Index size = m_matrix.rows();
eigen_assert(size == 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 without square root of \c *this
* \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>::PlainMatrixType>
inline const LDLT<typename MatrixBase<Derived>::PlainObject>
MatrixBase<Derived>::ldlt() const
{
return derived();
return LDLT<PlainObject>(derived());
}
#endif // EIGEN_LDLT_H

View File

@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -25,6 +25,10 @@
#ifndef EIGEN_LLT_H
#define EIGEN_LLT_H
namespace internal{
template<typename MatrixType, int UpLo> struct LLT_Traits;
}
/** \ingroup cholesky_Module
*
* \class LLT
@@ -41,44 +45,138 @@
* and even faster. Nevertheless, this standard Cholesky decomposition remains useful in many other
* situations like generalised eigen problems with hermitian matrices.
*
* 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.
* 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.
*
* \sa MatrixBase::llt(), class LDLT
*/
template<typename MatrixType> class LLT
/* 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
{
private:
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 Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;
typedef typename MatrixType::Index Index;
enum {
PacketSize = ei_packet_traits<Scalar>::size,
AlignmentMask = int(PacketSize)-1
PacketSize = internal::packet_traits<Scalar>::size,
AlignmentMask = int(PacketSize)-1,
UpLo = _UpLo
};
public:
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_matrix(matrix.rows(), matrix.cols()),
m_isInitialized(false)
{
compute(matrix);
}
/** \returns the lower triangular matrix L */
inline Part<MatrixType, LowerTriangular> matrixL(void) const { return m_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 true if the matrix is positive definite */
inline bool isPositiveDefinite(void) const { return m_isPositiveDefinite; }
/** \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);
}
template<typename RhsDerived, typename ResDerived>
bool solve(const MatrixBase<RhsDerived> &b, MatrixBase<ResDerived> *result) const;
/** \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>
bool solveInPlace(MatrixBase<Derived> &bAndX) const;
void solveInPlace(MatrixBase<Derived> &bAndX) const;
void compute(const MatrixType& matrix);
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(); }
protected:
/** \internal
@@ -86,101 +184,203 @@ template<typename MatrixType> class LLT
* The strict upper part is not used and even not initialized.
*/
MatrixType m_matrix;
bool m_isPositiveDefinite;
bool m_isInitialized;
ComputationInfo m_info;
};
namespace internal {
template<int UpLo> struct llt_inplace;
template<> struct llt_inplace<Lower>
{
template<typename MatrixType>
static typename MatrixType::Index unblocked(MatrixType& mat)
{
typedef typename MatrixType::Index Index;
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar;
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<> struct llt_inplace<Upper>
{
template<typename MatrixType>
static EIGEN_STRONG_INLINE typename MatrixType::Index unblocked(MatrixType& mat)
{
Transpose<MatrixType> matt(mat);
return llt_inplace<Lower>::unblocked(matt);
}
template<typename MatrixType>
static EIGEN_STRONG_INLINE typename MatrixType::Index blocked(MatrixType& mat)
{
Transpose<MatrixType> matt(mat);
return llt_inplace<Lower>::blocked(matt);
}
};
template<typename MatrixType> struct LLT_Traits<MatrixType,Lower>
{
typedef TriangularView<MatrixType, Lower> MatrixL;
typedef TriangularView<typename MatrixType::AdjointReturnType, Upper> MatrixU;
inline static MatrixL getL(const MatrixType& m) { return m; }
inline static MatrixU getU(const MatrixType& m) { return m.adjoint(); }
static bool inplace_decomposition(MatrixType& m)
{ return llt_inplace<Lower>::blocked(m)==-1; }
};
template<typename MatrixType> struct LLT_Traits<MatrixType,Upper>
{
typedef TriangularView<typename MatrixType::AdjointReturnType, Lower> MatrixL;
typedef TriangularView<MatrixType, Upper> MatrixU;
inline static MatrixL getL(const MatrixType& m) { return m.adjoint(); }
inline static MatrixU getU(const MatrixType& m) { return m; }
static bool inplace_decomposition(MatrixType& m)
{ return llt_inplace<Upper>::blocked(m)==-1; }
};
} // end namespace internal
/** Computes / recomputes the Cholesky decomposition A = LL^* = U^*U of \a matrix
*
*
* \returns a reference to *this
*/
template<typename MatrixType>
void LLT<MatrixType>::compute(const MatrixType& a)
template<typename MatrixType, int _UpLo>
LLT<MatrixType,_UpLo>& LLT<MatrixType,_UpLo>::compute(const MatrixType& a)
{
assert(a.rows()==a.cols());
const int size = a.rows();
const Index size = a.rows();
m_matrix.resize(size, size);
const RealScalar eps = ei_sqrt(precision<Scalar>());
m_matrix = a;
RealScalar x;
x = ei_real(a.coeff(0,0));
m_isPositiveDefinite = x > eps && ei_isMuchSmallerThan(ei_imag(a.coeff(0,0)), RealScalar(1));
m_matrix.coeffRef(0,0) = ei_sqrt(x);
m_matrix.col(0).end(size-1) = a.row(0).end(size-1).adjoint() / ei_real(m_matrix.coeff(0,0));
for (int j = 1; j < size; ++j)
{
Scalar tmp = ei_real(a.coeff(j,j)) - m_matrix.row(j).start(j).squaredNorm();
x = ei_real(tmp);
if (x < eps || (!ei_isMuchSmallerThan(ei_imag(tmp), RealScalar(1))))
{
m_isPositiveDefinite = false;
return;
}
m_matrix.coeffRef(j,j) = x = ei_sqrt(x);
m_isInitialized = true;
bool ok = Traits::inplace_decomposition(m_matrix);
m_info = ok ? Success : NumericalIssue;
int endSize = size-j-1;
if (endSize>0) {
// Note that when all matrix columns have good alignment, then the following
// product is guaranteed to be optimal with respect to alignment.
m_matrix.col(j).end(endSize) =
(m_matrix.block(j+1, 0, endSize, j) * m_matrix.row(j).start(j).adjoint()).lazy();
// FIXME could use a.col instead of a.row
m_matrix.col(j).end(endSize) = (a.row(j).end(endSize).adjoint()
- m_matrix.col(j).end(endSize) ) / x;
}
}
return *this;
}
/** Computes the solution x of \f$ A x = b \f$ using the current decomposition of A.
* The result is stored in \a result
*
* \returns true in case of success, false otherwise.
*
* In other words, it computes \f$ b = A^{-1} b \f$ with
* \f$ {L^{*}}^{-1} L^{-1} b \f$ from right to left.
*
* Example: \include LLT_solve.cpp
* Output: \verbinclude LLT_solve.out
*
* \sa LLT::solveInPlace(), MatrixBase::llt()
*/
template<typename MatrixType>
template<typename RhsDerived, typename ResDerived>
bool LLT<MatrixType>::solve(const MatrixBase<RhsDerived> &b, MatrixBase<ResDerived> *result) const
namespace internal {
template<typename _MatrixType, int UpLo, typename Rhs>
struct solve_retval<LLT<_MatrixType, UpLo>, Rhs>
: solve_retval_base<LLT<_MatrixType, UpLo>, Rhs>
{
const int size = m_matrix.rows();
ei_assert(size==b.rows() && "LLT::solve(): invalid number of rows of the right hand side matrix b");
return solveInPlace((*result) = b);
typedef LLT<_MatrixType,UpLo> LLTType;
EIGEN_MAKE_SOLVE_HELPERS(LLTType,Rhs)
template<typename Dest> void evalTo(Dest& dst) const
{
dst = rhs();
dec().solveInPlace(dst);
}
};
}
/** This is the \em in-place version of solve().
/** \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>
template<typename MatrixType, int _UpLo>
template<typename Derived>
bool LLT<MatrixType>::solveInPlace(MatrixBase<Derived> &bAndX) const
void LLT<MatrixType,_UpLo>::solveInPlace(MatrixBase<Derived> &bAndX) const
{
const int size = m_matrix.rows();
ei_assert(size==bAndX.rows());
if (!m_isPositiveDefinite)
return false;
matrixL().solveTriangularInPlace(bAndX);
m_matrix.adjoint().template part<UpperTriangular>().solveTriangularInPlace(bAndX);
return true;
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>::PlainMatrixType>
inline const LLT<typename MatrixBase<Derived>::PlainObject>
MatrixBase<Derived>::llt() const
{
return LLT<PlainMatrixType>(derived());
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);
}
#endif // EIGEN_LLT_H

322
Eigen/src/Core/Array.h Normal file
View File

@@ -0,0 +1,322 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_ARRAY_H
#define EIGEN_ARRAY_H
/** \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:
enum { NeedsToAlign = (!(Options&DontAlign))
&& SizeAtCompileTime!=Dynamic && ((static_cast<int>(sizeof(Scalar))*SizeAtCompileTime)%16)==0 };
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
using Base::base;
using Base::coeff;
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)
#endif // EIGEN_ARRAY_H

239
Eigen/src/Core/ArrayBase.h Normal file
View File

@@ -0,0 +1,239 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_ARRAYBASE_H
#define EIGEN_ARRAYBASE_H
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<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(sizeof(typename OtherDerived::Scalar)==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);}
// mixing arrays and matrices is not legal
template<typename OtherDerived> Derived& operator-=(const MatrixBase<OtherDerived>& )
{EIGEN_STATIC_ASSERT(sizeof(typename OtherDerived::Scalar)==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);}
};
/** 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();
}
#endif // EIGEN_ARRAYBASE_H

View File

@@ -0,0 +1,221 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_ARRAYWRAPPER_H
#define EIGEN_ARRAYWRAPPER_H
/** \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::nested<ExpressionType>::type NestedExpressionType;
inline ArrayWrapper(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 Scalar& coeffRef(Index row, Index col) const
{
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);
}
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; }
protected:
const 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::nested<ExpressionType>::type NestedExpressionType;
inline MatrixWrapper(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 Scalar& coeffRef(Index row, Index col) const
{
return m_expression.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);
}
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);
}
protected:
const NestedExpressionType m_expression;
};
#endif // EIGEN_ARRAYWRAPPER_H

View File

@@ -1,9 +1,9 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2007 Michael Olbrich <michael.olbrich@gmx.net>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -27,169 +27,220 @@
#ifndef EIGEN_ASSIGN_H
#define EIGEN_ASSIGN_H
namespace internal {
/***************************************************************************
* Part 1 : the logic deciding a strategy for vectorization and unrolling
* Part 1 : the logic deciding a strategy for traversal and unrolling *
***************************************************************************/
template <typename Derived, typename OtherDerived>
struct ei_assign_traits
struct assign_traits
{
public:
enum {
DstIsAligned = Derived::Flags & AlignedBit,
DstHasDirectAccess = Derived::Flags & DirectAccessBit,
SrcIsAligned = OtherDerived::Flags & AlignedBit,
SrcAlignment = DstIsAligned && SrcIsAligned ? Aligned : Unaligned
JointAlignment = bool(DstIsAligned) && bool(SrcIsAligned) ? Aligned : Unaligned
};
private:
enum {
InnerSize = int(Derived::Flags)&RowMajorBit
? Derived::ColsAtCompileTime
: Derived::RowsAtCompileTime,
InnerMaxSize = int(Derived::Flags)&RowMajorBit
? Derived::MaxColsAtCompileTime
: Derived::MaxRowsAtCompileTime,
PacketSize = ei_packet_traits<typename Derived::Scalar>::size
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 {
MightVectorize = (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit)
&& ((int(Derived::Flags)&RowMajorBit)==(int(OtherDerived::Flags)&RowMajorBit)),
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),
MayLinearVectorize = MightVectorize && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit),
MaySliceVectorize = MightVectorize && 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 */
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 {
Vectorization = int(MayInnerVectorize) ? int(InnerVectorization)
: int(MayLinearVectorize) ? int(LinearVectorization)
: int(MaySliceVectorize) ? int(SliceVectorization)
: int(NoVectorization)
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 * (int(Vectorization) == int(NoVectorization) ? 1 : int(PacketSize)),
MayUnrollCompletely = int(Derived::SizeAtCompileTime) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit),
MayUnrollInner = int(InnerSize * OtherDerived::CoeffReadCost) <= int(UnrollingLimit)
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(Vectorization) == int(InnerVectorization) || int(Vectorization) == int(NoVectorization))
? (
int(MayUnrollCompletely) ? int(CompleteUnrolling)
: int(MayUnrollInner) ? int(InnerUnrolling)
: int(NoUnrolling)
)
: int(Vectorization) == int(LinearVectorization)
? ( int(MayUnrollCompletely) && int(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) )
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
***************************************************************************/
/***********************
*** No vectorization ***
***********************/
/************************
*** Default traversal ***
************************/
template<typename Derived1, typename Derived2, int Index, int Stop>
struct ei_assign_novec_CompleteUnrolling
struct assign_DefaultTraversal_CompleteUnrolling
{
enum {
row = int(Derived1::Flags)&RowMajorBit
? Index / int(Derived1::ColsAtCompileTime)
: Index % Derived1::RowsAtCompileTime,
col = int(Derived1::Flags)&RowMajorBit
? Index % int(Derived1::ColsAtCompileTime)
: Index / Derived1::RowsAtCompileTime
outer = Index / Derived1::InnerSizeAtCompileTime,
inner = Index % Derived1::InnerSizeAtCompileTime
};
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
dst.copyCoeff(row, col, src);
ei_assign_novec_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, 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 ei_assign_novec_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
struct assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
{
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {}
};
template<typename Derived1, typename Derived2, int Index, int Stop>
struct ei_assign_novec_InnerUnrolling
struct assign_DefaultTraversal_InnerUnrolling
{
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int row_or_col)
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int outer)
{
const bool rowMajor = int(Derived1::Flags)&RowMajorBit;
const int row = rowMajor ? row_or_col : Index;
const int col = rowMajor ? Index : row_or_col;
dst.copyCoeff(row, col, src);
ei_assign_novec_InnerUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src, row_or_col);
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 ei_assign_novec_InnerUnrolling<Derived1, Derived2, Stop, Stop>
struct assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Stop, Stop>
{
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &, int) {}
};
/***********************
*** Linear traversal ***
***********************/
template<typename Derived1, typename Derived2, int Index, int Stop>
struct assign_LinearTraversal_CompleteUnrolling
{
EIGEN_STRONG_INLINE static 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>
{
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {}
};
/**************************
*** Inner vectorization ***
**************************/
template<typename Derived1, typename Derived2, int Index, int Stop>
struct ei_assign_innervec_CompleteUnrolling
struct assign_innervec_CompleteUnrolling
{
enum {
row = int(Derived1::Flags)&RowMajorBit
? Index / int(Derived1::ColsAtCompileTime)
: Index % Derived1::RowsAtCompileTime,
col = int(Derived1::Flags)&RowMajorBit
? Index % int(Derived1::ColsAtCompileTime)
: Index / Derived1::RowsAtCompileTime,
SrcAlignment = ei_assign_traits<Derived1,Derived2>::SrcAlignment
outer = Index / Derived1::InnerSizeAtCompileTime,
inner = Index % Derived1::InnerSizeAtCompileTime,
JointAlignment = assign_traits<Derived1,Derived2>::JointAlignment
};
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
dst.template copyPacket<Derived2, Aligned, SrcAlignment>(row, col, src);
ei_assign_innervec_CompleteUnrolling<Derived1, Derived2,
Index+ei_packet_traits<typename Derived1::Scalar>::size, Stop>::run(dst, 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 ei_assign_innervec_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
struct assign_innervec_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
{
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {}
};
template<typename Derived1, typename Derived2, int Index, int Stop>
struct ei_assign_innervec_InnerUnrolling
struct assign_innervec_InnerUnrolling
{
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int row_or_col)
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int outer)
{
const int row = int(Derived1::Flags)&RowMajorBit ? row_or_col : Index;
const int col = int(Derived1::Flags)&RowMajorBit ? Index : row_or_col;
dst.template copyPacket<Derived2, Aligned, Aligned>(row, col, src);
ei_assign_innervec_InnerUnrolling<Derived1, Derived2,
Index+ei_packet_traits<typename Derived1::Scalar>::size, Stop>::run(dst, src, row_or_col);
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 ei_assign_innervec_InnerUnrolling<Derived1, Derived2, Stop, Stop>
struct assign_innervec_InnerUnrolling<Derived1, Derived2, Stop, Stop>
{
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &, int) {}
};
@@ -199,53 +250,80 @@ struct ei_assign_innervec_InnerUnrolling<Derived1, Derived2, Stop, Stop>
***************************************************************************/
template<typename Derived1, typename Derived2,
int Vectorization = ei_assign_traits<Derived1, Derived2>::Vectorization,
int Unrolling = ei_assign_traits<Derived1, Derived2>::Unrolling>
struct ei_assign_impl;
int Traversal = assign_traits<Derived1, Derived2>::Traversal,
int Unrolling = assign_traits<Derived1, Derived2>::Unrolling>
struct assign_impl;
/***********************
*** No vectorization ***
***********************/
/************************
*** Default traversal ***
************************/
template<typename Derived1, typename Derived2, int Unrolling>
struct assign_impl<Derived1, Derived2, InvalidTraversal, Unrolling>
{
inline static void run(Derived1 &, const Derived2 &) { }
};
template<typename Derived1, typename Derived2>
struct ei_assign_impl<Derived1, Derived2, NoVectorization, NoUnrolling>
struct assign_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling>
{
typedef typename Derived1::Index Index;
inline static void run(Derived1 &dst, const Derived2 &src)
{
const int innerSize = dst.innerSize();
const int outerSize = dst.outerSize();
for(int j = 0; j < outerSize; ++j)
for(int i = 0; i < innerSize; ++i)
{
if(int(Derived1::Flags)&RowMajorBit)
dst.copyCoeff(j, i, src);
else
dst.copyCoeff(i, j, 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>
struct ei_assign_impl<Derived1, Derived2, NoVectorization, CompleteUnrolling>
struct assign_impl<Derived1, Derived2, DefaultTraversal, CompleteUnrolling>
{
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
ei_assign_novec_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
::run(dst, src);
}
};
template<typename Derived1, typename Derived2>
struct ei_assign_impl<Derived1, Derived2, NoVectorization, InnerUnrolling>
struct assign_impl<Derived1, Derived2, DefaultTraversal, InnerUnrolling>
{
typedef typename Derived1::Index Index;
EIGEN_STRONG_INLINE static 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>
struct assign_impl<Derived1, Derived2, LinearTraversal, NoUnrolling>
{
typedef typename Derived1::Index Index;
inline static 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>
struct assign_impl<Derived1, Derived2, LinearTraversal, CompleteUnrolling>
{
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
const bool rowMajor = int(Derived1::Flags)&RowMajorBit;
const int innerSize = rowMajor ? Derived1::ColsAtCompileTime : Derived1::RowsAtCompileTime;
const int outerSize = dst.outerSize();
for(int j = 0; j < outerSize; ++j)
ei_assign_novec_InnerUnrolling<Derived1, Derived2, 0, innerSize>
::run(dst, src, j);
assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
::run(dst, src);
}
};
@@ -254,45 +332,40 @@ struct ei_assign_impl<Derived1, Derived2, NoVectorization, InnerUnrolling>
**************************/
template<typename Derived1, typename Derived2>
struct ei_assign_impl<Derived1, Derived2, InnerVectorization, NoUnrolling>
struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, NoUnrolling>
{
typedef typename Derived1::Index Index;
inline static void run(Derived1 &dst, const Derived2 &src)
{
const int innerSize = dst.innerSize();
const int outerSize = dst.outerSize();
const int packetSize = ei_packet_traits<typename Derived1::Scalar>::size;
for(int j = 0; j < outerSize; ++j)
for(int i = 0; i < innerSize; i+=packetSize)
{
if(int(Derived1::Flags)&RowMajorBit)
dst.template copyPacket<Derived2, Aligned, Aligned>(j, i, src);
else
dst.template copyPacket<Derived2, Aligned, Aligned>(i, j, 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>
struct ei_assign_impl<Derived1, Derived2, InnerVectorization, CompleteUnrolling>
struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, CompleteUnrolling>
{
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
ei_assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
::run(dst, src);
}
};
template<typename Derived1, typename Derived2>
struct ei_assign_impl<Derived1, Derived2, InnerVectorization, InnerUnrolling>
struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, InnerUnrolling>
{
typedef typename Derived1::Index Index;
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
const bool rowMajor = int(Derived1::Flags)&RowMajorBit;
const int innerSize = rowMajor ? Derived1::ColsAtCompileTime : Derived1::RowsAtCompileTime;
const int outerSize = dst.outerSize();
for(int j = 0; j < outerSize; ++j)
ei_assign_innervec_InnerUnrolling<Derived1, Derived2, 0, innerSize>
::run(dst, src, j);
const Index outerSize = dst.outerSize();
for(Index outer = 0; outer < outerSize; ++outer)
assign_innervec_InnerUnrolling<Derived1, Derived2, 0, Derived1::InnerSizeAtCompileTime>
::run(dst, src, outer);
}
};
@@ -300,41 +373,71 @@ struct ei_assign_impl<Derived1, Derived2, InnerVectorization, InnerUnrolling>
*** Linear vectorization ***
***************************/
template<typename Derived1, typename Derived2>
struct ei_assign_impl<Derived1, Derived2, LinearVectorization, NoUnrolling>
template <bool IsAligned = false>
struct unaligned_assign_impl
{
inline static void run(Derived1 &dst, const Derived2 &src)
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
{
const int size = dst.size();
const int packetSize = ei_packet_traits<typename Derived1::Scalar>::size;
const int alignedStart = ei_assign_traits<Derived1,Derived2>::DstIsAligned ? 0
: ei_alignmentOffset(&dst.coeffRef(0), size);
const int alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize;
for(int index = 0; index < alignedStart; ++index)
dst.copyCoeff(index, src);
for(int index = alignedStart; index < alignedEnd; index += packetSize)
{
dst.template copyPacket<Derived2, Aligned, ei_assign_traits<Derived1,Derived2>::SrcAlignment>(index, src);
}
for(int index = alignedEnd; index < size; ++index)
for (typename Derived::Index index = start; index < end; ++index)
dst.copyCoeff(index, src);
}
};
template<typename Derived1, typename Derived2>
struct ei_assign_impl<Derived1, Derived2, LinearVectorization, CompleteUnrolling>
struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling>
{
typedef typename Derived1::Index Index;
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
const int size = Derived1::SizeAtCompileTime;
const int packetSize = ei_packet_traits<typename Derived1::Scalar>::size;
const int alignedSize = (size/packetSize)*packetSize;
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
: first_aligned(&dst.coeffRef(0), size);
const Index alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize;
ei_assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, alignedSize>::run(dst, src);
ei_assign_novec_CompleteUnrolling<Derived1, Derived2, alignedSize, size>::run(dst, src);
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>
struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, CompleteUnrolling>
{
typedef typename Derived1::Index Index;
EIGEN_STRONG_INLINE static 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);
}
};
@@ -343,103 +446,148 @@ struct ei_assign_impl<Derived1, Derived2, LinearVectorization, CompleteUnrolling
***************************/
template<typename Derived1, typename Derived2>
struct ei_assign_impl<Derived1, Derived2, SliceVectorization, NoUnrolling>
struct assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling>
{
typedef typename Derived1::Index Index;
inline static void run(Derived1 &dst, const Derived2 &src)
{
const int packetSize = ei_packet_traits<typename Derived1::Scalar>::size;
const int packetAlignedMask = packetSize - 1;
const int innerSize = dst.innerSize();
const int outerSize = dst.outerSize();
const int alignedStep = (packetSize - dst.stride() % packetSize) & packetAlignedMask;
int alignedStart = ei_assign_traits<Derived1,Derived2>::DstIsAligned ? 0
: ei_alignmentOffset(&dst.coeffRef(0), innerSize);
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
: first_aligned(&dst.coeffRef(0,0), innerSize);
for(int i = 0; i < outerSize; ++i)
for(Index outer = 0; outer < outerSize; ++outer)
{
const int alignedEnd = alignedStart + ((innerSize-alignedStart) & ~packetAlignedMask);
const Index alignedEnd = alignedStart + ((innerSize-alignedStart) & ~packetAlignedMask);
// do the non-vectorizable part of the assignment
for (int index = 0; index<alignedStart ; ++index)
{
if(Derived1::Flags&RowMajorBit)
dst.copyCoeff(i, index, src);
else
dst.copyCoeff(index, i, src);
}
for(Index inner = 0; inner<alignedStart ; ++inner)
dst.copyCoeffByOuterInner(outer, inner, src);
// do the vectorizable part of the assignment
for (int index = alignedStart; index<alignedEnd; index+=packetSize)
{
if(Derived1::Flags&RowMajorBit)
dst.template copyPacket<Derived2, Aligned, Unaligned>(i, index, src);
else
dst.template copyPacket<Derived2, Aligned, Unaligned>(index, i, src);
}
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 (int index = alignedEnd; index<innerSize ; ++index)
{
if(Derived1::Flags&RowMajorBit)
dst.copyCoeff(i, index, src);
else
dst.copyCoeff(index, i, src);
}
for(Index inner = alignedEnd; inner<innerSize ; ++inner)
dst.copyCoeffByOuterInner(outer, inner, src);
alignedStart = std::min<int>((alignedStart+alignedStep)%packetSize, innerSize);
alignedStart = std::min<Index>((alignedStart+alignedStep)%packetSize, innerSize);
}
}
};
} // end namespace internal
/***************************************************************************
* Part 4 : implementation of MatrixBase methods
* Part 4 : implementation of DenseBase methods
***************************************************************************/
template<typename Derived>
template<typename OtherDerived>
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>
::lazyAssign(const MatrixBase<OtherDerived>& other)
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((ei_is_same_type<typename Derived::Scalar, typename OtherDerived::Scalar>::ret),
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
ei_assert(rows() == other.rows() && cols() == other.cols());
ei_assign_impl<Derived, OtherDerived>::run(derived(),other.derived());
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) == int(OtherDerived::ColsAtCompileTime)
&& int(Derived::ColsAtCompileTime) == int(OtherDerived::RowsAtCompileTime)
&& ((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 ei_assign_selector;
struct assign_selector;
template<typename Derived, typename OtherDerived>
struct ei_assign_selector<Derived,OtherDerived,false,false> {
struct assign_selector<Derived,OtherDerived,false,false> {
EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); }
};
template<typename Derived, typename OtherDerived>
struct ei_assign_selector<Derived,OtherDerived,true,false> {
struct assign_selector<Derived,OtherDerived,true,false> {
EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); }
};
template<typename Derived, typename OtherDerived>
struct ei_assign_selector<Derived,OtherDerived,false,true> {
struct assign_selector<Derived,OtherDerived,false,true> {
EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); }
};
template<typename Derived, typename OtherDerived>
struct ei_assign_selector<Derived,OtherDerived,true,true> {
struct assign_selector<Derived,OtherDerived,true,true> {
EIGEN_STRONG_INLINE static 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& MatrixBase<Derived>
::operator=(const MatrixBase<OtherDerived>& other)
EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase<OtherDerived>& other)
{
return ei_assign_selector<Derived,OtherDerived>::run(derived(), other.derived());
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();
}
#endif // EIGEN_ASSIGN_H

345
Eigen/src/Core/BandMatrix.h Normal file
View File

@@ -0,0 +1,345 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_BANDMATRIX_H
#define EIGEN_BANDMATRIX_H
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)
{
//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
#endif // EIGEN_BANDMATRIX_H

View File

@@ -1,8 +1,8 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -27,20 +27,17 @@
#define EIGEN_BLOCK_H
/** \class Block
* \ingroup Core_Module
*
* \brief Expression of a fixed-size or dynamic-size block
*
* \param MatrixType the type of the object in which we are taking a 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 _PacketAccess allows to enforce aligned loads and stores if set to ForceAligned.
* The default is AsRequested. This parameter is internaly used by Eigen
* in expressions such as \code mat.block() += other; \endcode and most of
* the time this is the only way it is used.
* \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 MatrixBase::block(int,int,int,int) and MatrixBase::block<int,int>(int,int) and
* 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,
@@ -51,7 +48,7 @@
* \include class_Block.cpp
* Output: \verbinclude class_Block.out
*
* \note Even though this expression has dynamic size, in the case where \a MatrixType
* \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.
*
@@ -59,695 +56,294 @@
* \include class_FixedBlock.cpp
* Output: \verbinclude class_FixedBlock.out
*
* \sa MatrixBase::block(int,int,int,int), MatrixBase::block(int,int), class VectorBlock
* \sa DenseBase::block(Index,Index,Index,Index), DenseBase::block(Index,Index), class VectorBlock
*/
template<typename MatrixType, int BlockRows, int BlockCols, int _PacketAccess, int _DirectAccessStatus>
struct ei_traits<Block<MatrixType, BlockRows, BlockCols, _PacketAccess, _DirectAccessStatus> >
{
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::Nested MatrixTypeNested;
typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
enum{
RowsAtCompileTime = MatrixType::RowsAtCompileTime == 1 ? 1 : BlockRows,
ColsAtCompileTime = MatrixType::ColsAtCompileTime == 1 ? 1 : BlockCols,
MaxRowsAtCompileTime = RowsAtCompileTime == 1 ? 1
: (BlockRows==Dynamic ? MatrixType::MaxRowsAtCompileTime : BlockRows),
MaxColsAtCompileTime = ColsAtCompileTime == 1 ? 1
: (BlockCols==Dynamic ? MatrixType::MaxColsAtCompileTime : BlockCols),
RowMajor = int(MatrixType::Flags)&RowMajorBit,
InnerSize = RowMajor ? ColsAtCompileTime : RowsAtCompileTime,
InnerMaxSize = RowMajor ? MaxColsAtCompileTime : MaxRowsAtCompileTime,
MaskPacketAccessBit = (InnerMaxSize == Dynamic || (InnerSize >= ei_packet_traits<Scalar>::size))
? PacketAccessBit : 0,
FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
Flags = (MatrixType::Flags & (HereditaryBits | MaskPacketAccessBit | DirectAccessBit)) | FlagsLinearAccessBit,
CoeffReadCost = MatrixType::CoeffReadCost,
PacketAccess = _PacketAccess
};
typedef typename ei_meta_if<int(PacketAccess)==ForceAligned,
Block<MatrixType, BlockRows, BlockCols, _PacketAccess, _DirectAccessStatus>&,
Block<MatrixType, BlockRows, BlockCols, ForceAligned, _DirectAccessStatus> >::ret AlignedDerivedType;
};
template<typename MatrixType, int BlockRows, int BlockCols, int PacketAccess, int _DirectAccessStatus> class Block
: public MatrixBase<Block<MatrixType, BlockRows, BlockCols, PacketAccess, _DirectAccessStatus> >
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 % packet_traits<Scalar>::size) == 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:
EIGEN_GENERIC_PUBLIC_INTERFACE(Block)
typedef typename internal::dense_xpr_base<Block>::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Block)
class InnerIterator;
/** Column or Row constructor
*/
inline Block(const MatrixType& matrix, int i)
: m_matrix(matrix),
// It is a row if and only if BlockRows==1 and BlockCols==MatrixType::ColsAtCompileTime,
// and it is a column if and only if BlockRows==MatrixType::RowsAtCompileTime and BlockCols==1,
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==MatrixType::ColsAtCompileTime) ? i : 0),
m_startCol( (BlockRows==MatrixType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
m_blockRows(matrix.rows()), // if it is a row, then m_blockRows has a fixed-size of 1, so no pb to try to overwrite it
m_blockCols(matrix.cols()) // same for m_blockCols
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())
{
ei_assert( (i>=0) && (
((BlockRows==1) && (BlockCols==MatrixType::ColsAtCompileTime) && i<matrix.rows())
||((BlockRows==MatrixType::RowsAtCompileTime) && (BlockCols==1) && i<matrix.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(const MatrixType& matrix, int startRow, int startCol)
: m_matrix(matrix), m_startRow(startRow), m_startCol(startCol),
m_blockRows(matrix.rows()), m_blockCols(matrix.cols())
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 && RowsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
ei_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= matrix.rows()
&& startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= matrix.cols());
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(const MatrixType& matrix,
int startRow, int startCol,
int blockRows, int blockCols)
: m_matrix(matrix), m_startRow(startRow), m_startCol(startCol),
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)
{
ei_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
&& (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
ei_assert(startRow >= 0 && blockRows >= 1 && startRow + blockRows <= matrix.rows()
&& startCol >= 0 && blockCols >= 1 && startCol + blockCols <= matrix.cols());
eigen_assert(startRow >= 0 && blockRows >= 0 && startRow + blockRows <= xpr.rows()
&& startCol >= 0 && blockCols >= 0 && startCol + blockCols <= xpr.cols());
}
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
inline int rows() const { return m_blockRows.value(); }
inline int cols() const { return m_blockCols.value(); }
inline Index rows() const { return m_blockRows.value(); }
inline Index cols() const { return m_blockCols.value(); }
inline Scalar& coeffRef(int row, int col)
inline Scalar& coeffRef(Index row, Index col)
{
return m_matrix.const_cast_derived()
EIGEN_STATIC_ASSERT_LVALUE(XprType)
return m_xpr.const_cast_derived()
.coeffRef(row + m_startRow.value(), col + m_startCol.value());
}
inline const Scalar coeff(int row, int col) const
inline const Scalar& coeffRef(Index row, Index col) const
{
return m_matrix.coeff(row + m_startRow.value(), col + m_startCol.value());
return m_xpr.derived()
.coeffRef(row + m_startRow.value(), col + m_startCol.value());
}
inline Scalar& coeffRef(int index)
EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index row, Index col) const
{
return m_matrix.const_cast_derived()
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 coeff(int index) const
inline const Scalar& coeffRef(Index index) const
{
return m_matrix
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(int row, int col) const
inline PacketScalar packet(Index row, Index col) const
{
return m_matrix.template packet<Unaligned>
return m_xpr.template packet<Unaligned>
(row + m_startRow.value(), col + m_startCol.value());
}
template<int LoadMode>
inline void writePacket(int row, int col, const PacketScalar& x)
inline void writePacket(Index row, Index col, const PacketScalar& x)
{
m_matrix.const_cast_derived().template writePacket<Unaligned>
m_xpr.const_cast_derived().template writePacket<Unaligned>
(row + m_startRow.value(), col + m_startCol.value(), x);
}
template<int LoadMode>
inline PacketScalar packet(int index) const
inline PacketScalar packet(Index index) const
{
return m_matrix.template packet<Unaligned>
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(int index, const PacketScalar& x)
inline void writePacket(Index index, const PacketScalar& x)
{
m_matrix.const_cast_derived().template writePacket<Unaligned>
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
protected:
const typename MatrixType::Nested m_matrix;
const ei_int_if_dynamic<MatrixType::RowsAtCompileTime == 1 ? 0 : Dynamic> m_startRow;
const ei_int_if_dynamic<MatrixType::ColsAtCompileTime == 1 ? 0 : Dynamic> m_startCol;
const ei_int_if_dynamic<RowsAtCompileTime> m_blockRows;
const ei_int_if_dynamic<ColsAtCompileTime> m_blockCols;
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 MatrixType, int BlockRows, int BlockCols, int PacketAccess>
class Block<MatrixType,BlockRows,BlockCols,PacketAccess,HasDirectAccess>
: public MapBase<Block<MatrixType, BlockRows, BlockCols,PacketAccess,HasDirectAccess> >
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:
_EIGEN_GENERIC_PUBLIC_INTERFACE(Block, MapBase<Block>)
class InnerIterator;
typedef typename ei_traits<Block>::AlignedDerivedType AlignedDerivedType;
typedef MapBase<Block> Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Block)
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
AlignedDerivedType forceAligned()
{
if (PacketAccess==ForceAligned)
return *this;
else
return Block<MatrixType,BlockRows,BlockCols,ForceAligned,HasDirectAccess>
(m_matrix, Base::m_data, Base::m_rows.value(), Base::m_cols.value());
}
/** Column or Row constructor
*/
inline Block(const MatrixType& matrix, int i)
: Base(&matrix.const_cast_derived().coeffRef(
(BlockRows==1) && (BlockCols==MatrixType::ColsAtCompileTime) ? i : 0,
(BlockRows==MatrixType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
BlockRows==1 ? 1 : matrix.rows(),
BlockCols==1 ? 1 : matrix.cols()),
m_matrix(matrix)
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)
{
ei_assert( (i>=0) && (
((BlockRows==1) && (BlockCols==MatrixType::ColsAtCompileTime) && i<matrix.rows())
||((BlockRows==MatrixType::RowsAtCompileTime) && (BlockCols==1) && i<matrix.cols())));
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(const MatrixType& matrix, int startRow, int startCol)
: Base(&matrix.const_cast_derived().coeffRef(startRow,startCol)), m_matrix(matrix)
inline Block(XprType& xpr, Index startRow, Index startCol)
: Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol))), m_xpr(xpr)
{
ei_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= matrix.rows()
&& startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= matrix.cols());
eigen_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= xpr.rows()
&& startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= xpr.cols());
init();
}
/** Dynamic-size constructor
*/
inline Block(const MatrixType& matrix,
int startRow, int startCol,
int blockRows, int blockCols)
: Base(&matrix.const_cast_derived().coeffRef(startRow,startCol), blockRows, blockCols),
m_matrix(matrix)
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)
{
ei_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
&& (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
ei_assert(startRow >= 0 && blockRows >= 1 && startRow + blockRows <= matrix.rows()
&& startCol >= 0 && blockCols >= 1 && startCol + blockCols <= matrix.cols());
eigen_assert(startRow >= 0 && blockRows >= 0 && startRow + blockRows <= xpr.rows()
&& startCol >= 0 && blockCols >= 0 && startCol + blockCols <= xpr.cols());
init();
}
inline int stride(void) const { return m_matrix.stride(); }
/** \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();
}
/** \internal used by allowAligned() */
inline Block(const MatrixType& matrix, const Scalar* data, int blockRows, int blockCols)
: Base(data, blockRows, blockCols), m_matrix(matrix)
{}
const typename MatrixType::Nested m_matrix;
const typename XprType::Nested m_xpr;
int m_outerStride;
};
/** \returns a dynamic-size expression of a block in *this.
*
* \param startRow the first row in the block
* \param startCol the first column in the block
* \param blockRows the number of rows in the block
* \param blockCols the number of columns in the block
*
* \addexample BlockIntIntIntInt \label How to reference a sub-matrix (dynamic-size)
*
* Example: \include MatrixBase_block_int_int_int_int.cpp
* Output: \verbinclude MatrixBase_block_int_int_int_int.out
*
* \note Even though the returned expression has dynamic size, in the case
* when it is applied to a fixed-size matrix, it inherits a fixed maximal size,
* which means that evaluating it does not cause a dynamic memory allocation.
*
* \sa class Block, block(int,int)
*/
template<typename Derived>
inline typename BlockReturnType<Derived>::Type MatrixBase<Derived>
::block(int startRow, int startCol, int blockRows, int blockCols)
{
return typename BlockReturnType<Derived>::Type(derived(), startRow, startCol, blockRows, blockCols);
}
/** This is the const version of block(int,int,int,int). */
template<typename Derived>
inline const typename BlockReturnType<Derived>::Type MatrixBase<Derived>
::block(int startRow, int startCol, int blockRows, int blockCols) const
{
return typename BlockReturnType<Derived>::Type(derived(), startRow, startCol, blockRows, blockCols);
}
/** \returns a dynamic-size expression of a segment (i.e. a vector block) in *this.
*
* \only_for_vectors
*
* \addexample SegmentIntInt \label How to reference a sub-vector (dynamic size)
*
* \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(int)
*/
template<typename Derived>
inline typename BlockReturnType<Derived>::SubVectorType MatrixBase<Derived>
::segment(int start, int size)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return typename BlockReturnType<Derived>::SubVectorType(derived(), RowsAtCompileTime == 1 ? 0 : start,
ColsAtCompileTime == 1 ? 0 : start,
RowsAtCompileTime == 1 ? 1 : size,
ColsAtCompileTime == 1 ? 1 : size);
}
/** This is the const version of segment(int,int).*/
template<typename Derived>
inline const typename BlockReturnType<Derived>::SubVectorType
MatrixBase<Derived>::segment(int start, int size) const
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return typename BlockReturnType<Derived>::SubVectorType(derived(), RowsAtCompileTime == 1 ? 0 : start,
ColsAtCompileTime == 1 ? 0 : start,
RowsAtCompileTime == 1 ? 1 : size,
ColsAtCompileTime == 1 ? 1 : size);
}
/** \returns a dynamic-size expression of the first coefficients of *this.
*
* \only_for_vectors
*
* \param size the number of coefficients in the block
*
* \addexample BlockInt \label How to reference a sub-vector (fixed-size)
*
* 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(int,int)
*/
template<typename Derived>
inline typename BlockReturnType<Derived,Dynamic>::SubVectorType
MatrixBase<Derived>::start(int size)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return Block<Derived,
RowsAtCompileTime == 1 ? 1 : Dynamic,
ColsAtCompileTime == 1 ? 1 : Dynamic>
(derived(), 0, 0,
RowsAtCompileTime == 1 ? 1 : size,
ColsAtCompileTime == 1 ? 1 : size);
}
/** This is the const version of start(int).*/
template<typename Derived>
inline const typename BlockReturnType<Derived,Dynamic>::SubVectorType
MatrixBase<Derived>::start(int size) const
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return Block<Derived,
RowsAtCompileTime == 1 ? 1 : Dynamic,
ColsAtCompileTime == 1 ? 1 : Dynamic>
(derived(), 0, 0,
RowsAtCompileTime == 1 ? 1 : size,
ColsAtCompileTime == 1 ? 1 : size);
}
/** \returns a dynamic-size expression of the last coefficients of *this.
*
* \only_for_vectors
*
* \param size the number of coefficients in the block
*
* \addexample BlockEnd \label How to reference the end of a vector (fixed-size)
*
* 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(int,int)
*/
template<typename Derived>
inline typename BlockReturnType<Derived,Dynamic>::SubVectorType
MatrixBase<Derived>::end(int size)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return Block<Derived,
RowsAtCompileTime == 1 ? 1 : Dynamic,
ColsAtCompileTime == 1 ? 1 : Dynamic>
(derived(),
RowsAtCompileTime == 1 ? 0 : rows() - size,
ColsAtCompileTime == 1 ? 0 : cols() - size,
RowsAtCompileTime == 1 ? 1 : size,
ColsAtCompileTime == 1 ? 1 : size);
}
/** This is the const version of end(int).*/
template<typename Derived>
inline const typename BlockReturnType<Derived,Dynamic>::SubVectorType
MatrixBase<Derived>::end(int size) const
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return Block<Derived,
RowsAtCompileTime == 1 ? 1 : Dynamic,
ColsAtCompileTime == 1 ? 1 : Dynamic>
(derived(),
RowsAtCompileTime == 1 ? 0 : rows() - size,
ColsAtCompileTime == 1 ? 0 : cols() - size,
RowsAtCompileTime == 1 ? 1 : size,
ColsAtCompileTime == 1 ? 1 : 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 BlockReturnType<Derived,Size>::SubVectorType
MatrixBase<Derived>::segment(int start)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return Block<Derived, (RowsAtCompileTime == 1 ? 1 : Size),
(ColsAtCompileTime == 1 ? 1 : Size)>
(derived(), RowsAtCompileTime == 1 ? 0 : start,
ColsAtCompileTime == 1 ? 0 : start);
}
/** This is the const version of segment<int>(int).*/
template<typename Derived>
template<int Size>
inline const typename BlockReturnType<Derived,Size>::SubVectorType
MatrixBase<Derived>::segment(int start) const
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return Block<Derived, (RowsAtCompileTime == 1 ? 1 : Size),
(ColsAtCompileTime == 1 ? 1 : Size)>
(derived(), RowsAtCompileTime == 1 ? 0 : start,
ColsAtCompileTime == 1 ? 0 : 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
*
* \addexample BlockStart \label How to reference the start of a vector (fixed-size)
*
* 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 BlockReturnType<Derived,Size>::SubVectorType
MatrixBase<Derived>::start()
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return Block<Derived, (RowsAtCompileTime == 1 ? 1 : Size),
(ColsAtCompileTime == 1 ? 1 : Size)>(derived(), 0, 0);
}
/** This is the const version of start<int>().*/
template<typename Derived>
template<int Size>
inline const typename BlockReturnType<Derived,Size>::SubVectorType
MatrixBase<Derived>::start() const
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return Block<Derived, (RowsAtCompileTime == 1 ? 1 : Size),
(ColsAtCompileTime == 1 ? 1 : Size)>(derived(), 0, 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 BlockReturnType<Derived,Size>::SubVectorType
MatrixBase<Derived>::end()
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return Block<Derived, RowsAtCompileTime == 1 ? 1 : Size,
ColsAtCompileTime == 1 ? 1 : Size>
(derived(),
RowsAtCompileTime == 1 ? 0 : rows() - Size,
ColsAtCompileTime == 1 ? 0 : cols() - Size);
}
/** This is the const version of end<int>.*/
template<typename Derived>
template<int Size>
inline const typename BlockReturnType<Derived,Size>::SubVectorType
MatrixBase<Derived>::end() const
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return Block<Derived, RowsAtCompileTime == 1 ? 1 : Size,
ColsAtCompileTime == 1 ? 1 : Size>
(derived(),
RowsAtCompileTime == 1 ? 0 : rows() - Size,
ColsAtCompileTime == 1 ? 0 : cols() - Size);
}
/** \returns a dynamic-size expression of a corner of *this.
*
* \param type the type of corner. Can be \a Eigen::TopLeft, \a Eigen::TopRight,
* \a Eigen::BottomLeft, \a Eigen::BottomRight.
* \param cRows the number of rows in the corner
* \param cCols the number of columns in the corner
*
* \addexample BlockCornerDynamicSize \label How to reference a sub-corner of a matrix
*
* Example: \include MatrixBase_corner_enum_int_int.cpp
* Output: \verbinclude MatrixBase_corner_enum_int_int.out
*
* \note Even though the returned expression has dynamic size, in the case
* when it is applied to a fixed-size matrix, it inherits a fixed maximal size,
* which means that evaluating it does not cause a dynamic memory allocation.
*
* \sa class Block, block(int,int,int,int)
*/
template<typename Derived>
inline typename BlockReturnType<Derived>::Type MatrixBase<Derived>
::corner(CornerType type, int cRows, int cCols)
{
switch(type)
{
default:
ei_assert(false && "Bad corner type.");
case TopLeft:
return typename BlockReturnType<Derived>::Type(derived(), 0, 0, cRows, cCols);
case TopRight:
return typename BlockReturnType<Derived>::Type(derived(), 0, cols() - cCols, cRows, cCols);
case BottomLeft:
return typename BlockReturnType<Derived>::Type(derived(), rows() - cRows, 0, cRows, cCols);
case BottomRight:
return typename BlockReturnType<Derived>::Type(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
}
}
/** This is the const version of corner(CornerType, int, int).*/
template<typename Derived>
inline const typename BlockReturnType<Derived>::Type
MatrixBase<Derived>::corner(CornerType type, int cRows, int cCols) const
{
switch(type)
{
default:
ei_assert(false && "Bad corner type.");
case TopLeft:
return typename BlockReturnType<Derived>::Type(derived(), 0, 0, cRows, cCols);
case TopRight:
return typename BlockReturnType<Derived>::Type(derived(), 0, cols() - cCols, cRows, cCols);
case BottomLeft:
return typename BlockReturnType<Derived>::Type(derived(), rows() - cRows, 0, cRows, cCols);
case BottomRight:
return typename BlockReturnType<Derived>::Type(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
}
}
/** \returns a fixed-size expression of a corner of *this.
*
* \param type the type of corner. Can be \a Eigen::TopLeft, \a Eigen::TopRight,
* \a Eigen::BottomLeft, \a Eigen::BottomRight.
*
* The template parameters CRows and CCols arethe number of rows and columns in the corner.
*
* Example: \include MatrixBase_template_int_int_corner_enum.cpp
* Output: \verbinclude MatrixBase_template_int_int_corner_enum.out
*
* \sa class Block, block(int,int,int,int)
*/
template<typename Derived>
template<int CRows, int CCols>
inline typename BlockReturnType<Derived, CRows, CCols>::Type
MatrixBase<Derived>::corner(CornerType type)
{
switch(type)
{
default:
ei_assert(false && "Bad corner type.");
case TopLeft:
return Block<Derived, CRows, CCols>(derived(), 0, 0);
case TopRight:
return Block<Derived, CRows, CCols>(derived(), 0, cols() - CCols);
case BottomLeft:
return Block<Derived, CRows, CCols>(derived(), rows() - CRows, 0);
case BottomRight:
return Block<Derived, CRows, CCols>(derived(), rows() - CRows, cols() - CCols);
}
}
/** This is the const version of corner<int, int>(CornerType).*/
template<typename Derived>
template<int CRows, int CCols>
inline const typename BlockReturnType<Derived, CRows, CCols>::Type
MatrixBase<Derived>::corner(CornerType type) const
{
switch(type)
{
default:
ei_assert(false && "Bad corner type.");
case TopLeft:
return Block<Derived, CRows, CCols>(derived(), 0, 0);
case TopRight:
return Block<Derived, CRows, CCols>(derived(), 0, cols() - CCols);
case BottomLeft:
return Block<Derived, CRows, CCols>(derived(), rows() - CRows, 0);
case BottomRight:
return Block<Derived, CRows, CCols>(derived(), rows() - CRows, cols() - CCols);
}
}
/** \returns a fixed-size expression of a block in *this.
*
* The template parameters \a BlockRows and \a BlockCols are the number of
* rows and columns in the block.
*
* \param startRow the first row in the block
* \param startCol the first column in the block
*
* \addexample BlockSubMatrixFixedSize \label How to reference a sub-matrix (fixed-size)
*
* Example: \include MatrixBase_block_int_int.cpp
* Output: \verbinclude MatrixBase_block_int_int.out
*
* \note since block is a templated member, the keyword template has to be used
* if the matrix type is also a template parameter: \code m.template block<3,3>(1,1); \endcode
*
* \sa class Block, block(int,int,int,int)
*/
template<typename Derived>
template<int BlockRows, int BlockCols>
inline typename BlockReturnType<Derived, BlockRows, BlockCols>::Type
MatrixBase<Derived>::block(int startRow, int startCol)
{
return Block<Derived, BlockRows, BlockCols>(derived(), startRow, startCol);
}
/** This is the const version of block<>(int, int). */
template<typename Derived>
template<int BlockRows, int BlockCols>
inline const typename BlockReturnType<Derived, BlockRows, BlockCols>::Type
MatrixBase<Derived>::block(int startRow, int startCol) const
{
return Block<Derived, BlockRows, BlockCols>(derived(), startRow, startCol);
}
/** \returns an expression of the \a i-th column of *this. Note that the numbering starts at 0.
*
* \addexample BlockColumn \label How to reference a single column of a matrix
*
* Example: \include MatrixBase_col.cpp
* Output: \verbinclude MatrixBase_col.out
*
* \sa row(), class Block */
template<typename Derived>
inline typename MatrixBase<Derived>::ColXpr
MatrixBase<Derived>::col(int i)
{
return ColXpr(derived(), i);
}
/** This is the const version of col(). */
template<typename Derived>
inline const typename MatrixBase<Derived>::ColXpr
MatrixBase<Derived>::col(int i) const
{
return ColXpr(derived(), i);
}
/** \returns an expression of the \a i-th row of *this. Note that the numbering starts at 0.
*
* \addexample BlockRow \label How to reference a single row of a matrix
*
* Example: \include MatrixBase_row.cpp
* Output: \verbinclude MatrixBase_row.out
*
* \sa col(), class Block */
template<typename Derived>
inline typename MatrixBase<Derived>::RowXpr
MatrixBase<Derived>::row(int i)
{
return RowXpr(derived(), i);
}
/** This is the const version of row(). */
template<typename Derived>
inline const typename MatrixBase<Derived>::RowXpr
MatrixBase<Derived>::row(int i) const
{
return RowXpr(derived(), i);
}
#endif // EIGEN_BLOCK_H

View File

@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -25,8 +25,10 @@
#ifndef EIGEN_ALLANDANY_H
#define EIGEN_ALLANDANY_H
namespace internal {
template<typename Derived, int UnrollCount>
struct ei_all_unroller
struct all_unroller
{
enum {
col = (UnrollCount-1) / Derived::RowsAtCompileTime,
@@ -35,24 +37,24 @@ struct ei_all_unroller
inline static bool run(const Derived &mat)
{
return ei_all_unroller<Derived, UnrollCount-1>::run(mat) && mat.coeff(row, col);
return all_unroller<Derived, UnrollCount-1>::run(mat) && mat.coeff(row, col);
}
};
template<typename Derived>
struct ei_all_unroller<Derived, 1>
struct all_unroller<Derived, 1>
{
inline static bool run(const Derived &mat) { return mat.coeff(0, 0); }
};
template<typename Derived>
struct ei_all_unroller<Derived, Dynamic>
struct all_unroller<Derived, Dynamic>
{
inline static bool run(const Derived &) { return false; }
};
template<typename Derived, int UnrollCount>
struct ei_any_unroller
struct any_unroller
{
enum {
col = (UnrollCount-1) / Derived::RowsAtCompileTime,
@@ -61,85 +63,87 @@ struct ei_any_unroller
inline static bool run(const Derived &mat)
{
return ei_any_unroller<Derived, UnrollCount-1>::run(mat) || mat.coeff(row, col);
return any_unroller<Derived, UnrollCount-1>::run(mat) || mat.coeff(row, col);
}
};
template<typename Derived>
struct ei_any_unroller<Derived, 1>
struct any_unroller<Derived, 1>
{
inline static bool run(const Derived &mat) { return mat.coeff(0, 0); }
};
template<typename Derived>
struct ei_any_unroller<Derived, Dynamic>
struct any_unroller<Derived, Dynamic>
{
inline static bool run(const Derived &) { return false; }
};
/** \array_module
*
* \returns true if all coefficients are true
*
* \addexample CwiseAll \label How to check whether a point is inside a box (using operator< and all())
} // end namespace internal
/** \returns true if all coefficients are true
*
* Example: \include MatrixBase_all.cpp
* Output: \verbinclude MatrixBase_all.out
*
* \sa MatrixBase::any(), Cwise::operator<()
* \sa any(), Cwise::operator<()
*/
template<typename Derived>
inline bool MatrixBase<Derived>::all() const
inline bool DenseBase<Derived>::all() const
{
const bool unroll = SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost)
<= EIGEN_UNROLLING_LIMIT;
enum {
unroll = SizeAtCompileTime != Dynamic
&& CoeffReadCost != Dynamic
&& NumTraits<Scalar>::AddCost != Dynamic
&& SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
};
if(unroll)
return ei_all_unroller<Derived,
return internal::all_unroller<Derived,
unroll ? int(SizeAtCompileTime) : Dynamic
>::run(derived());
else
{
for(int j = 0; j < cols(); ++j)
for(int i = 0; i < rows(); ++i)
for(Index j = 0; j < cols(); ++j)
for(Index i = 0; i < rows(); ++i)
if (!coeff(i, j)) return false;
return true;
}
}
/** \array_module
*
* \returns true if at least one coefficient is true
/** \returns true if at least one coefficient is true
*
* \sa MatrixBase::all()
* \sa all()
*/
template<typename Derived>
inline bool MatrixBase<Derived>::any() const
inline bool DenseBase<Derived>::any() const
{
const bool unroll = SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost)
<= EIGEN_UNROLLING_LIMIT;
enum {
unroll = SizeAtCompileTime != Dynamic
&& CoeffReadCost != Dynamic
&& NumTraits<Scalar>::AddCost != Dynamic
&& SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
};
if(unroll)
return ei_any_unroller<Derived,
return internal::any_unroller<Derived,
unroll ? int(SizeAtCompileTime) : Dynamic
>::run(derived());
else
{
for(int j = 0; j < cols(); ++j)
for(int i = 0; i < rows(); ++i)
for(Index j = 0; j < cols(); ++j)
for(Index i = 0; i < rows(); ++i)
if (coeff(i, j)) return true;
return false;
}
}
/** \array_module
*
* \returns the number of coefficients which evaluate to true
/** \returns the number of coefficients which evaluate to true
*
* \sa MatrixBase::all(), MatrixBase::any()
* \sa all(), any()
*/
template<typename Derived>
inline int MatrixBase<Derived>::count() const
inline typename DenseBase<Derived>::Index DenseBase<Derived>::count() const
{
return this->cast<bool>().cast<int>().sum();
return derived().template cast<bool>().template cast<Index>().sum();
}
#endif // EIGEN_ALLANDANY_H

View File

@@ -2,8 +2,9 @@ FILE(GLOB Eigen_Core_SRCS "*.h")
INSTALL(FILES
${Eigen_Core_SRCS}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Core
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Core COMPONENT Devel
)
ADD_SUBDIRECTORY(products)
ADD_SUBDIRECTORY(util)
ADD_SUBDIRECTORY(arch)

View File

@@ -1,752 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_CACHE_FRIENDLY_PRODUCT_H
#define EIGEN_CACHE_FRIENDLY_PRODUCT_H
template <int L2MemorySize,typename Scalar>
struct ei_L2_block_traits {
enum {width = 8 * ei_meta_sqrt<L2MemorySize/(64*sizeof(Scalar))>::ret };
};
#ifndef EIGEN_EXTERN_INSTANTIATIONS
template<typename Scalar>
static void ei_cache_friendly_product(
int _rows, int _cols, int depth,
bool _lhsRowMajor, const Scalar* _lhs, int _lhsStride,
bool _rhsRowMajor, const Scalar* _rhs, int _rhsStride,
bool resRowMajor, Scalar* res, int resStride)
{
const Scalar* EIGEN_RESTRICT lhs;
const Scalar* EIGEN_RESTRICT rhs;
int lhsStride, rhsStride, rows, cols;
bool lhsRowMajor;
if (resRowMajor)
{
lhs = _rhs;
rhs = _lhs;
lhsStride = _rhsStride;
rhsStride = _lhsStride;
cols = _rows;
rows = _cols;
lhsRowMajor = !_rhsRowMajor;
ei_assert(_lhsRowMajor);
}
else
{
lhs = _lhs;
rhs = _rhs;
lhsStride = _lhsStride;
rhsStride = _rhsStride;
rows = _rows;
cols = _cols;
lhsRowMajor = _lhsRowMajor;
ei_assert(!_rhsRowMajor);
}
typedef typename ei_packet_traits<Scalar>::type PacketType;
enum {
PacketSize = sizeof(PacketType)/sizeof(Scalar),
#if (defined __i386__)
// i386 architecture provides only 8 xmm registers,
// so let's reduce the max number of rows processed at once.
MaxBlockRows = 4,
MaxBlockRows_ClampingMask = 0xFFFFFC,
#else
MaxBlockRows = 8,
MaxBlockRows_ClampingMask = 0xFFFFF8,
#endif
// maximal size of the blocks fitted in L2 cache
MaxL2BlockSize = ei_L2_block_traits<EIGEN_TUNE_FOR_CPU_CACHE_SIZE,Scalar>::width
};
const bool resIsAligned = (PacketSize==1) || (((resStride%PacketSize) == 0) && (size_t(res)%16==0));
const int remainingSize = depth % PacketSize;
const int size = depth - remainingSize; // third dimension of the product clamped to packet boundaries
const int l2BlockRows = MaxL2BlockSize > rows ? rows : MaxL2BlockSize;
const int l2BlockCols = MaxL2BlockSize > cols ? cols : MaxL2BlockSize;
const int l2BlockSize = MaxL2BlockSize > size ? size : MaxL2BlockSize;
const int l2BlockSizeAligned = (1 + std::max(l2BlockSize,l2BlockCols)/PacketSize)*PacketSize;
const bool needRhsCopy = (PacketSize>1) && ((rhsStride%PacketSize!=0) || (size_t(rhs)%16!=0));
Scalar* EIGEN_RESTRICT block = 0;
const int allocBlockSize = l2BlockRows*size;
block = ei_aligned_stack_new(Scalar, allocBlockSize);
Scalar* EIGEN_RESTRICT rhsCopy
= ei_aligned_stack_new(Scalar, l2BlockSizeAligned*l2BlockSizeAligned);
// loops on each L2 cache friendly blocks of the result
for(int l2i=0; l2i<rows; l2i+=l2BlockRows)
{
const int l2blockRowEnd = std::min(l2i+l2BlockRows, rows);
const int l2blockRowEndBW = l2blockRowEnd & MaxBlockRows_ClampingMask; // end of the rows aligned to bw
const int l2blockRemainingRows = l2blockRowEnd - l2blockRowEndBW; // number of remaining rows
//const int l2blockRowEndBWPlusOne = l2blockRowEndBW + (l2blockRemainingRows?0:MaxBlockRows);
// build a cache friendly blocky matrix
int count = 0;
// copy l2blocksize rows of m_lhs to blocks of ps x bw
for(int l2k=0; l2k<size; l2k+=l2BlockSize)
{
const int l2blockSizeEnd = std::min(l2k+l2BlockSize, size);
for (int i = l2i; i<l2blockRowEndBW/*PlusOne*/; i+=MaxBlockRows)
{
// TODO merge the "if l2blockRemainingRows" using something like:
// const int blockRows = std::min(i+MaxBlockRows, rows) - i;
for (int k=l2k; k<l2blockSizeEnd; k+=PacketSize)
{
// TODO write these loops using meta unrolling
// negligible for large matrices but useful for small ones
if (lhsRowMajor)
{
for (int w=0; w<MaxBlockRows; ++w)
for (int s=0; s<PacketSize; ++s)
block[count++] = lhs[(i+w)*lhsStride + (k+s)];
}
else
{
for (int w=0; w<MaxBlockRows; ++w)
for (int s=0; s<PacketSize; ++s)
block[count++] = lhs[(i+w) + (k+s)*lhsStride];
}
}
}
if (l2blockRemainingRows>0)
{
for (int k=l2k; k<l2blockSizeEnd; k+=PacketSize)
{
if (lhsRowMajor)
{
for (int w=0; w<l2blockRemainingRows; ++w)
for (int s=0; s<PacketSize; ++s)
block[count++] = lhs[(l2blockRowEndBW+w)*lhsStride + (k+s)];
}
else
{
for (int w=0; w<l2blockRemainingRows; ++w)
for (int s=0; s<PacketSize; ++s)
block[count++] = lhs[(l2blockRowEndBW+w) + (k+s)*lhsStride];
}
}
}
}
for(int l2j=0; l2j<cols; l2j+=l2BlockCols)
{
int l2blockColEnd = std::min(l2j+l2BlockCols, cols);
for(int l2k=0; l2k<size; l2k+=l2BlockSize)
{
// acumulate bw rows of lhs time a single column of rhs to a bw x 1 block of res
int l2blockSizeEnd = std::min(l2k+l2BlockSize, size);
// if not aligned, copy the rhs block
if (needRhsCopy)
for(int l1j=l2j; l1j<l2blockColEnd; l1j+=1)
{
ei_internal_assert(l2BlockSizeAligned*(l1j-l2j)+(l2blockSizeEnd-l2k) < l2BlockSizeAligned*l2BlockSizeAligned);
memcpy(rhsCopy+l2BlockSizeAligned*(l1j-l2j),&(rhs[l1j*rhsStride+l2k]),(l2blockSizeEnd-l2k)*sizeof(Scalar));
}
// for each bw x 1 result's block
for(int l1i=l2i; l1i<l2blockRowEndBW; l1i+=MaxBlockRows)
{
int offsetblock = l2k * (l2blockRowEnd-l2i) + (l1i-l2i)*(l2blockSizeEnd-l2k) - l2k*MaxBlockRows;
const Scalar* EIGEN_RESTRICT localB = &block[offsetblock];
for(int l1j=l2j; l1j<l2blockColEnd; l1j+=1)
{
const Scalar* EIGEN_RESTRICT rhsColumn;
if (needRhsCopy)
rhsColumn = &(rhsCopy[l2BlockSizeAligned*(l1j-l2j)-l2k]);
else
rhsColumn = &(rhs[l1j*rhsStride]);
PacketType dst[MaxBlockRows];
dst[3] = dst[2] = dst[1] = dst[0] = ei_pset1(Scalar(0.));
if (MaxBlockRows==8)
dst[7] = dst[6] = dst[5] = dst[4] = dst[0];
PacketType tmp;
for(int k=l2k; k<l2blockSizeEnd; k+=PacketSize)
{
tmp = ei_ploadu(&rhsColumn[k]);
PacketType A0, A1, A2, A3, A4, A5;
A0 = ei_pload(localB + k*MaxBlockRows);
A1 = ei_pload(localB + k*MaxBlockRows+1*PacketSize);
A2 = ei_pload(localB + k*MaxBlockRows+2*PacketSize);
A3 = ei_pload(localB + k*MaxBlockRows+3*PacketSize);
if (MaxBlockRows==8) A4 = ei_pload(localB + k*MaxBlockRows+4*PacketSize);
if (MaxBlockRows==8) A5 = ei_pload(localB + k*MaxBlockRows+5*PacketSize);
dst[0] = ei_pmadd(tmp, A0, dst[0]);
if (MaxBlockRows==8) A0 = ei_pload(localB + k*MaxBlockRows+6*PacketSize);
dst[1] = ei_pmadd(tmp, A1, dst[1]);
if (MaxBlockRows==8) A1 = ei_pload(localB + k*MaxBlockRows+7*PacketSize);
dst[2] = ei_pmadd(tmp, A2, dst[2]);
dst[3] = ei_pmadd(tmp, A3, dst[3]);
if (MaxBlockRows==8)
{
dst[4] = ei_pmadd(tmp, A4, dst[4]);
dst[5] = ei_pmadd(tmp, A5, dst[5]);
dst[6] = ei_pmadd(tmp, A0, dst[6]);
dst[7] = ei_pmadd(tmp, A1, dst[7]);
}
}
Scalar* EIGEN_RESTRICT localRes = &(res[l1i + l1j*resStride]);
if (PacketSize>1 && resIsAligned)
{
// the result is aligned: let's do packet reduction
ei_pstore(&(localRes[0]), ei_padd(ei_pload(&(localRes[0])), ei_preduxp(&dst[0])));
if (PacketSize==2)
ei_pstore(&(localRes[2]), ei_padd(ei_pload(&(localRes[2])), ei_preduxp(&(dst[2]))));
if (MaxBlockRows==8)
{
ei_pstore(&(localRes[4]), ei_padd(ei_pload(&(localRes[4])), ei_preduxp(&(dst[4]))));
if (PacketSize==2)
ei_pstore(&(localRes[6]), ei_padd(ei_pload(&(localRes[6])), ei_preduxp(&(dst[6]))));
}
}
else
{
// not aligned => per coeff packet reduction
localRes[0] += ei_predux(dst[0]);
localRes[1] += ei_predux(dst[1]);
localRes[2] += ei_predux(dst[2]);
localRes[3] += ei_predux(dst[3]);
if (MaxBlockRows==8)
{
localRes[4] += ei_predux(dst[4]);
localRes[5] += ei_predux(dst[5]);
localRes[6] += ei_predux(dst[6]);
localRes[7] += ei_predux(dst[7]);
}
}
}
}
if (l2blockRemainingRows>0)
{
int offsetblock = l2k * (l2blockRowEnd-l2i) + (l2blockRowEndBW-l2i)*(l2blockSizeEnd-l2k) - l2k*l2blockRemainingRows;
const Scalar* localB = &block[offsetblock];
for(int l1j=l2j; l1j<l2blockColEnd; l1j+=1)
{
const Scalar* EIGEN_RESTRICT rhsColumn;
if (needRhsCopy)
rhsColumn = &(rhsCopy[l2BlockSizeAligned*(l1j-l2j)-l2k]);
else
rhsColumn = &(rhs[l1j*rhsStride]);
PacketType dst[MaxBlockRows];
dst[3] = dst[2] = dst[1] = dst[0] = ei_pset1(Scalar(0.));
if (MaxBlockRows==8)
dst[7] = dst[6] = dst[5] = dst[4] = dst[0];
// let's declare a few other temporary registers
PacketType tmp;
for(int k=l2k; k<l2blockSizeEnd; k+=PacketSize)
{
tmp = ei_pload(&rhsColumn[k]);
dst[0] = ei_pmadd(tmp, ei_pload(&(localB[k*l2blockRemainingRows ])), dst[0]);
if (l2blockRemainingRows>=2) dst[1] = ei_pmadd(tmp, ei_pload(&(localB[k*l2blockRemainingRows+ PacketSize])), dst[1]);
if (l2blockRemainingRows>=3) dst[2] = ei_pmadd(tmp, ei_pload(&(localB[k*l2blockRemainingRows+2*PacketSize])), dst[2]);
if (l2blockRemainingRows>=4) dst[3] = ei_pmadd(tmp, ei_pload(&(localB[k*l2blockRemainingRows+3*PacketSize])), dst[3]);
if (MaxBlockRows==8)
{
if (l2blockRemainingRows>=5) dst[4] = ei_pmadd(tmp, ei_pload(&(localB[k*l2blockRemainingRows+4*PacketSize])), dst[4]);
if (l2blockRemainingRows>=6) dst[5] = ei_pmadd(tmp, ei_pload(&(localB[k*l2blockRemainingRows+5*PacketSize])), dst[5]);
if (l2blockRemainingRows>=7) dst[6] = ei_pmadd(tmp, ei_pload(&(localB[k*l2blockRemainingRows+6*PacketSize])), dst[6]);
if (l2blockRemainingRows>=8) dst[7] = ei_pmadd(tmp, ei_pload(&(localB[k*l2blockRemainingRows+7*PacketSize])), dst[7]);
}
}
Scalar* EIGEN_RESTRICT localRes = &(res[l2blockRowEndBW + l1j*resStride]);
// process the remaining rows once at a time
localRes[0] += ei_predux(dst[0]);
if (l2blockRemainingRows>=2) localRes[1] += ei_predux(dst[1]);
if (l2blockRemainingRows>=3) localRes[2] += ei_predux(dst[2]);
if (l2blockRemainingRows>=4) localRes[3] += ei_predux(dst[3]);
if (MaxBlockRows==8)
{
if (l2blockRemainingRows>=5) localRes[4] += ei_predux(dst[4]);
if (l2blockRemainingRows>=6) localRes[5] += ei_predux(dst[5]);
if (l2blockRemainingRows>=7) localRes[6] += ei_predux(dst[6]);
if (l2blockRemainingRows>=8) localRes[7] += ei_predux(dst[7]);
}
}
}
}
}
}
if (PacketSize>1 && remainingSize)
{
if (lhsRowMajor)
{
for (int j=0; j<cols; ++j)
for (int i=0; i<rows; ++i)
{
Scalar tmp = lhs[i*lhsStride+size] * rhs[j*rhsStride+size];
// FIXME this loop get vectorized by the compiler !
for (int k=1; k<remainingSize; ++k)
tmp += lhs[i*lhsStride+size+k] * rhs[j*rhsStride+size+k];
res[i+j*resStride] += tmp;
}
}
else
{
for (int j=0; j<cols; ++j)
for (int i=0; i<rows; ++i)
{
Scalar tmp = lhs[i+size*lhsStride] * rhs[j*rhsStride+size];
for (int k=1; k<remainingSize; ++k)
tmp += lhs[i+(size+k)*lhsStride] * rhs[j*rhsStride+size+k];
res[i+j*resStride] += tmp;
}
}
}
ei_aligned_stack_delete(Scalar, block, allocBlockSize);
ei_aligned_stack_delete(Scalar, rhsCopy, l2BlockSizeAligned*l2BlockSizeAligned);
}
#endif // EIGEN_EXTERN_INSTANTIATIONS
/* Optimized col-major matrix * vector product:
* This algorithm processes 4 columns at onces that allows to both reduce
* the number of load/stores of the result by a factor 4 and to reduce
* the instruction dependency. Moreover, we know that all bands have the
* same alignment pattern.
* TODO: since rhs gets evaluated only once, no need to evaluate it
*/
template<typename Scalar, typename RhsType>
static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
int size,
const Scalar* lhs, int lhsStride,
const RhsType& rhs,
Scalar* res)
{
#ifdef _EIGEN_ACCUMULATE_PACKETS
#error _EIGEN_ACCUMULATE_PACKETS has already been defined
#endif
#define _EIGEN_ACCUMULATE_PACKETS(A0,A13,A2,OFFSET) \
ei_pstore(&res[j OFFSET], \
ei_padd(ei_pload(&res[j OFFSET]), \
ei_padd( \
ei_padd(ei_pmul(ptmp0,ei_pload ## A0(&lhs0[j OFFSET])),ei_pmul(ptmp1,ei_pload ## A13(&lhs1[j OFFSET]))), \
ei_padd(ei_pmul(ptmp2,ei_pload ## A2(&lhs2[j OFFSET])),ei_pmul(ptmp3,ei_pload ## A13(&lhs3[j OFFSET]))) )))
typedef typename ei_packet_traits<Scalar>::type Packet;
const int PacketSize = sizeof(Packet)/sizeof(Scalar);
enum { AllAligned = 0, EvenAligned, FirstAligned, NoneAligned };
const int columnsAtOnce = 4;
const int peels = 2;
const int PacketAlignedMask = PacketSize-1;
const int PeelAlignedMask = PacketSize*peels-1;
// How many coeffs of the result do we have to skip to be aligned.
// Here we assume data are at least aligned on the base scalar type that is mandatory anyway.
const int alignedStart = ei_alignmentOffset(res,size);
const int alignedSize = PacketSize>1 ? alignedStart + ((size-alignedStart) & ~PacketAlignedMask) : 0;
const int peeledSize = peels>1 ? alignedStart + ((alignedSize-alignedStart) & ~PeelAlignedMask) : alignedStart;
const int alignmentStep = PacketSize>1 ? (PacketSize - lhsStride % PacketSize) & PacketAlignedMask : 0;
int alignmentPattern = alignmentStep==0 ? AllAligned
: alignmentStep==(PacketSize/2) ? EvenAligned
: FirstAligned;
// we cannot assume the first element is aligned because of sub-matrices
const int lhsAlignmentOffset = ei_alignmentOffset(lhs,size);
// find how many columns do we have to skip to be aligned with the result (if possible)
int skipColumns = 0;
if (PacketSize>1)
{
ei_internal_assert(size_t(lhs+lhsAlignmentOffset)%sizeof(Packet)==0 || size<PacketSize);
while (skipColumns<PacketSize &&
alignedStart != ((lhsAlignmentOffset + alignmentStep*skipColumns)%PacketSize))
++skipColumns;
if (skipColumns==PacketSize)
{
// nothing can be aligned, no need to skip any column
alignmentPattern = NoneAligned;
skipColumns = 0;
}
else
{
skipColumns = std::min(skipColumns,rhs.size());
// note that the skiped columns are processed later.
}
ei_internal_assert((alignmentPattern==NoneAligned) || (size_t(lhs+alignedStart+lhsStride*skipColumns)%sizeof(Packet))==0);
}
int offset1 = (FirstAligned && alignmentStep==1?3:1);
int offset3 = (FirstAligned && alignmentStep==1?1:3);
int columnBound = ((rhs.size()-skipColumns)/columnsAtOnce)*columnsAtOnce + skipColumns;
for (int i=skipColumns; i<columnBound; i+=columnsAtOnce)
{
Packet ptmp0 = ei_pset1(rhs[i]), ptmp1 = ei_pset1(rhs[i+offset1]),
ptmp2 = ei_pset1(rhs[i+2]), ptmp3 = ei_pset1(rhs[i+offset3]);
// this helps a lot generating better binary code
const Scalar *lhs0 = lhs + i*lhsStride, *lhs1 = lhs + (i+offset1)*lhsStride,
*lhs2 = lhs + (i+2)*lhsStride, *lhs3 = lhs + (i+offset3)*lhsStride;
if (PacketSize>1)
{
/* explicit vectorization */
// process initial unaligned coeffs
for (int j=0; j<alignedStart; ++j)
res[j] += ei_pfirst(ptmp0)*lhs0[j] + ei_pfirst(ptmp1)*lhs1[j] + ei_pfirst(ptmp2)*lhs2[j] + ei_pfirst(ptmp3)*lhs3[j];
if (alignedSize>alignedStart)
{
switch(alignmentPattern)
{
case AllAligned:
for (int j = alignedStart; j<alignedSize; j+=PacketSize)
_EIGEN_ACCUMULATE_PACKETS(,,,);
break;
case EvenAligned:
for (int j = alignedStart; j<alignedSize; j+=PacketSize)
_EIGEN_ACCUMULATE_PACKETS(,u,,);
break;
case FirstAligned:
if(peels>1)
{
Packet A00, A01, A02, A03, A10, A11, A12, A13;
A01 = ei_pload(&lhs1[alignedStart-1]);
A02 = ei_pload(&lhs2[alignedStart-2]);
A03 = ei_pload(&lhs3[alignedStart-3]);
for (int j = alignedStart; j<peeledSize; j+=peels*PacketSize)
{
A11 = ei_pload(&lhs1[j-1+PacketSize]); ei_palign<1>(A01,A11);
A12 = ei_pload(&lhs2[j-2+PacketSize]); ei_palign<2>(A02,A12);
A13 = ei_pload(&lhs3[j-3+PacketSize]); ei_palign<3>(A03,A13);
A00 = ei_pload (&lhs0[j]);
A10 = ei_pload (&lhs0[j+PacketSize]);
A00 = ei_pmadd(ptmp0, A00, ei_pload(&res[j]));
A10 = ei_pmadd(ptmp0, A10, ei_pload(&res[j+PacketSize]));
A00 = ei_pmadd(ptmp1, A01, A00);
A01 = ei_pload(&lhs1[j-1+2*PacketSize]); ei_palign<1>(A11,A01);
A00 = ei_pmadd(ptmp2, A02, A00);
A02 = ei_pload(&lhs2[j-2+2*PacketSize]); ei_palign<2>(A12,A02);
A00 = ei_pmadd(ptmp3, A03, A00);
ei_pstore(&res[j],A00);
A03 = ei_pload(&lhs3[j-3+2*PacketSize]); ei_palign<3>(A13,A03);
A10 = ei_pmadd(ptmp1, A11, A10);
A10 = ei_pmadd(ptmp2, A12, A10);
A10 = ei_pmadd(ptmp3, A13, A10);
ei_pstore(&res[j+PacketSize],A10);
}
}
for (int j = peeledSize; j<alignedSize; j+=PacketSize)
_EIGEN_ACCUMULATE_PACKETS(,u,u,);
break;
default:
for (int j = alignedStart; j<alignedSize; j+=PacketSize)
_EIGEN_ACCUMULATE_PACKETS(u,u,u,);
break;
}
}
} // end explicit vectorization
/* process remaining coeffs (or all if there is no explicit vectorization) */
for (int j=alignedSize; j<size; ++j)
res[j] += ei_pfirst(ptmp0)*lhs0[j] + ei_pfirst(ptmp1)*lhs1[j] + ei_pfirst(ptmp2)*lhs2[j] + ei_pfirst(ptmp3)*lhs3[j];
}
// process remaining first and last columns (at most columnsAtOnce-1)
int end = rhs.size();
int start = columnBound;
do
{
for (int i=start; i<end; ++i)
{
Packet ptmp0 = ei_pset1(rhs[i]);
const Scalar* lhs0 = lhs + i*lhsStride;
if (PacketSize>1)
{
/* explicit vectorization */
// process first unaligned result's coeffs
for (int j=0; j<alignedStart; ++j)
res[j] += ei_pfirst(ptmp0) * lhs0[j];
// process aligned result's coeffs
if ((size_t(lhs0+alignedStart)%sizeof(Packet))==0)
for (int j = alignedStart;j<alignedSize;j+=PacketSize)
ei_pstore(&res[j], ei_pmadd(ptmp0,ei_pload(&lhs0[j]),ei_pload(&res[j])));
else
for (int j = alignedStart;j<alignedSize;j+=PacketSize)
ei_pstore(&res[j], ei_pmadd(ptmp0,ei_ploadu(&lhs0[j]),ei_pload(&res[j])));
}
// process remaining scalars (or all if no explicit vectorization)
for (int j=alignedSize; j<size; ++j)
res[j] += ei_pfirst(ptmp0) * lhs0[j];
}
if (skipColumns)
{
start = 0;
end = skipColumns;
skipColumns = 0;
}
else
break;
} while(PacketSize>1);
#undef _EIGEN_ACCUMULATE_PACKETS
}
// TODO add peeling to mask unaligned load/stores
template<typename Scalar, typename ResType>
static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
const Scalar* lhs, int lhsStride,
const Scalar* rhs, int rhsSize,
ResType& res)
{
#ifdef _EIGEN_ACCUMULATE_PACKETS
#error _EIGEN_ACCUMULATE_PACKETS has already been defined
#endif
#define _EIGEN_ACCUMULATE_PACKETS(A0,A13,A2,OFFSET) {\
Packet b = ei_pload(&rhs[j]); \
ptmp0 = ei_pmadd(b, ei_pload##A0 (&lhs0[j]), ptmp0); \
ptmp1 = ei_pmadd(b, ei_pload##A13(&lhs1[j]), ptmp1); \
ptmp2 = ei_pmadd(b, ei_pload##A2 (&lhs2[j]), ptmp2); \
ptmp3 = ei_pmadd(b, ei_pload##A13(&lhs3[j]), ptmp3); }
typedef typename ei_packet_traits<Scalar>::type Packet;
const int PacketSize = sizeof(Packet)/sizeof(Scalar);
enum { AllAligned=0, EvenAligned=1, FirstAligned=2, NoneAligned=3 };
const int rowsAtOnce = 4;
const int peels = 2;
const int PacketAlignedMask = PacketSize-1;
const int PeelAlignedMask = PacketSize*peels-1;
const int size = rhsSize;
// How many coeffs of the result do we have to skip to be aligned.
// Here we assume data are at least aligned on the base scalar type that is mandatory anyway.
const int alignedStart = ei_alignmentOffset(rhs, size);
const int alignedSize = PacketSize>1 ? alignedStart + ((size-alignedStart) & ~PacketAlignedMask) : 0;
const int peeledSize = peels>1 ? alignedStart + ((alignedSize-alignedStart) & ~PeelAlignedMask) : alignedStart;
const int alignmentStep = PacketSize>1 ? (PacketSize - lhsStride % PacketSize) & PacketAlignedMask : 0;
int alignmentPattern = alignmentStep==0 ? AllAligned
: alignmentStep==(PacketSize/2) ? EvenAligned
: FirstAligned;
// we cannot assume the first element is aligned because of sub-matrices
const int lhsAlignmentOffset = ei_alignmentOffset(lhs,size);
// find how many rows do we have to skip to be aligned with rhs (if possible)
int skipRows = 0;
if (PacketSize>1)
{
ei_internal_assert(size_t(lhs+lhsAlignmentOffset)%sizeof(Packet)==0 || size<PacketSize);
while (skipRows<PacketSize &&
alignedStart != ((lhsAlignmentOffset + alignmentStep*skipRows)%PacketSize))
++skipRows;
if (skipRows==PacketSize)
{
// nothing can be aligned, no need to skip any column
alignmentPattern = NoneAligned;
skipRows = 0;
}
else
{
skipRows = std::min(skipRows,res.size());
// note that the skiped columns are processed later.
}
ei_internal_assert((alignmentPattern==NoneAligned) || PacketSize==1
|| (size_t(lhs+alignedStart+lhsStride*skipRows)%sizeof(Packet))==0);
}
int offset1 = (FirstAligned && alignmentStep==1?3:1);
int offset3 = (FirstAligned && alignmentStep==1?1:3);
int rowBound = ((res.size()-skipRows)/rowsAtOnce)*rowsAtOnce + skipRows;
for (int i=skipRows; i<rowBound; i+=rowsAtOnce)
{
Scalar tmp0 = Scalar(0), tmp1 = Scalar(0), tmp2 = Scalar(0), tmp3 = Scalar(0);
// this helps the compiler generating good binary code
const Scalar *lhs0 = lhs + i*lhsStride, *lhs1 = lhs + (i+offset1)*lhsStride,
*lhs2 = lhs + (i+2)*lhsStride, *lhs3 = lhs + (i+offset3)*lhsStride;
if (PacketSize>1)
{
/* explicit vectorization */
Packet ptmp0 = ei_pset1(Scalar(0)), ptmp1 = ei_pset1(Scalar(0)), ptmp2 = ei_pset1(Scalar(0)), ptmp3 = ei_pset1(Scalar(0));
// process initial unaligned coeffs
// FIXME this loop get vectorized by the compiler !
for (int j=0; j<alignedStart; ++j)
{
Scalar b = rhs[j];
tmp0 += b*lhs0[j]; tmp1 += b*lhs1[j]; tmp2 += b*lhs2[j]; tmp3 += b*lhs3[j];
}
if (alignedSize>alignedStart)
{
switch(alignmentPattern)
{
case AllAligned:
for (int j = alignedStart; j<alignedSize; j+=PacketSize)
_EIGEN_ACCUMULATE_PACKETS(,,,);
break;
case EvenAligned:
for (int j = alignedStart; j<alignedSize; j+=PacketSize)
_EIGEN_ACCUMULATE_PACKETS(,u,,);
break;
case FirstAligned:
if (peels>1)
{
/* Here we proccess 4 rows with with two peeled iterations to hide
* tghe overhead of unaligned loads. Moreover unaligned loads are handled
* using special shift/move operations between the two aligned packets
* overlaping the desired unaligned packet. This is *much* more efficient
* than basic unaligned loads.
*/
Packet A01, A02, A03, b, A11, A12, A13;
A01 = ei_pload(&lhs1[alignedStart-1]);
A02 = ei_pload(&lhs2[alignedStart-2]);
A03 = ei_pload(&lhs3[alignedStart-3]);
for (int j = alignedStart; j<peeledSize; j+=peels*PacketSize)
{
b = ei_pload(&rhs[j]);
A11 = ei_pload(&lhs1[j-1+PacketSize]); ei_palign<1>(A01,A11);
A12 = ei_pload(&lhs2[j-2+PacketSize]); ei_palign<2>(A02,A12);
A13 = ei_pload(&lhs3[j-3+PacketSize]); ei_palign<3>(A03,A13);
ptmp0 = ei_pmadd(b, ei_pload (&lhs0[j]), ptmp0);
ptmp1 = ei_pmadd(b, A01, ptmp1);
A01 = ei_pload(&lhs1[j-1+2*PacketSize]); ei_palign<1>(A11,A01);
ptmp2 = ei_pmadd(b, A02, ptmp2);
A02 = ei_pload(&lhs2[j-2+2*PacketSize]); ei_palign<2>(A12,A02);
ptmp3 = ei_pmadd(b, A03, ptmp3);
A03 = ei_pload(&lhs3[j-3+2*PacketSize]); ei_palign<3>(A13,A03);
b = ei_pload(&rhs[j+PacketSize]);
ptmp0 = ei_pmadd(b, ei_pload (&lhs0[j+PacketSize]), ptmp0);
ptmp1 = ei_pmadd(b, A11, ptmp1);
ptmp2 = ei_pmadd(b, A12, ptmp2);
ptmp3 = ei_pmadd(b, A13, ptmp3);
}
}
for (int j = peeledSize; j<alignedSize; j+=PacketSize)
_EIGEN_ACCUMULATE_PACKETS(,u,u,);
break;
default:
for (int j = alignedStart; j<alignedSize; j+=PacketSize)
_EIGEN_ACCUMULATE_PACKETS(u,u,u,);
break;
}
tmp0 += ei_predux(ptmp0);
tmp1 += ei_predux(ptmp1);
tmp2 += ei_predux(ptmp2);
tmp3 += ei_predux(ptmp3);
}
} // end explicit vectorization
// process remaining coeffs (or all if no explicit vectorization)
// FIXME this loop get vectorized by the compiler !
for (int j=alignedSize; j<size; ++j)
{
Scalar b = rhs[j];
tmp0 += b*lhs0[j]; tmp1 += b*lhs1[j]; tmp2 += b*lhs2[j]; tmp3 += b*lhs3[j];
}
res[i] += tmp0; res[i+offset1] += tmp1; res[i+2] += tmp2; res[i+offset3] += tmp3;
}
// process remaining first and last rows (at most columnsAtOnce-1)
int end = res.size();
int start = rowBound;
do
{
for (int i=start; i<end; ++i)
{
Scalar tmp0 = Scalar(0);
Packet ptmp0 = ei_pset1(tmp0);
const Scalar* lhs0 = lhs + i*lhsStride;
// process first unaligned result's coeffs
// FIXME this loop get vectorized by the compiler !
for (int j=0; j<alignedStart; ++j)
tmp0 += rhs[j] * lhs0[j];
if (alignedSize>alignedStart)
{
// process aligned rhs coeffs
if ((size_t(lhs0+alignedStart)%sizeof(Packet))==0)
for (int j = alignedStart;j<alignedSize;j+=PacketSize)
ptmp0 = ei_pmadd(ei_pload(&rhs[j]), ei_pload(&lhs0[j]), ptmp0);
else
for (int j = alignedStart;j<alignedSize;j+=PacketSize)
ptmp0 = ei_pmadd(ei_pload(&rhs[j]), ei_ploadu(&lhs0[j]), ptmp0);
tmp0 += ei_predux(ptmp0);
}
// process remaining scalars
// FIXME this loop get vectorized by the compiler !
for (int j=alignedSize; j<size; ++j)
tmp0 += rhs[j] * lhs0[j];
res[i] += tmp0;
}
if (skipRows)
{
start = 0;
end = skipRows;
skipRows = 0;
}
else
break;
} while(PacketSize>1);
#undef _EIGEN_ACCUMULATE_PACKETS
}
#endif // EIGEN_CACHE_FRIENDLY_PRODUCT_H

View File

@@ -1,384 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_COEFFS_H
#define EIGEN_COEFFS_H
/** Short version: don't use this function, use
* \link operator()(int,int) const \endlink instead.
*
* Long version: this function is similar to
* \link operator()(int,int) 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()(int,int) const \endlink.
*
* \sa operator()(int,int) const, coeffRef(int,int), coeff(int) const
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
::coeff(int row, int col) const
{
ei_internal_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
return derived().coeff(row, col);
}
/** \returns the coefficient at given the given row and column.
*
* \sa operator()(int,int), operator[](int) const
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
::operator()(int row, int col) const
{
ei_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
return derived().coeff(row, col);
}
/** Short version: don't use this function, use
* \link operator()(int,int) \endlink instead.
*
* Long version: this function is similar to
* \link operator()(int,int) \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()(int,int) \endlink.
*
* \sa operator()(int,int), coeff(int, int) const, coeffRef(int)
*/
template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
::coeffRef(int row, int col)
{
ei_internal_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
return derived().coeffRef(row, col);
}
/** \returns a reference to the coefficient at given the given row and column.
*
* \sa operator()(int,int) const, operator[](int)
*/
template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
::operator()(int row, int col)
{
ei_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
return derived().coeffRef(row, col);
}
/** Short version: don't use this function, use
* \link operator[](int) const \endlink instead.
*
* Long version: this function is similar to
* \link operator[](int) 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[](int) const \endlink.
*
* \sa operator[](int) const, coeffRef(int), coeff(int,int) const
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
::coeff(int index) const
{
ei_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[](int), operator()(int,int) const, x() const, y() const,
* z() const, w() const
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
::operator[](int index) const
{
ei_assert(index >= 0 && index < size());
return derived().coeff(index);
}
/** \returns the coefficient at given index.
*
* This is synonymous to operator[](int) const.
*
* This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
*
* \sa operator[](int), operator()(int,int) const, x() const, y() const,
* z() const, w() const
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
::operator()(int index) const
{
ei_assert(index >= 0 && index < size());
return derived().coeff(index);
}
/** Short version: don't use this function, use
* \link operator[](int) \endlink instead.
*
* Long version: this function is similar to
* \link operator[](int) \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[](int) \endlink.
*
* \sa operator[](int), coeff(int) const, coeffRef(int,int)
*/
template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
::coeffRef(int index)
{
ei_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[](int) const, operator()(int,int), x(), y(), z(), w()
*/
template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
::operator[](int index)
{
ei_assert(index >= 0 && index < size());
return derived().coeffRef(index);
}
/** \returns a reference to the coefficient at given index.
*
* This is synonymous to operator[](int).
*
* This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
*
* \sa operator[](int) const, operator()(int,int), x(), y(), z(), w()
*/
template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
::operator()(int index)
{
ei_assert(index >= 0 && index < size());
return derived().coeffRef(index);
}
/** equivalent to operator[](0). */
template<typename Derived>
EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
::x() const { return (*this)[0]; }
/** equivalent to operator[](1). */
template<typename Derived>
EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
::y() const { return (*this)[1]; }
/** equivalent to operator[](2). */
template<typename Derived>
EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
::z() const { return (*this)[2]; }
/** equivalent to operator[](3). */
template<typename Derived>
EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
::w() const { return (*this)[3]; }
/** equivalent to operator[](0). */
template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
::x() { return (*this)[0]; }
/** equivalent to operator[](1). */
template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
::y() { return (*this)[1]; }
/** equivalent to operator[](2). */
template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
::z() { return (*this)[2]; }
/** equivalent to operator[](3). */
template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
::w() { return (*this)[3]; }
/** \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<typename Derived>
template<int LoadMode>
EIGEN_STRONG_INLINE typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type
MatrixBase<Derived>::packet(int row, int col) const
{
ei_internal_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
return derived().template packet<LoadMode>(row,col);
}
/** 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<typename Derived>
template<int StoreMode>
EIGEN_STRONG_INLINE void MatrixBase<Derived>::writePacket
(int row, int col, const typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type& x)
{
ei_internal_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
derived().template writePacket<StoreMode>(row,col,x);
}
/** \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<typename Derived>
template<int LoadMode>
EIGEN_STRONG_INLINE typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type
MatrixBase<Derived>::packet(int index) const
{
ei_internal_assert(index >= 0 && index < size());
return derived().template packet<LoadMode>(index);
}
/** 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<typename Derived>
template<int StoreMode>
EIGEN_STRONG_INLINE void MatrixBase<Derived>::writePacket
(int index, const typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type& x)
{
ei_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 Derived>
template<typename OtherDerived>
EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyCoeff(int row, int col, const MatrixBase<OtherDerived>& other)
{
ei_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 Derived>
template<typename OtherDerived>
EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyCoeff(int index, const MatrixBase<OtherDerived>& other)
{
ei_internal_assert(index >= 0 && index < size());
derived().coeffRef(index) = other.derived().coeff(index);
}
/** \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 Derived>
template<typename OtherDerived, int StoreMode, int LoadMode>
EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyPacket(int row, int col, const MatrixBase<OtherDerived>& other)
{
ei_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 Derived>
template<typename OtherDerived, int StoreMode, int LoadMode>
EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyPacket(int index, const MatrixBase<OtherDerived>& other)
{
ei_internal_assert(index >= 0 && index < size());
derived().template writePacket<StoreMode>(index,
other.derived().template packet<LoadMode>(index));
}
#endif
#endif // EIGEN_COEFFS_H

View File

@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
@@ -27,6 +27,7 @@
#define EIGEN_COMMAINITIALIZER_H
/** \class CommaInitializer
* \ingroup Core_Module
*
* \brief Helper class used by the comma initializer operator
*
@@ -36,70 +37,72 @@
*
* \sa \ref MatrixBaseCommaInitRef "MatrixBase::operator<<", CommaInitializer::finished()
*/
template<typename MatrixType>
template<typename XprType>
struct CommaInitializer
{
typedef typename ei_traits<MatrixType>::Scalar Scalar;
inline CommaInitializer(MatrixType& mat, const Scalar& s)
: m_matrix(mat), m_row(0), m_col(1), m_currentBlockRows(1)
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_matrix.coeffRef(0,0) = s;
m_xpr.coeffRef(0,0) = s;
}
template<typename OtherDerived>
inline CommaInitializer(MatrixType& mat, const MatrixBase<OtherDerived>& other)
: m_matrix(mat), m_row(0), m_col(other.cols()), m_currentBlockRows(other.rows())
inline CommaInitializer(XprType& xpr, const DenseBase<OtherDerived>& other)
: m_xpr(xpr), m_row(0), m_col(other.cols()), m_currentBlockRows(other.rows())
{
m_matrix.block(0, 0, other.rows(), other.cols()) = other;
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_matrix.cols())
if (m_col==m_xpr.cols())
{
m_row+=m_currentBlockRows;
m_col = 0;
m_currentBlockRows = 1;
ei_assert(m_row<m_matrix.rows()
eigen_assert(m_row<m_xpr.rows()
&& "Too many rows passed to comma initializer (operator<<)");
}
ei_assert(m_col<m_matrix.cols()
eigen_assert(m_col<m_xpr.cols()
&& "Too many coefficients passed to comma initializer (operator<<)");
ei_assert(m_currentBlockRows==1);
m_matrix.coeffRef(m_row, m_col++) = s;
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 MatrixBase<OtherDerived>& other)
CommaInitializer& operator,(const DenseBase<OtherDerived>& other)
{
if (m_col==m_matrix.cols())
if (m_col==m_xpr.cols())
{
m_row+=m_currentBlockRows;
m_col = 0;
m_currentBlockRows = other.rows();
ei_assert(m_row+m_currentBlockRows<=m_matrix.rows()
eigen_assert(m_row+m_currentBlockRows<=m_xpr.rows()
&& "Too many rows passed to comma initializer (operator<<)");
}
ei_assert(m_col<m_matrix.cols()
eigen_assert(m_col<m_xpr.cols()
&& "Too many coefficients passed to comma initializer (operator<<)");
ei_assert(m_currentBlockRows==other.rows());
eigen_assert(m_currentBlockRows==other.rows());
if (OtherDerived::SizeAtCompileTime != Dynamic)
m_matrix.template block<OtherDerived::RowsAtCompileTime != Dynamic ? OtherDerived::RowsAtCompileTime : 1,
m_xpr.template block<OtherDerived::RowsAtCompileTime != Dynamic ? OtherDerived::RowsAtCompileTime : 1,
OtherDerived::ColsAtCompileTime != Dynamic ? OtherDerived::ColsAtCompileTime : 1>
(m_row, m_col) = other;
else
m_matrix.block(m_row, m_col, other.rows(), other.cols()) = other;
m_xpr.block(m_row, m_col, other.rows(), other.cols()) = other;
m_col += other.cols();
return *this;
}
inline ~CommaInitializer()
{
ei_assert((m_row+m_currentBlockRows) == m_matrix.rows()
&& m_col == m_matrix.cols()
eigen_assert((m_row+m_currentBlockRows) == m_xpr.rows()
&& m_col == m_xpr.cols()
&& "Too few coefficients passed to comma initializer (operator<<)");
}
@@ -110,12 +113,12 @@ struct CommaInitializer
* quaternion.fromRotationMatrix((Matrix3f() << axis0, axis1, axis2).finished());
* \endcode
*/
inline MatrixType& finished() { return m_matrix; }
inline XprType& finished() { return m_xpr; }
MatrixType& m_matrix; // target matrix
int m_row; // current row id
int m_col; // current col id
int m_currentBlockRows; // current block height
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
@@ -124,15 +127,13 @@ struct CommaInitializer
* The coefficients must be provided in a row major order and exactly match
* the size of the matrix. Otherwise an assertion is raised.
*
* \addexample CommaInit \label How to easily set all the coefficients of a matrix
*
* Example: \include MatrixBase_set.cpp
* Output: \verbinclude MatrixBase_set.out
*
* \sa CommaInitializer::finished(), class CommaInitializer
*/
template<typename Derived>
inline CommaInitializer<Derived> MatrixBase<Derived>::operator<< (const Scalar& s)
inline CommaInitializer<Derived> DenseBase<Derived>::operator<< (const Scalar& s)
{
return CommaInitializer<Derived>(*static_cast<Derived*>(this), s);
}
@@ -141,7 +142,7 @@ inline CommaInitializer<Derived> MatrixBase<Derived>::operator<< (const Scalar&
template<typename Derived>
template<typename OtherDerived>
inline CommaInitializer<Derived>
MatrixBase<Derived>::operator<<(const MatrixBase<OtherDerived>& other)
DenseBase<Derived>::operator<<(const DenseBase<OtherDerived>& other)
{
return CommaInitializer<Derived>(*static_cast<Derived *>(this), other);
}

View File

@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
@@ -27,108 +27,144 @@
#define EIGEN_CWISE_BINARY_OP_H
/** \class CwiseBinaryOp
* \ingroup Core_Module
*
* \brief Generic expression of a coefficient-wise operator between two matrices or vectors
* \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 of a generic binary operator of two matrices or vectors.
* It is the return type of the operator+, operator-, and the Cwise methods, and most
* of the time this is the only way it is used.
* 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.
*
* However, if you want to write a function returning such an expression, you
* will need to use this class.
* 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 ei_traits<CwiseBinaryOp<BinaryOp, Lhs, 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 ei_result_of<
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 ei_unref<LhsNested>::type _LhsNested;
typedef typename ei_unref<RhsNested>::type _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,
RowsAtCompileTime = Lhs::RowsAtCompileTime,
ColsAtCompileTime = Lhs::ColsAtCompileTime,
MaxRowsAtCompileTime = Lhs::MaxRowsAtCompileTime,
MaxColsAtCompileTime = Lhs::MaxColsAtCompileTime,
Flags = (int(LhsFlags) | int(RhsFlags)) & (
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) & (LinearAccessBit | AlignedBit))
| (ei_functor_traits<BinaryOp>::PacketAccess && ((int(LhsFlags) & RowMajorBit)==(int(RhsFlags) & RowMajorBit))
? (int(LhsFlags) & int(RhsFlags) & PacketAccessBit) : 0)),
CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + ei_functor_traits<BinaryOp>::Cost
| (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 : ei_no_assignment_operator,
public MatrixBase<CwiseBinaryOp<BinaryOp, Lhs, 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 ei_traits<CwiseBinaryOp>::LhsNested LhsNested;
typedef typename ei_traits<CwiseBinaryOp>::RhsNested RhsNested;
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)
{
// 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.
EIGEN_STATIC_ASSERT((ei_functor_allows_mixing_real_and_complex<BinaryOp>::ret
? int(ei_is_same_type<typename Lhs::RealScalar, typename Rhs::RealScalar>::ret)
: int(ei_is_same_type<typename Lhs::Scalar, typename Rhs::Scalar>::ret)),
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar);
// require the sizes to match
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs)
ei_assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols());
eigen_assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols());
}
EIGEN_STRONG_INLINE int rows() const { return m_lhs.rows(); }
EIGEN_STRONG_INLINE int cols() const { return m_lhs.cols(); }
EIGEN_STRONG_INLINE const Scalar coeff(int row, int col) const
{
return m_functor(m_lhs.coeff(row, col), m_rhs.coeff(row, col));
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();
}
template<int LoadMode>
EIGEN_STRONG_INLINE PacketScalar packet(int row, int col) const
{
return m_functor.packetOp(m_lhs.template packet<LoadMode>(row, col), m_rhs.template packet<LoadMode>(row, col));
}
EIGEN_STRONG_INLINE const Scalar coeff(int index) const
{
return m_functor(m_lhs.coeff(index), m_rhs.coeff(index));
}
template<int LoadMode>
EIGEN_STRONG_INLINE PacketScalar packet(int index) const
{
return m_functor.packetOp(m_lhs.template packet<LoadMode>(index), m_rhs.template packet<LoadMode>(index));
}
/** \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:
const LhsNested m_lhs;
@@ -136,21 +172,42 @@ class CwiseBinaryOp : ei_no_assignment_operator,
const BinaryOp m_functor;
};
/**\returns an expression of the difference of \c *this and \a other
*
* \note If you want to substract a given scalar from all coefficients, see Cwise::operator-().
*
* \sa class CwiseBinaryOp, MatrixBase::operator-=(), Cwise::operator-()
*/
template<typename Derived>
template<typename OtherDerived>
EIGEN_STRONG_INLINE const CwiseBinaryOp<ei_scalar_difference_op<typename ei_traits<Derived>::Scalar>,
Derived, OtherDerived>
MatrixBase<Derived>::operator-(const MatrixBase<OtherDerived> &other) const
template<typename BinaryOp, typename Lhs, typename Rhs>
class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Dense>
: public internal::dense_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type
{
return CwiseBinaryOp<ei_scalar_difference_op<Scalar>,
Derived, OtherDerived>(derived(), other.derived());
}
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.
*
@@ -161,23 +218,9 @@ template<typename OtherDerived>
EIGEN_STRONG_INLINE Derived &
MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other)
{
return *this = *this - other;
}
/** \relates MatrixBase
*
* \returns an expression of the sum of \c *this and \a other
*
* \note If you want to add a given scalar to all coefficients, see Cwise::operator+().
*
* \sa class CwiseBinaryOp, MatrixBase::operator+=(), Cwise::operator+()
*/
template<typename Derived>
template<typename OtherDerived>
EIGEN_STRONG_INLINE const CwiseBinaryOp<ei_scalar_sum_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived>
MatrixBase<Derived>::operator+(const MatrixBase<OtherDerived> &other) const
{
return CwiseBinaryOp<ei_scalar_sum_op<Scalar>, Derived, OtherDerived>(derived(), other.derived());
SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, Derived, OtherDerived> tmp(derived());
tmp = other.derived();
return derived();
}
/** replaces \c *this by \c *this + \a other.
@@ -189,116 +232,9 @@ template<typename OtherDerived>
EIGEN_STRONG_INLINE Derived &
MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
{
return *this = *this + other;
}
/** \returns an expression of the Schur product (coefficient wise product) of *this and \a other
*
* Example: \include Cwise_product.cpp
* Output: \verbinclude Cwise_product.out
*
* \sa class CwiseBinaryOp, operator/(), square()
*/
template<typename ExpressionType>
template<typename OtherDerived>
EIGEN_STRONG_INLINE const EIGEN_CWISE_PRODUCT_RETURN_TYPE
Cwise<ExpressionType>::operator*(const MatrixBase<OtherDerived> &other) const
{
return EIGEN_CWISE_PRODUCT_RETURN_TYPE(_expression(), other.derived());
}
/** \returns an expression of the coefficient-wise quotient of *this and \a other
*
* Example: \include Cwise_quotient.cpp
* Output: \verbinclude Cwise_quotient.out
*
* \sa class CwiseBinaryOp, operator*(), inverse()
*/
template<typename ExpressionType>
template<typename OtherDerived>
EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op)
Cwise<ExpressionType>::operator/(const MatrixBase<OtherDerived> &other) const
{
return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op)(_expression(), other.derived());
}
/** Replaces this expression by its coefficient-wise product with \a other.
*
* Example: \include Cwise_times_equal.cpp
* Output: \verbinclude Cwise_times_equal.out
*
* \sa operator*(), operator/=()
*/
template<typename ExpressionType>
template<typename OtherDerived>
inline ExpressionType& Cwise<ExpressionType>::operator*=(const MatrixBase<OtherDerived> &other)
{
return m_matrix.const_cast_derived() = *this * other;
}
/** Replaces this expression by its coefficient-wise quotient by \a other.
*
* Example: \include Cwise_slash_equal.cpp
* Output: \verbinclude Cwise_slash_equal.out
*
* \sa operator/(), operator*=()
*/
template<typename ExpressionType>
template<typename OtherDerived>
inline ExpressionType& Cwise<ExpressionType>::operator/=(const MatrixBase<OtherDerived> &other)
{
return m_matrix.const_cast_derived() = *this / other;
}
/** \returns an expression of the coefficient-wise min of *this and \a other
*
* Example: \include Cwise_min.cpp
* Output: \verbinclude Cwise_min.out
*
* \sa class CwiseBinaryOp
*/
template<typename ExpressionType>
template<typename OtherDerived>
EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op)
Cwise<ExpressionType>::min(const MatrixBase<OtherDerived> &other) const
{
return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op)(_expression(), other.derived());
}
/** \returns an expression of the coefficient-wise max of *this and \a other
*
* Example: \include Cwise_max.cpp
* Output: \verbinclude Cwise_max.out
*
* \sa class CwiseBinaryOp
*/
template<typename ExpressionType>
template<typename OtherDerived>
EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op)
Cwise<ExpressionType>::max(const MatrixBase<OtherDerived> &other) const
{
return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op)(_expression(), other.derived());
}
/** \returns an expression of a custom coefficient-wise operator \a func of *this and \a other
*
* The template parameter \a CustomBinaryOp is the type of the functor
* of the custom operator (see class CwiseBinaryOp for an example)
*
* \addexample CustomCwiseBinaryFunctors \label How to use custom coeff wise binary functors
*
* Here is an example illustrating the use of custom functors:
* \include class_CwiseBinaryOp.cpp
* Output: \verbinclude class_CwiseBinaryOp.out
*
* \sa class CwiseBinaryOp, MatrixBase::operator+, MatrixBase::operator-, Cwise::operator*, Cwise::operator/
*/
template<typename Derived>
template<typename CustomBinaryOp, typename OtherDerived>
EIGEN_STRONG_INLINE const CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived>
MatrixBase<Derived>::binaryExpr(const MatrixBase<OtherDerived> &other, const CustomBinaryOp& func) const
{
return CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived>(derived(), other.derived(), func);
SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, Derived, OtherDerived> tmp(derived());
tmp = other.derived();
return derived();
}
#endif // EIGEN_CWISE_BINARY_OP_H

View File

@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -26,81 +26,84 @@
#define EIGEN_CWISE_NULLARY_OP_H
/** \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() functions,
* 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, MatrixBase::NullaryExpr()
* \sa class CwiseUnaryOp, class CwiseBinaryOp, DenseBase::NullaryExpr()
*/
template<typename NullaryOp, typename MatrixType>
struct ei_traits<CwiseNullaryOp<NullaryOp, MatrixType> > : ei_traits<MatrixType>
namespace internal {
template<typename NullaryOp, typename PlainObjectType>
struct traits<CwiseNullaryOp<NullaryOp, PlainObjectType> > : traits<PlainObjectType>
{
enum {
Flags = (ei_traits<MatrixType>::Flags
Flags = (traits<PlainObjectType>::Flags
& ( HereditaryBits
| (ei_functor_has_linear_access<NullaryOp>::ret ? LinearAccessBit : 0)
| (ei_functor_traits<NullaryOp>::PacketAccess ? PacketAccessBit : 0)))
| (ei_functor_traits<NullaryOp>::IsRepeatable ? 0 : EvalBeforeNestingBit),
CoeffReadCost = ei_functor_traits<NullaryOp>::Cost
| (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 MatrixType>
class CwiseNullaryOp : ei_no_assignment_operator,
public MatrixBase<CwiseNullaryOp<NullaryOp, MatrixType> >
template<typename NullaryOp, typename PlainObjectType>
class CwiseNullaryOp : internal::no_assignment_operator,
public internal::dense_xpr_base< CwiseNullaryOp<NullaryOp, PlainObjectType> >::type
{
public:
EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseNullaryOp)
typedef typename internal::dense_xpr_base<CwiseNullaryOp>::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(CwiseNullaryOp)
CwiseNullaryOp(int rows, int cols, const NullaryOp& func = NullaryOp())
CwiseNullaryOp(Index rows, Index cols, const NullaryOp& func = NullaryOp())
: m_rows(rows), m_cols(cols), m_functor(func)
{
ei_assert(rows > 0
&& (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
&& cols > 0
&& (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
eigen_assert(rows >= 0
&& (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
&& cols >= 0
&& (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
}
EIGEN_STRONG_INLINE int rows() const { return m_rows.value(); }
EIGEN_STRONG_INLINE int cols() const { return m_cols.value(); }
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(int rows, int cols) const
EIGEN_STRONG_INLINE const Scalar coeff(Index rows, Index cols) const
{
return m_functor(rows, cols);
}
template<int LoadMode>
EIGEN_STRONG_INLINE PacketScalar packet(int, int) const
EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
{
return m_functor.packetOp();
return m_functor.packetOp(row, col);
}
EIGEN_STRONG_INLINE const Scalar coeff(int index) const
EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
{
if(RowsAtCompileTime == 1)
return m_functor(0, index);
else
return m_functor(index, 0);
return m_functor(index);
}
template<int LoadMode>
EIGEN_STRONG_INLINE PacketScalar packet(int) const
EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
{
return m_functor.packetOp();
return m_functor.packetOp(index);
}
protected:
const ei_int_if_dynamic<RowsAtCompileTime> m_rows;
const ei_int_if_dynamic<ColsAtCompileTime> m_cols;
const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
const NullaryOp m_functor;
};
@@ -121,7 +124,7 @@ class CwiseNullaryOp : ei_no_assignment_operator,
template<typename Derived>
template<typename CustomNullaryOp>
EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived>
MatrixBase<Derived>::NullaryExpr(int rows, int cols, const CustomNullaryOp& func)
DenseBase<Derived>::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func)
{
return CwiseNullaryOp<CustomNullaryOp, Derived>(rows, cols, func);
}
@@ -144,16 +147,16 @@ MatrixBase<Derived>::NullaryExpr(int rows, int cols, const CustomNullaryOp& func
template<typename Derived>
template<typename CustomNullaryOp>
EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived>
MatrixBase<Derived>::NullaryExpr(int size, const CustomNullaryOp& func)
DenseBase<Derived>::NullaryExpr(Index size, const CustomNullaryOp& func)
{
ei_assert(IsVectorAtCompileTime);
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 MatrixBase types. For dynamic-size types, you
* 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.
@@ -163,7 +166,7 @@ MatrixBase<Derived>::NullaryExpr(int size, const CustomNullaryOp& func)
template<typename Derived>
template<typename CustomNullaryOp>
EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived>
MatrixBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
DenseBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
{
return CwiseNullaryOp<CustomNullaryOp, Derived>(RowsAtCompileTime, ColsAtCompileTime, func);
}
@@ -171,7 +174,7 @@ MatrixBase<Derived>::NullaryExpr(const CustomNullaryOp& 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 MatrixBase type.
* 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
@@ -182,16 +185,16 @@ MatrixBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
* \sa class CwiseNullaryOp
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
MatrixBase<Derived>::Constant(int rows, int cols, const Scalar& value)
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Constant(Index rows, Index cols, const Scalar& value)
{
return NullaryExpr(rows, cols, ei_scalar_constant_op<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 MatrixBase type.
* Must be compatible with this DenseBase type.
*
* \only_for_vectors
*
@@ -204,15 +207,15 @@ MatrixBase<Derived>::Constant(int rows, int cols, const Scalar& value)
* \sa class CwiseNullaryOp
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
MatrixBase<Derived>::Constant(int size, const Scalar& value)
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Constant(Index size, const Scalar& value)
{
return NullaryExpr(size, ei_scalar_constant_op<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 MatrixBase types. For dynamic-size types, you
* 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.
@@ -220,44 +223,179 @@ MatrixBase<Derived>::Constant(int size, const Scalar& value)
* \sa class CwiseNullaryOp
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
MatrixBase<Derived>::Constant(const Scalar& value)
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Constant(const Scalar& value)
{
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
return NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, ei_scalar_constant_op<Scalar>(value));
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.
*
* \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>
bool MatrixBase<Derived>::isApproxToConstant
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].
*
* \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(int j = 0; j < cols(); ++j)
for(int i = 0; i < rows(); ++i)
if(!ei_isApprox(coeff(i, j), value, prec))
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 MatrixBase<Derived>::fill(const Scalar& value)
EIGEN_STRONG_INLINE void DenseBase<Derived>::fill(const Scalar& value)
{
setConstant(value);
}
/** Sets all coefficients in this expression to \a value.
*
* \sa fill(), Constant(), class CwiseNullaryOp, setZero(), setOnes()
* \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& MatrixBase<Derived>::setConstant(const Scalar& value)
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].
*
* \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));
}
// zero:
/** \returns an expression of a zero matrix.
@@ -269,16 +407,14 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setConstant(const Scalar& valu
* it is redundant to pass \a rows and \a cols as arguments, so Zero() should be used
* instead.
*
* \addexample Zero \label How to take get a zero matrix
*
* Example: \include MatrixBase_zero_int_int.cpp
* Output: \verbinclude MatrixBase_zero_int_int.out
*
* \sa Zero(), Zero(int)
* \sa Zero(), Zero(Index)
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
MatrixBase<Derived>::Zero(int rows, int cols)
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Zero(Index rows, Index cols)
{
return Constant(rows, cols, Scalar(0));
}
@@ -297,11 +433,11 @@ MatrixBase<Derived>::Zero(int rows, int cols)
* Example: \include MatrixBase_zero_int.cpp
* Output: \verbinclude MatrixBase_zero_int.out
*
* \sa Zero(), Zero(int,int)
* \sa Zero(), Zero(Index,Index)
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
MatrixBase<Derived>::Zero(int size)
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Zero(Index size)
{
return Constant(size, Scalar(0));
}
@@ -314,11 +450,11 @@ MatrixBase<Derived>::Zero(int size)
* Example: \include MatrixBase_zero.cpp
* Output: \verbinclude MatrixBase_zero.out
*
* \sa Zero(int), Zero(int,int)
* \sa Zero(Index), Zero(Index,Index)
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
MatrixBase<Derived>::Zero()
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Zero()
{
return Constant(Scalar(0));
}
@@ -332,11 +468,11 @@ MatrixBase<Derived>::Zero()
* \sa class CwiseNullaryOp, Zero()
*/
template<typename Derived>
bool MatrixBase<Derived>::isZero(RealScalar prec) const
bool DenseBase<Derived>::isZero(RealScalar prec) const
{
for(int j = 0; j < cols(); ++j)
for(int i = 0; i < rows(); ++i)
if(!ei_isMuchSmallerThan(coeff(i, j), static_cast<Scalar>(1), prec))
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;
}
@@ -349,11 +485,46 @@ bool MatrixBase<Derived>::isZero(RealScalar prec) const
* \sa class CwiseNullaryOp, Zero()
*/
template<typename Derived>
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setZero()
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.
@@ -365,16 +536,14 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setZero()
* it is redundant to pass \a rows and \a cols as arguments, so Ones() should be used
* instead.
*
* \addexample One \label How to get a matrix with all coefficients equal one
*
* Example: \include MatrixBase_ones_int_int.cpp
* Output: \verbinclude MatrixBase_ones_int_int.out
*
* \sa Ones(), Ones(int), isOnes(), class Ones
* \sa Ones(), Ones(Index), isOnes(), class Ones
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
MatrixBase<Derived>::Ones(int rows, int cols)
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Ones(Index rows, Index cols)
{
return Constant(rows, cols, Scalar(1));
}
@@ -393,11 +562,11 @@ MatrixBase<Derived>::Ones(int rows, int cols)
* Example: \include MatrixBase_ones_int.cpp
* Output: \verbinclude MatrixBase_ones_int.out
*
* \sa Ones(), Ones(int,int), isOnes(), class Ones
* \sa Ones(), Ones(Index,Index), isOnes(), class Ones
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
MatrixBase<Derived>::Ones(int size)
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Ones(Index size)
{
return Constant(size, Scalar(1));
}
@@ -410,11 +579,11 @@ MatrixBase<Derived>::Ones(int size)
* Example: \include MatrixBase_ones.cpp
* Output: \verbinclude MatrixBase_ones.out
*
* \sa Ones(int), Ones(int,int), isOnes(), class Ones
* \sa Ones(Index), Ones(Index,Index), isOnes(), class Ones
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
MatrixBase<Derived>::Ones()
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Ones()
{
return Constant(Scalar(1));
}
@@ -428,7 +597,7 @@ MatrixBase<Derived>::Ones()
* \sa class CwiseNullaryOp, Ones()
*/
template<typename Derived>
bool MatrixBase<Derived>::isOnes
bool DenseBase<Derived>::isOnes
(RealScalar prec) const
{
return isApproxToConstant(Scalar(1), prec);
@@ -442,11 +611,46 @@ bool MatrixBase<Derived>::isOnes
* \sa class CwiseNullaryOp, Ones()
*/
template<typename Derived>
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setOnes()
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).
@@ -458,8 +662,6 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setOnes()
* it is redundant to pass \a rows and \a cols as arguments, so Identity() should be used
* instead.
*
* \addexample Identity \label How to get an identity matrix
*
* Example: \include MatrixBase_identity_int_int.cpp
* Output: \verbinclude MatrixBase_identity_int_int.out
*
@@ -467,9 +669,9 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setOnes()
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
MatrixBase<Derived>::Identity(int rows, int cols)
MatrixBase<Derived>::Identity(Index rows, Index cols)
{
return NullaryExpr(rows, cols, ei_scalar_identity_op<Scalar>());
return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_identity_op<Scalar>());
}
/** \returns an expression of the identity matrix (not necessarily square).
@@ -480,14 +682,14 @@ MatrixBase<Derived>::Identity(int rows, int cols)
* Example: \include MatrixBase_identity.cpp
* Output: \verbinclude MatrixBase_identity.out
*
* \sa Identity(int,int), setIdentity(), isIdentity()
* \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 NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, ei_scalar_identity_op<Scalar>());
return MatrixBase<Derived>::NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_identity_op<Scalar>());
}
/** \returns true if *this is approximately equal to the identity matrix
@@ -497,24 +699,24 @@ MatrixBase<Derived>::Identity()
* Example: \include MatrixBase_isIdentity.cpp
* Output: \verbinclude MatrixBase_isIdentity.out
*
* \sa class CwiseNullaryOp, Identity(), Identity(int,int), setIdentity()
* \sa class CwiseNullaryOp, Identity(), Identity(Index,Index), setIdentity()
*/
template<typename Derived>
bool MatrixBase<Derived>::isIdentity
(RealScalar prec) const
{
for(int j = 0; j < cols(); ++j)
for(Index j = 0; j < cols(); ++j)
{
for(int i = 0; i < rows(); ++i)
for(Index i = 0; i < rows(); ++i)
{
if(i == j)
{
if(!ei_isApprox(coeff(i, j), static_cast<Scalar>(1), prec))
if(!internal::isApprox(this->coeff(i, j), static_cast<Scalar>(1), prec))
return false;
}
else
{
if(!ei_isMuchSmallerThan(coeff(i, j), static_cast<RealScalar>(1), prec))
if(!internal::isMuchSmallerThan(this->coeff(i, j), static_cast<RealScalar>(1), prec))
return false;
}
}
@@ -522,8 +724,10 @@ bool MatrixBase<Derived>::isIdentity
return true;
}
namespace internal {
template<typename Derived, bool Big = (Derived::SizeAtCompileTime>=16)>
struct ei_setIdentity_impl
struct setIdentity_impl
{
static EIGEN_STRONG_INLINE Derived& run(Derived& m)
{
@@ -532,38 +736,58 @@ struct ei_setIdentity_impl
};
template<typename Derived>
struct ei_setIdentity_impl<Derived, true>
struct setIdentity_impl<Derived, true>
{
typedef typename Derived::Index Index;
static EIGEN_STRONG_INLINE Derived& run(Derived& m)
{
m.setZero();
const int size = std::min(m.rows(), m.cols());
for(int i = 0; i < size; ++i) m.coeffRef(i,i) = typename Derived::Scalar(1);
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(int,int), isIdentity()
* \sa class CwiseNullaryOp, Identity(), Identity(Index,Index), isIdentity()
*/
template<typename Derived>
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity()
{
return ei_setIdentity_impl<Derived>::run(derived());
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(int), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
* \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(int size, int i)
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);
@@ -575,10 +799,10 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBa
*
* This variant is for fixed-size vector only.
*
* \sa MatrixBase::Unit(int,int), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
* \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(int i)
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index i)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return BasisReturnType(SquareMatrixType::Identity(),i);
@@ -588,7 +812,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBa
*
* \only_for_vectors
*
* \sa MatrixBase::Unit(int,int), MatrixBase::Unit(int), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
* \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()
@@ -598,7 +822,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBa
*
* \only_for_vectors
*
* \sa MatrixBase::Unit(int,int), MatrixBase::Unit(int), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
* \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()
@@ -608,7 +832,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBa
*
* \only_for_vectors
*
* \sa MatrixBase::Unit(int,int), MatrixBase::Unit(int), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
* \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()
@@ -618,7 +842,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBa
*
* \only_for_vectors
*
* \sa MatrixBase::Unit(int,int), MatrixBase::Unit(int), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
* \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()

View File

@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
@@ -27,203 +27,111 @@
#define EIGEN_CWISE_UNARY_OP_H
/** \class CwiseUnaryOp
* \ingroup Core_Module
*
* \brief Generic expression of a coefficient-wise unary operator of a matrix or a vector
* \brief Generic expression where a coefficient-wise unary operator is applied to an expression
*
* \param UnaryOp template functor implementing the operator
* \param MatrixType the type of the matrix we are applying the unary operator
* \param XprType the type of the expression to which we are applying the unary operator
*
* This class represents an expression of a generic unary operator of a matrix or a vector.
* It is the return type of the unary operator-, of a matrix or a vector, and most
* of the time this is the only way it is used.
* 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
*/
template<typename UnaryOp, typename MatrixType>
struct ei_traits<CwiseUnaryOp<UnaryOp, MatrixType> >
: ei_traits<MatrixType>
namespace internal {
template<typename UnaryOp, typename XprType>
struct traits<CwiseUnaryOp<UnaryOp, XprType> >
: traits<XprType>
{
typedef typename ei_result_of<
UnaryOp(typename MatrixType::Scalar)
typedef typename result_of<
UnaryOp(typename XprType::Scalar)
>::type Scalar;
typedef typename MatrixType::Nested MatrixTypeNested;
typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
typedef typename XprType::Nested XprTypeNested;
typedef typename remove_reference<XprTypeNested>::type _XprTypeNested;
enum {
Flags = (_MatrixTypeNested::Flags & (
Flags = _XprTypeNested::Flags & (
HereditaryBits | LinearAccessBit | AlignedBit
| (ei_functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0))),
CoeffReadCost = _MatrixTypeNested::CoeffReadCost + ei_functor_traits<UnaryOp>::Cost
| (functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0)),
CoeffReadCost = _XprTypeNested::CoeffReadCost + functor_traits<UnaryOp>::Cost
};
};
}
template<typename UnaryOp, typename MatrixType>
class CwiseUnaryOp : ei_no_assignment_operator,
public MatrixBase<CwiseUnaryOp<UnaryOp, MatrixType> >
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 MatrixType& mat, const UnaryOp& func = UnaryOp())
: m_matrix(mat), m_functor(func) {}
inline CwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp())
: m_xpr(xpr), m_functor(func) {}
EIGEN_STRONG_INLINE int rows() const { return m_matrix.rows(); }
EIGEN_STRONG_INLINE int cols() const { return m_matrix.cols(); }
EIGEN_STRONG_INLINE Index rows() const { return m_xpr.rows(); }
EIGEN_STRONG_INLINE Index cols() const { return m_xpr.cols(); }
EIGEN_STRONG_INLINE const Scalar coeff(int row, int col) const
{
return m_functor(m_matrix.coeff(row, col));
}
/** \returns the functor representing the unary operation */
const UnaryOp& functor() const { return m_functor; }
template<int LoadMode>
EIGEN_STRONG_INLINE PacketScalar packet(int row, int col) const
{
return m_functor.packetOp(m_matrix.template packet<LoadMode>(row, col));
}
/** \returns the nested expression */
const typename internal::remove_all<typename XprType::Nested>::type&
nestedExpression() const { return m_xpr; }
EIGEN_STRONG_INLINE const Scalar coeff(int index) const
{
return m_functor(m_matrix.coeff(index));
}
template<int LoadMode>
EIGEN_STRONG_INLINE PacketScalar packet(int index) const
{
return m_functor.packetOp(m_matrix.template packet<LoadMode>(index));
}
/** \returns the nested expression */
typename internal::remove_all<typename XprType::Nested>::type&
nestedExpression() { return m_xpr.const_cast_derived(); }
protected:
const typename MatrixType::Nested m_matrix;
const typename XprType::Nested m_xpr;
const UnaryOp m_functor;
};
/** \returns an expression of a custom coefficient-wise unary operator \a func of *this
*
* The template parameter \a CustomUnaryOp is the type of the functor
* of the custom unary operator.
*
* \addexample CustomCwiseUnaryFunctors \label How to use custom coeff wise unary functors
*
* Example:
* \include class_CwiseUnaryOp.cpp
* Output: \verbinclude class_CwiseUnaryOp.out
*
* \sa class CwiseUnaryOp, class CwiseBinarOp, MatrixBase::operator-, Cwise::abs
*/
template<typename Derived>
template<typename CustomUnaryOp>
EIGEN_STRONG_INLINE const CwiseUnaryOp<CustomUnaryOp, Derived>
MatrixBase<Derived>::unaryExpr(const CustomUnaryOp& func) const
// 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
{
return CwiseUnaryOp<CustomUnaryOp, Derived>(derived(), func);
}
public:
/** \returns an expression of the opposite of \c *this
*/
template<typename Derived>
EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_opposite_op<typename ei_traits<Derived>::Scalar>,Derived>
MatrixBase<Derived>::operator-() const
{
return derived();
}
typedef CwiseUnaryOp<UnaryOp, XprType> Derived;
typedef typename internal::dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
/** \returns an expression of the coefficient-wise absolute value of \c *this
*
* Example: \include Cwise_abs.cpp
* Output: \verbinclude Cwise_abs.out
*
* \sa abs2()
*/
template<typename ExpressionType>
EIGEN_STRONG_INLINE const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs_op)
Cwise<ExpressionType>::abs() const
{
return _expression();
}
EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const
{
return derived().functor()(derived().nestedExpression().coeff(row, col));
}
/** \returns an expression of the coefficient-wise squared absolute value of \c *this
*
* Example: \include Cwise_abs2.cpp
* Output: \verbinclude Cwise_abs2.out
*
* \sa abs(), square()
*/
template<typename ExpressionType>
EIGEN_STRONG_INLINE const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs2_op)
Cwise<ExpressionType>::abs2() const
{
return _expression();
}
template<int LoadMode>
EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
{
return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(row, col));
}
/** \returns an expression of the complex conjugate of \c *this.
*
* \sa adjoint() */
template<typename Derived>
EIGEN_STRONG_INLINE typename MatrixBase<Derived>::ConjugateReturnType
MatrixBase<Derived>::conjugate() const
{
return ConjugateReturnType(derived());
}
EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
{
return derived().functor()(derived().nestedExpression().coeff(index));
}
/** \returns an expression of the real part of \c *this.
*
* \sa imag() */
template<typename Derived>
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::RealReturnType
MatrixBase<Derived>::real() const { return derived(); }
/** \returns an expression of the imaginary part of \c *this.
*
* \sa real() */
template<typename Derived>
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ImagReturnType
MatrixBase<Derived>::imag() const { return derived(); }
/** \returns an expression of *this with the \a Scalar type casted to
* \a NewScalar.
*
* The template parameter \a NewScalar is the type we are casting the scalars to.
*
* \sa class CwiseUnaryOp
*/
template<typename Derived>
template<typename NewType>
EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_cast_op<typename ei_traits<Derived>::Scalar, NewType>, Derived>
MatrixBase<Derived>::cast() const
{
return derived();
}
/** \relates MatrixBase */
template<typename Derived>
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ScalarMultipleReturnType
MatrixBase<Derived>::operator*(const Scalar& scalar) const
{
return CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, Derived>
(derived(), ei_scalar_multiple_op<Scalar>(scalar));
}
/** \relates MatrixBase */
template<typename Derived>
EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived>
MatrixBase<Derived>::operator/(const Scalar& scalar) const
{
return CwiseUnaryOp<ei_scalar_quotient1_op<Scalar>, Derived>
(derived(), ei_scalar_quotient1_op<Scalar>(scalar));
}
template<typename Derived>
EIGEN_STRONG_INLINE Derived&
MatrixBase<Derived>::operator*=(const Scalar& other)
{
return *this = *this * other;
}
template<typename Derived>
EIGEN_STRONG_INLINE Derived&
MatrixBase<Derived>::operator/=(const Scalar& other)
{
return *this = *this / other;
}
template<int LoadMode>
EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
{
return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(index));
}
};
#endif // EIGEN_CWISE_UNARY_OP_H

View File

@@ -0,0 +1,148 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_CWISE_UNARY_VIEW_H
#define EIGEN_CWISE_UNARY_VIEW_H
/** \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
};
};
}
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
const 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();
}
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));
}
};
#endif // EIGEN_CWISE_UNARY_VIEW_H

537
Eigen/src/Core/DenseBase.h Normal file
View File

@@ -0,0 +1,537 @@
// 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>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_DENSEBASE_H
#define EIGEN_DENSEBASE_H
/** \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;
typedef typename internal::traits<Derived>::Index Index; /**< The type of indices */
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) ? SizeAtCompileTime
: int(IsRowMajor) ? ColsAtCompileTime : 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);
/** \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 const typename internal::eval<Derived>::type 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>&);
};
#endif // EIGEN_DENSEBASE_H

View File

@@ -0,0 +1,765 @@
// 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>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_DENSECOEFFSBASE_H
#define EIGEN_DENSECOEFFSBASE_H
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 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, 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
{
inline static typename Derived::Index run(const Derived&)
{ return 0; }
};
template<typename Derived>
struct first_aligned_impl<Derived, false>
{
inline static typename Derived::Index run(const Derived& m)
{
return 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>
inline static 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
#endif // EIGEN_DENSECOEFFSBASE_H

View File

@@ -0,0 +1,304 @@
// 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>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_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 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) {}
};
#ifdef EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask)
#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/UnalignedArrayAssert.html" \
" **** READ THIS WEB PAGE !!! ****");
#endif
template <typename T, int Size, int MatrixOrArrayOptions>
struct plain_array<T, Size, MatrixOrArrayOptions, 16>
{
EIGEN_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_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); }
inline static DenseIndex rows(void) {return _Rows;}
inline static 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& ) {}
inline static DenseIndex rows(void) {return _Rows;}
inline static 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; }
};
// 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); }
inline static 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;}
inline static 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; }
};
#endif // EIGEN_MATRIX_H

227
Eigen/src/Core/Diagonal.h Normal file
View File

@@ -0,0 +1,227 @@
// 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>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_DIAGONAL_H
#define EIGEN_DIAGONAL_H
/** \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 {
AbsDiagIndex = DiagIndex<0 ? -DiagIndex : DiagIndex, // only used if DiagIndex != Dynamic
// FIXME these computations are broken in the case where the matrix is rectangular and DiagIndex!=0
RowsAtCompileTime = (int(DiagIndex) == Dynamic || int(MatrixType::SizeAtCompileTime) == Dynamic) ? Dynamic
: (EIGEN_SIZE_MIN_PREFER_DYNAMIC(MatrixType::RowsAtCompileTime,
MatrixType::ColsAtCompileTime) - AbsDiagIndex),
ColsAtCompileTime = 1,
MaxRowsAtCompileTime = int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic
: DiagIndex == Dynamic ? EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::MaxRowsAtCompileTime,
MatrixType::MaxColsAtCompileTime)
: (EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::MaxRowsAtCompileTime, MatrixType::MaxColsAtCompileTime) - AbsDiagIndex),
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;
}
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());
}
protected:
const 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();
}
#endif // EIGEN_DIAGONAL_H

View File

@@ -1,124 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_DIAGONALCOEFFS_H
#define EIGEN_DIAGONALCOEFFS_H
/** \class DiagonalCoeffs
*
* \brief Expression of the main diagonal of a matrix
*
* \param MatrixType the type of the object in which we are taking the main diagonal
*
* The matrix is not required to be square.
*
* This class represents an expression of the main diagonal of a square matrix.
* It is the return type of MatrixBase::diagonal() and most of the time this is
* the only way it is used.
*
* \sa MatrixBase::diagonal()
*/
template<typename MatrixType>
struct ei_traits<DiagonalCoeffs<MatrixType> >
{
typedef typename MatrixType::Scalar Scalar;
typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
enum {
RowsAtCompileTime = int(MatrixType::SizeAtCompileTime) == Dynamic ? Dynamic
: EIGEN_ENUM_MIN(MatrixType::RowsAtCompileTime,
MatrixType::ColsAtCompileTime),
ColsAtCompileTime = 1,
MaxRowsAtCompileTime = int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic
: EIGEN_ENUM_MIN(MatrixType::MaxRowsAtCompileTime,
MatrixType::MaxColsAtCompileTime),
MaxColsAtCompileTime = 1,
Flags = (unsigned int)_MatrixTypeNested::Flags & (HereditaryBits | LinearAccessBit),
CoeffReadCost = _MatrixTypeNested::CoeffReadCost
};
};
template<typename MatrixType> class DiagonalCoeffs
: public MatrixBase<DiagonalCoeffs<MatrixType> >
{
public:
EIGEN_GENERIC_PUBLIC_INTERFACE(DiagonalCoeffs)
inline DiagonalCoeffs(const MatrixType& matrix) : m_matrix(matrix) {}
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(DiagonalCoeffs)
inline int rows() const { return std::min(m_matrix.rows(), m_matrix.cols()); }
inline int cols() const { return 1; }
inline Scalar& coeffRef(int row, int)
{
return m_matrix.const_cast_derived().coeffRef(row, row);
}
inline const Scalar coeff(int row, int) const
{
return m_matrix.coeff(row, row);
}
inline Scalar& coeffRef(int index)
{
return m_matrix.const_cast_derived().coeffRef(index, index);
}
inline const Scalar coeff(int index) const
{
return m_matrix.coeff(index, index);
}
protected:
const typename MatrixType::Nested m_matrix;
};
/** \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 DiagonalCoeffs */
template<typename Derived>
inline DiagonalCoeffs<Derived>
MatrixBase<Derived>::diagonal()
{
return DiagonalCoeffs<Derived>(derived());
}
/** This is the const version of diagonal(). */
template<typename Derived>
inline const DiagonalCoeffs<Derived>
MatrixBase<Derived>::diagonal() const
{
return DiagonalCoeffs<Derived>(derived());
}
#endif // EIGEN_DIAGONALCOEFFS_H

View File

@@ -1,7 +1,8 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -25,94 +26,257 @@
#ifndef EIGEN_DIAGONALMATRIX_H
#define EIGEN_DIAGONALMATRIX_H
#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 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<CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const DiagonalVectorType> >
inverse() const
{
return diagonal().cwiseInverse();
}
#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
* \nonstableyet
* \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 CoeffsVectorType the type of the vector of diagonal coefficients
* \param _DiagonalVectorType the type of the vector of diagonal coefficients
*
* This class is an expression of a diagonal matrix with given vector of diagonal
* coefficients. It is the return
* type of MatrixBase::diagonal(const OtherDerived&) and most of the time this is
* the only way it is used.
* 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 MatrixBase::diagonal(const OtherDerived&)
* \sa class DiagonalMatrix, class DiagonalBase, MatrixBase::asDiagonal()
*/
template<typename CoeffsVectorType>
struct ei_traits<DiagonalMatrix<CoeffsVectorType> >
namespace internal {
template<typename _DiagonalVectorType>
struct traits<DiagonalWrapper<_DiagonalVectorType> >
{
typedef typename CoeffsVectorType::Scalar Scalar;
typedef typename ei_nested<CoeffsVectorType>::type CoeffsVectorTypeNested;
typedef typename ei_unref<CoeffsVectorTypeNested>::type _CoeffsVectorTypeNested;
typedef _DiagonalVectorType DiagonalVectorType;
typedef typename DiagonalVectorType::Scalar Scalar;
typedef typename DiagonalVectorType::Index Index;
typedef typename DiagonalVectorType::StorageKind StorageKind;
enum {
RowsAtCompileTime = CoeffsVectorType::SizeAtCompileTime,
ColsAtCompileTime = CoeffsVectorType::SizeAtCompileTime,
MaxRowsAtCompileTime = CoeffsVectorType::MaxSizeAtCompileTime,
MaxColsAtCompileTime = CoeffsVectorType::MaxSizeAtCompileTime,
Flags = (_CoeffsVectorTypeNested::Flags & HereditaryBits) | Diagonal,
CoeffReadCost = _CoeffsVectorTypeNested::CoeffReadCost
RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
MaxRowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
MaxColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
Flags = traits<DiagonalVectorType>::Flags & LvalueBit
};
};
}
template<typename CoeffsVectorType>
class DiagonalMatrix : ei_no_assignment_operator,
public MatrixBase<DiagonalMatrix<CoeffsVectorType> >
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
EIGEN_GENERIC_PUBLIC_INTERFACE(DiagonalMatrix)
/** Constructor from expression of diagonal coefficients to wrap. */
inline DiagonalWrapper(const DiagonalVectorType& diagonal) : m_diagonal(diagonal) {}
// needed to evaluate a DiagonalMatrix<Xpr> to a DiagonalMatrix<NestByValue<Vector> >
template<typename OtherCoeffsVectorType>
inline DiagonalMatrix(const DiagonalMatrix<OtherCoeffsVectorType>& other) : m_coeffs(other.diagonal())
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(CoeffsVectorType);
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherCoeffsVectorType);
ei_assert(m_coeffs.size() > 0);
}
inline DiagonalMatrix(const CoeffsVectorType& coeffs) : m_coeffs(coeffs)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(CoeffsVectorType);
ei_assert(coeffs.size() > 0);
}
inline int rows() const { return m_coeffs.size(); }
inline int cols() const { return m_coeffs.size(); }
inline const Scalar coeff(int row, int col) const
{
return row == col ? m_coeffs.coeff(row) : static_cast<Scalar>(0);
}
inline const CoeffsVectorType& diagonal() const { return m_coeffs; }
/** \returns a const reference to the wrapped expression of diagonal coefficients. */
const DiagonalVectorType& diagonal() const { return m_diagonal; }
protected:
const typename CoeffsVectorType::Nested m_coeffs;
const typename DiagonalVectorType::Nested m_diagonal;
};
/** \nonstableyet
* \returns an expression of a diagonal matrix with *this as vector of diagonal coefficients
/** \returns a pseudo-expression of a diagonal matrix with *this as vector of diagonal coefficients
*
* \only_for_vectors
*
* \addexample AsDiagonalExample \label How to build a diagonal matrix from a vector
*
* Example: \include MatrixBase_asDiagonal.cpp
* Output: \verbinclude MatrixBase_asDiagonal.out
*
* \sa class DiagonalMatrix, isDiagonal()
* \sa class DiagonalWrapper, class DiagonalMatrix, diagonal(), isDiagonal()
**/
template<typename Derived>
inline const DiagonalMatrix<Derived>
inline const DiagonalWrapper<const Derived>
MatrixBase<Derived>::asDiagonal() const
{
return derived();
}
/** \nonstableyet
* \returns true if *this is approximately equal to a diagonal matrix,
/** \returns true if *this is approximately equal to a diagonal matrix,
* within the precision given by \a prec.
*
* Example: \include MatrixBase_isDiagonal.cpp
@@ -121,21 +285,20 @@ MatrixBase<Derived>::asDiagonal() const
* \sa asDiagonal()
*/
template<typename Derived>
bool MatrixBase<Derived>::isDiagonal
(RealScalar prec) const
bool MatrixBase<Derived>::isDiagonal(RealScalar prec) const
{
if(cols() != rows()) return false;
RealScalar maxAbsOnDiagonal = static_cast<RealScalar>(-1);
for(int j = 0; j < cols(); ++j)
for(Index j = 0; j < cols(); ++j)
{
RealScalar absOnDiagonal = ei_abs(coeff(j,j));
RealScalar absOnDiagonal = internal::abs(coeff(j,j));
if(absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal;
}
for(int j = 0; j < cols(); ++j)
for(int i = 0; i < j; ++i)
for(Index j = 0; j < cols(); ++j)
for(Index i = 0; i < j; ++i)
{
if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnDiagonal, prec)) return false;
if(!ei_isMuchSmallerThan(coeff(j, i), maxAbsOnDiagonal, prec)) return false;
if(!internal::isMuchSmallerThan(coeff(i, j), maxAbsOnDiagonal, prec)) return false;
if(!internal::isMuchSmallerThan(coeff(j, i), maxAbsOnDiagonal, prec)) return false;
}
return true;
}

View File

@@ -1,8 +1,8 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -26,105 +26,110 @@
#ifndef EIGEN_DIAGONALPRODUCT_H
#define EIGEN_DIAGONALPRODUCT_H
/** \internal Specialization of ei_nested for DiagonalMatrix.
* Unlike ei_nested, if the argument is a DiagonalMatrix and if it must be evaluated,
* then it evaluated to a DiagonalMatrix having its own argument evaluated.
*/
template<typename T, int N> struct ei_nested_diagonal : ei_nested<T,N> {};
template<typename T, int N> struct ei_nested_diagonal<DiagonalMatrix<T>,N >
: ei_nested<DiagonalMatrix<T>, N, DiagonalMatrix<NestByValue<typename ei_plain_matrix_type<T>::type> > >
{};
// specialization of ProductReturnType
template<typename Lhs, typename Rhs>
struct ProductReturnType<Lhs,Rhs,DiagonalProduct>
namespace internal {
template<typename MatrixType, typename DiagonalType, int ProductOrder>
struct traits<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> >
: traits<MatrixType>
{
typedef typename ei_nested_diagonal<Lhs,Rhs::ColsAtCompileTime>::type LhsNested;
typedef typename ei_nested_diagonal<Rhs,Lhs::RowsAtCompileTime>::type RhsNested;
typedef Product<LhsNested, RhsNested, DiagonalProduct> Type;
};
template<typename LhsNested, typename RhsNested>
struct ei_traits<Product<LhsNested, RhsNested, DiagonalProduct> >
{
// clean the nested types:
typedef typename ei_cleantype<LhsNested>::type _LhsNested;
typedef typename ei_cleantype<RhsNested>::type _RhsNested;
typedef typename _LhsNested::Scalar Scalar;
typedef typename scalar_product_traits<typename MatrixType::Scalar, typename DiagonalType::Scalar>::ReturnType Scalar;
enum {
LhsFlags = _LhsNested::Flags,
RhsFlags = _RhsNested::Flags,
RowsAtCompileTime = _LhsNested::RowsAtCompileTime,
ColsAtCompileTime = _RhsNested::ColsAtCompileTime,
MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime,
MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime,
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
LhsIsDiagonal = (_LhsNested::Flags&Diagonal)==Diagonal,
RhsIsDiagonal = (_RhsNested::Flags&Diagonal)==Diagonal,
_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))),
CanVectorizeRhs = (!RhsIsDiagonal) && (RhsFlags & RowMajorBit) && (RhsFlags & PacketAccessBit)
&& (ColsAtCompileTime % ei_packet_traits<Scalar>::size == 0),
CanVectorizeLhs = (!LhsIsDiagonal) && (!(LhsFlags & RowMajorBit)) && (LhsFlags & PacketAccessBit)
&& (RowsAtCompileTime % ei_packet_traits<Scalar>::size == 0),
RemovedBits = ~((RhsFlags & RowMajorBit) && (!CanVectorizeLhs) ? 0 : RowMajorBit),
Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits)
| (((CanVectorizeLhs&&RhsIsDiagonal) || (CanVectorizeRhs&&LhsIsDiagonal)) ? PacketAccessBit : 0),
CoeffReadCost = NumTraits<Scalar>::MulCost + _LhsNested::CoeffReadCost + _RhsNested::CoeffReadCost
Flags = (HereditaryBits & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0),
CoeffReadCost = NumTraits<Scalar>::MulCost + MatrixType::CoeffReadCost + DiagonalType::DiagonalVectorType::CoeffReadCost
};
};
}
template<typename LhsNested, typename RhsNested> class Product<LhsNested, RhsNested, DiagonalProduct> : ei_no_assignment_operator,
public MatrixBase<Product<LhsNested, RhsNested, DiagonalProduct> >
template<typename MatrixType, typename DiagonalType, int ProductOrder>
class DiagonalProduct : internal::no_assignment_operator,
public MatrixBase<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> >
{
typedef typename ei_traits<Product>::_LhsNested _LhsNested;
typedef typename ei_traits<Product>::_RhsNested _RhsNested;
enum {
RhsIsDiagonal = (_RhsNested::Flags&Diagonal)==Diagonal
};
public:
EIGEN_GENERIC_PUBLIC_INTERFACE(Product)
typedef MatrixBase<DiagonalProduct> Base;
EIGEN_DENSE_PUBLIC_INTERFACE(DiagonalProduct)
template<typename Lhs, typename Rhs>
inline Product(const Lhs& lhs, const Rhs& rhs)
: m_lhs(lhs), m_rhs(rhs)
inline DiagonalProduct(const MatrixType& matrix, const DiagonalType& diagonal)
: m_matrix(matrix), m_diagonal(diagonal)
{
ei_assert(lhs.cols() == rhs.rows());
eigen_assert(diagonal.diagonal().size() == (ProductOrder == OnTheLeft ? matrix.rows() : matrix.cols()));
}
inline int rows() const { return m_lhs.rows(); }
inline int cols() const { return m_rhs.cols(); }
inline Index rows() const { return m_matrix.rows(); }
inline Index cols() const { return m_matrix.cols(); }
const Scalar coeff(int row, int col) const
const Scalar coeff(Index row, Index col) const
{
const int unique = RhsIsDiagonal ? col : row;
return m_lhs.coeff(row, unique) * m_rhs.coeff(unique, col);
return m_diagonal.diagonal().coeff(ProductOrder == OnTheLeft ? row : col) * m_matrix.coeff(row, col);
}
template<int LoadMode>
const PacketScalar packet(int row, int col) const
EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
{
if (RhsIsDiagonal)
{
return ei_pmul(m_lhs.template packet<LoadMode>(row, col), ei_pset1(m_rhs.coeff(col, col)));
}
else
{
return ei_pmul(ei_pset1(m_lhs.coeff(row, row)), m_rhs.template packet<LoadMode>(row, col));
}
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:
const LhsNested m_lhs;
const RhsNested m_rhs;
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));
}
const typename MatrixType::Nested m_matrix;
const 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());
}
#endif // EIGEN_DIAGONALPRODUCT_H

View File

@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2006-2008, 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -25,258 +25,105 @@
#ifndef EIGEN_DOT_H
#define EIGEN_DOT_H
/***************************************************************************
* Part 1 : the logic deciding a strategy for vectorization and unrolling
***************************************************************************/
namespace internal {
template<typename Derived1, typename Derived2>
struct ei_dot_traits
{
public:
enum {
Vectorization = (int(Derived1::Flags)&int(Derived2::Flags)&ActualPacketAccessBit)
&& (int(Derived1::Flags)&int(Derived2::Flags)&LinearAccessBit)
? LinearVectorization
: NoVectorization
};
private:
typedef typename Derived1::Scalar Scalar;
enum {
PacketSize = ei_packet_traits<Scalar>::size,
Cost = Derived1::SizeAtCompileTime * (Derived1::CoeffReadCost + Derived2::CoeffReadCost + NumTraits<Scalar>::MulCost)
+ (Derived1::SizeAtCompileTime-1) * NumTraits<Scalar>::AddCost,
UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Vectorization) == int(NoVectorization) ? 1 : int(PacketSize))
};
public:
enum {
Unrolling = Cost <= UnrollingLimit
? CompleteUnrolling
: NoUnrolling
};
};
/***************************************************************************
* Part 2 : unrollers
***************************************************************************/
/*** no vectorization ***/
template<typename Derived1, typename Derived2, int Start, int Length>
struct ei_dot_novec_unroller
{
enum {
HalfLength = Length/2
};
typedef typename Derived1::Scalar Scalar;
inline static Scalar run(const Derived1& v1, const Derived2& v2)
{
return ei_dot_novec_unroller<Derived1, Derived2, Start, HalfLength>::run(v1, v2)
+ ei_dot_novec_unroller<Derived1, Derived2, Start+HalfLength, Length-HalfLength>::run(v1, v2);
}
};
template<typename Derived1, typename Derived2, int Start>
struct ei_dot_novec_unroller<Derived1, Derived2, Start, 1>
{
typedef typename Derived1::Scalar Scalar;
inline static Scalar run(const Derived1& v1, const Derived2& v2)
{
return v1.coeff(Start) * ei_conj(v2.coeff(Start));
}
};
/*** vectorization ***/
template<typename Derived1, typename Derived2, int Index, int Stop,
bool LastPacket = (Stop-Index == ei_packet_traits<typename Derived1::Scalar>::size)>
struct ei_dot_vec_unroller
{
typedef typename Derived1::Scalar Scalar;
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
enum {
row1 = Derived1::RowsAtCompileTime == 1 ? 0 : Index,
col1 = Derived1::RowsAtCompileTime == 1 ? Index : 0,
row2 = Derived2::RowsAtCompileTime == 1 ? 0 : Index,
col2 = Derived2::RowsAtCompileTime == 1 ? Index : 0
};
inline static PacketScalar run(const Derived1& v1, const Derived2& v2)
{
return ei_pmadd(
v1.template packet<Aligned>(row1, col1),
v2.template packet<Aligned>(row2, col2),
ei_dot_vec_unroller<Derived1, Derived2, Index+ei_packet_traits<Scalar>::size, Stop>::run(v1, v2)
);
}
};
template<typename Derived1, typename Derived2, int Index, int Stop>
struct ei_dot_vec_unroller<Derived1, Derived2, Index, Stop, true>
{
enum {
row1 = Derived1::RowsAtCompileTime == 1 ? 0 : Index,
col1 = Derived1::RowsAtCompileTime == 1 ? Index : 0,
row2 = Derived2::RowsAtCompileTime == 1 ? 0 : Index,
col2 = Derived2::RowsAtCompileTime == 1 ? Index : 0,
alignment1 = (Derived1::Flags & AlignedBit) ? Aligned : Unaligned,
alignment2 = (Derived2::Flags & AlignedBit) ? Aligned : Unaligned
};
typedef typename Derived1::Scalar Scalar;
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
inline static PacketScalar run(const Derived1& v1, const Derived2& v2)
{
return ei_pmul(v1.template packet<alignment1>(row1, col1), v2.template packet<alignment2>(row2, col2));
}
};
/***************************************************************************
* Part 3 : implementation of all cases
***************************************************************************/
template<typename Derived1, typename Derived2,
int Vectorization = ei_dot_traits<Derived1, Derived2>::Vectorization,
int Unrolling = ei_dot_traits<Derived1, Derived2>::Unrolling
// 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 ei_dot_impl;
template<typename Derived1, typename Derived2>
struct ei_dot_impl<Derived1, Derived2, NoVectorization, NoUnrolling>
struct dot_nocheck
{
typedef typename Derived1::Scalar Scalar;
static Scalar run(const Derived1& v1, const Derived2& v2)
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)
{
ei_assert(v1.size()>0 && "you are using a non initialized vector");
Scalar res;
res = v1.coeff(0) * ei_conj(v2.coeff(0));
for(int i = 1; i < v1.size(); ++i)
res += v1.coeff(i) * ei_conj(v2.coeff(i));
return res;
return a.template binaryExpr<scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> >(b).sum();
}
};
template<typename Derived1, typename Derived2>
struct ei_dot_impl<Derived1, Derived2, NoVectorization, CompleteUnrolling>
: public ei_dot_novec_unroller<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
{};
template<typename Derived1, typename Derived2>
struct ei_dot_impl<Derived1, Derived2, LinearVectorization, NoUnrolling>
template<typename T, typename U>
struct dot_nocheck<T, U, true>
{
typedef typename Derived1::Scalar Scalar;
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
static Scalar run(const Derived1& v1, const Derived2& v2)
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)
{
const int size = v1.size();
const int packetSize = ei_packet_traits<Scalar>::size;
const int alignedSize = (size/packetSize)*packetSize;
enum {
alignment1 = (Derived1::Flags & AlignedBit) ? Aligned : Unaligned,
alignment2 = (Derived2::Flags & AlignedBit) ? Aligned : Unaligned
};
Scalar res;
// do the vectorizable part of the sum
if(size >= packetSize)
{
PacketScalar packet_res = ei_pmul(
v1.template packet<alignment1>(0),
v2.template packet<alignment2>(0)
);
for(int index = packetSize; index<alignedSize; index += packetSize)
{
packet_res = ei_pmadd(
v1.template packet<alignment1>(index),
v2.template packet<alignment2>(index),
packet_res
);
}
res = ei_predux(packet_res);
// now we must do the rest without vectorization.
if(alignedSize == size) return res;
}
else // too small to vectorize anything.
// since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize.
{
res = Scalar(0);
}
// do the remainder of the vector
for(int index = alignedSize; index < size; ++index)
{
res += v1.coeff(index) * v2.coeff(index);
}
return res;
return a.transpose().template binaryExpr<scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> >(b).sum();
}
};
template<typename Derived1, typename Derived2>
struct ei_dot_impl<Derived1, Derived2, LinearVectorization, CompleteUnrolling>
{
typedef typename Derived1::Scalar Scalar;
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
enum {
PacketSize = ei_packet_traits<Scalar>::size,
Size = Derived1::SizeAtCompileTime,
VectorizationSize = (Size / PacketSize) * PacketSize
};
static Scalar run(const Derived1& v1, const Derived2& v2)
{
Scalar res = ei_predux(ei_dot_vec_unroller<Derived1, Derived2, 0, VectorizationSize>::run(v1, v2));
if (VectorizationSize != Size)
res += ei_dot_novec_unroller<Derived1, Derived2, VectorizationSize, Size-VectorizationSize>::run(v1, v2);
return res;
}
};
/***************************************************************************
* Part 4 : implementation of MatrixBase methods
***************************************************************************/
} // 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, linear in the first variable and conjugate-linear in the
* (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 ei_traits<Derived>::Scalar
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)
EIGEN_STATIC_ASSERT((ei_is_same_type<Scalar, typename OtherDerived::Scalar>::ret),
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)
ei_assert(size() == other.size());
eigen_assert(size() == other.size());
return ei_dot_impl<Derived, OtherDerived>::run(derived(), other.derived());
return internal::dot_nocheck<OtherDerived,Derived>::run(other,*this);
}
#endif
//---------- implementation of L2 norm and related functions ----------
/** \returns the squared \em l2 norm of *this, i.e., for vectors, the dot product of *this with itself.
*
* \sa dot(), norm()
*/
template<typename Derived>
inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real MatrixBase<Derived>::squaredNorm() const
EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::squaredNorm() const
{
return ei_real((*this).cwise().abs2().sum());
return internal::real((*this).cwiseAbs2().sum());
}
/** \returns the \em l2 norm of *this, i.e., for vectors, the square root of the dot product of *this with itself.
@@ -284,9 +131,9 @@ inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real MatrixBase<
* \sa dot(), squaredNorm()
*/
template<typename Derived>
inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
{
return ei_sqrt(squaredNorm());
return internal::sqrt(squaredNorm());
}
/** \returns an expression of the quotient of *this by its own norm.
@@ -296,11 +143,11 @@ inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real MatrixBase<
* \sa norm(), normalize()
*/
template<typename Derived>
inline const typename MatrixBase<Derived>::PlainMatrixType
inline const typename MatrixBase<Derived>::PlainObject
MatrixBase<Derived>::normalized() const
{
typedef typename ei_nested<Derived>::type Nested;
typedef typename ei_unref<Nested>::type _Nested;
typedef typename internal::nested<Derived>::type Nested;
typedef typename internal::remove_reference<Nested>::type _Nested;
_Nested n(derived());
return n / n.norm();
}
@@ -317,6 +164,65 @@ 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;
inline static 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>
{
inline static typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
{
return m.cwiseAbs().sum();
}
};
template<typename Derived>
struct lpNorm_selector<Derived, 2>
{
inline static typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
{
return m.norm();
}
};
template<typename Derived>
struct lpNorm_selector<Derived, Infinity>
{
inline static 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.
*
@@ -328,9 +234,9 @@ template<typename OtherDerived>
bool MatrixBase<Derived>::isOrthogonal
(const MatrixBase<OtherDerived>& other, RealScalar prec) const
{
typename ei_nested<Derived,2>::type nested(derived());
typename ei_nested<OtherDerived,2>::type otherNested(other.derived());
return ei_abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm();
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,
@@ -348,14 +254,15 @@ template<typename Derived>
bool MatrixBase<Derived>::isUnitary(RealScalar prec) const
{
typename Derived::Nested nested(derived());
for(int i = 0; i < cols(); ++i)
for(Index i = 0; i < cols(); ++i)
{
if(!ei_isApprox(nested.col(i).squaredNorm(), static_cast<Scalar>(1), prec))
if(!internal::isApprox(nested.col(i).squaredNorm(), static_cast<RealScalar>(1), prec))
return false;
for(int j = 0; j < i; ++j)
if(!ei_isMuchSmallerThan(nested.col(i).dot(nested.col(j)), static_cast<Scalar>(1), prec))
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;
}
#endif // EIGEN_DOT_H

172
Eigen/src/Core/EigenBase.h Normal file
View File

@@ -0,0 +1,172 @@
// 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>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_EIGENBASE_H
#define EIGEN_EIGENBASE_H
/** 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());
}
#endif // EIGEN_EIGENBASE_H

View File

@@ -1,5 +1,5 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
@@ -26,6 +26,7 @@
#define EIGEN_FLAGGED_H
/** \class Flagged
* \ingroup Core_Module
*
* \brief Expression with modified flags
*
@@ -39,106 +40,110 @@
*
* \sa MatrixBase::flagged()
*/
namespace internal {
template<typename ExpressionType, unsigned int Added, unsigned int Removed>
struct ei_traits<Flagged<ExpressionType, Added, Removed> > : ei_traits<ExpressionType>
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:
EIGEN_GENERIC_PUBLIC_INTERFACE(Flagged)
typedef typename ei_meta_if<ei_must_nest_by_value<ExpressionType>::ret,
ExpressionType, const ExpressionType&>::ret ExpressionTypeNested;
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 int rows() const { return m_matrix.rows(); }
inline int cols() const { return m_matrix.cols(); }
inline int stride() const { return m_matrix.stride(); }
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 coeff(int row, int col) const
inline CoeffReturnType coeff(Index row, Index col) const
{
return m_matrix.coeff(row, col);
}
inline Scalar& coeffRef(int row, int 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 coeff(int index) const
inline const Scalar& coeffRef(Index index) const
{
return m_matrix.coeff(index);
return m_matrix.const_cast_derived().coeffRef(index);
}
inline Scalar& coeffRef(int 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(int row, int col) const
inline const PacketScalar packet(Index row, Index col) const
{
return m_matrix.template packet<LoadMode>(row, col);
}
template<int LoadMode>
inline void writePacket(int row, int col, const PacketScalar& x)
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(int index) const
inline const PacketScalar packet(Index index) const
{
return m_matrix.template packet<LoadMode>(index);
}
template<int LoadMode>
inline void writePacket(int index, const PacketScalar& x)
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 flags
/** \returns an expression of *this with added and removed flags
*
* \addexample MarkExample \label How to mark a triangular matrix as triangular
* This is mostly for internal use.
*
* Example: \include MatrixBase_marked.cpp
* Output: \verbinclude MatrixBase_marked.out
*
* \sa class Flagged, extract(), part()
* \sa class Flagged
*/
template<typename Derived>
template<unsigned int Added>
inline const Flagged<Derived, Added, 0>
MatrixBase<Derived>::marked() const
{
return derived();
}
/** \returns an expression of *this with the following flags removed:
* EvalBeforeNestingBit and EvalBeforeAssigningBit.
*
* Example: \include MatrixBase_lazy.cpp
* Output: \verbinclude MatrixBase_lazy.out
*
* \sa class Flagged, marked()
*/
template<typename Derived>
inline const Flagged<Derived, 0, EvalBeforeNestingBit | EvalBeforeAssigningBit>
MatrixBase<Derived>::lazy() const
template<unsigned int Added,unsigned int Removed>
inline const Flagged<Derived, Added, Removed>
DenseBase<Derived>::flagged() const
{
return derived();
}

View File

@@ -0,0 +1,157 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_FORCEALIGNEDACCESS_H
#define EIGEN_FORCEALIGNEDACCESS_H
/** \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();
}
#endif // EIGEN_FORCEALIGNEDACCESS_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -26,7 +26,67 @@
#ifndef EIGEN_FUZZY_H
#define EIGEN_FUZZY_H
#ifndef EIGEN_LEGACY_COMPARES
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)
{
const typename internal::nested<Derived,2>::type nested(x);
const typename internal::nested<OtherDerived,2>::type otherNested(y);
return (nested - otherNested).cwiseAbs2().sum() <= prec * prec * std::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.
@@ -40,21 +100,19 @@
* \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 ei_isMuchSmallerThan(const
* or vector. If you want to test whether \c *this is zero, use internal::isMuchSmallerThan(const
* RealScalar&, RealScalar) instead.
*
* \sa ei_isMuchSmallerThan(const RealScalar&, RealScalar) const
* \sa internal::isMuchSmallerThan(const RealScalar&, RealScalar) const
*/
template<typename Derived>
template<typename OtherDerived>
bool MatrixBase<Derived>::isApprox(
const MatrixBase<OtherDerived>& other,
typename NumTraits<Scalar>::Real prec
bool DenseBase<Derived>::isApprox(
const DenseBase<OtherDerived>& other,
RealScalar prec
) const
{
const typename ei_nested<Derived,2>::type nested(derived());
const typename ei_nested<OtherDerived,2>::type otherNested(other.derived());
return (nested - otherNested).cwise().abs2().sum() <= prec * prec * std::min(nested.cwise().abs2().sum(), otherNested.cwise().abs2().sum());
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,
@@ -68,15 +126,15 @@ bool MatrixBase<Derived>::isApprox(
* 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 MatrixBase<OtherDerived>&, RealScalar) const
* \sa isApprox(), isMuchSmallerThan(const DenseBase<OtherDerived>&, RealScalar) const
*/
template<typename Derived>
bool MatrixBase<Derived>::isMuchSmallerThan(
bool DenseBase<Derived>::isMuchSmallerThan(
const typename NumTraits<Scalar>::Real& other,
typename NumTraits<Scalar>::Real prec
RealScalar prec
) const
{
return cwise().abs2().sum() <= prec * prec * other * other;
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,
@@ -91,144 +149,12 @@ bool MatrixBase<Derived>::isMuchSmallerThan(
*/
template<typename Derived>
template<typename OtherDerived>
bool MatrixBase<Derived>::isMuchSmallerThan(
const MatrixBase<OtherDerived>& other,
typename NumTraits<Scalar>::Real prec
bool DenseBase<Derived>::isMuchSmallerThan(
const DenseBase<OtherDerived>& other,
RealScalar prec
) const
{
return this->cwise().abs2().sum() <= prec * prec * other.cwise().abs2().sum();
return internal::isMuchSmallerThan_object_selector<Derived, OtherDerived>::run(derived(), other.derived(), prec);
}
#else
template<typename Derived, typename OtherDerived=Derived, bool IsVector=Derived::IsVectorAtCompileTime>
struct ei_fuzzy_selector;
/** \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 on all columns.
*
* \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 ei_isMuchSmallerThan(const
* RealScalar&, RealScalar) instead.
*
* \sa ei_isMuchSmallerThan(const RealScalar&, RealScalar) const
*/
template<typename Derived>
template<typename OtherDerived>
bool MatrixBase<Derived>::isApprox(
const MatrixBase<OtherDerived>& other,
typename NumTraits<Scalar>::Real prec
) const
{
return ei_fuzzy_selector<Derived,OtherDerived>::isApprox(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 on all columns.
*
* \sa isApprox(), isMuchSmallerThan(const MatrixBase<OtherDerived>&, RealScalar) const
*/
template<typename Derived>
bool MatrixBase<Derived>::isMuchSmallerThan(
const typename NumTraits<Scalar>::Real& other,
typename NumTraits<Scalar>::Real prec
) const
{
return ei_fuzzy_selector<Derived>::isMuchSmallerThan(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 on all columns.
*
* \sa isApprox(), isMuchSmallerThan(const RealScalar&, RealScalar) const
*/
template<typename Derived>
template<typename OtherDerived>
bool MatrixBase<Derived>::isMuchSmallerThan(
const MatrixBase<OtherDerived>& other,
typename NumTraits<Scalar>::Real prec
) const
{
return ei_fuzzy_selector<Derived,OtherDerived>::isMuchSmallerThan(derived(), other.derived(), prec);
}
template<typename Derived, typename OtherDerived>
struct ei_fuzzy_selector<Derived,OtherDerived,true>
{
typedef typename Derived::RealScalar RealScalar;
static bool isApprox(const Derived& self, const OtherDerived& other, RealScalar prec)
{
EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
ei_assert(self.size() == other.size());
return((self - other).squaredNorm() <= std::min(self.squaredNorm(), other.squaredNorm()) * prec * prec);
}
static bool isMuchSmallerThan(const Derived& self, const RealScalar& other, RealScalar prec)
{
return(self.squaredNorm() <= ei_abs2(other * prec));
}
static bool isMuchSmallerThan(const Derived& self, const OtherDerived& other, RealScalar prec)
{
EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
ei_assert(self.size() == other.size());
return(self.squaredNorm() <= other.squaredNorm() * prec * prec);
}
};
template<typename Derived, typename OtherDerived>
struct ei_fuzzy_selector<Derived,OtherDerived,false>
{
typedef typename Derived::RealScalar RealScalar;
static bool isApprox(const Derived& self, const OtherDerived& other, RealScalar prec)
{
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)
ei_assert(self.rows() == other.rows() && self.cols() == other.cols());
typename Derived::Nested nested(self);
typename OtherDerived::Nested otherNested(other);
for(int i = 0; i < self.cols(); ++i)
if((nested.col(i) - otherNested.col(i)).squaredNorm()
> std::min(nested.col(i).squaredNorm(), otherNested.col(i).squaredNorm()) * prec * prec)
return false;
return true;
}
static bool isMuchSmallerThan(const Derived& self, const RealScalar& other, RealScalar prec)
{
typename Derived::Nested nested(self);
for(int i = 0; i < self.cols(); ++i)
if(nested.col(i).squaredNorm() > ei_abs2(other * prec))
return false;
return true;
}
static bool isMuchSmallerThan(const Derived& self, const OtherDerived& other, RealScalar prec)
{
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)
ei_assert(self.rows() == other.rows() && self.cols() == other.cols());
typename Derived::Nested nested(self);
typename OtherDerived::Nested otherNested(other);
for(int i = 0; i < self.cols(); ++i)
if(nested.col(i).squaredNorm() > otherNested.col(i).squaredNorm() * prec * prec)
return false;
return true;
}
};
#endif
#endif // EIGEN_FUZZY_H

View File

@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
@@ -26,6 +26,8 @@
#ifndef EIGEN_GENERIC_PACKET_MATH_H
#define EIGEN_GENERIC_PACKET_MATH_H
namespace internal {
/** \internal
* \file GenericPacketMath.h
*
@@ -34,68 +36,235 @@
* 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
ei_padd(const Packet& a,
padd(const Packet& a,
const Packet& b) { return a+b; }
/** \internal \returns a - b (coeff-wise) */
template<typename Packet> inline Packet
ei_psub(const Packet& a,
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
ei_pmul(const Packet& a,
pmul(const Packet& a,
const Packet& b) { return a*b; }
/** \internal \returns a / b (coeff-wise) */
template<typename Packet> inline Packet
ei_pdiv(const Packet& a,
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
ei_pmin(const Packet& a,
pmin(const Packet& a,
const Packet& b) { return std::min(a, b); }
/** \internal \returns the max of \a a and \a b (coeff-wise) */
template<typename Packet> inline Packet
ei_pmax(const Packet& a,
pmax(const Packet& a,
const Packet& b) { return std::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 Scalar> inline typename ei_packet_traits<Scalar>::type
ei_pload(const Scalar* from) { return *from; }
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 Scalar> inline typename ei_packet_traits<Scalar>::type
ei_ploadu(const Scalar* from) { return *from; }
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 Scalar> inline typename ei_packet_traits<Scalar>::type
ei_pset1(const Scalar& a) { return 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 ei_pstore(Scalar* to, const Packet& from)
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 ei_pstoreu(Scalar* to, const Packet& from)
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 ei_unpacket_traits<Packet>::type ei_pfirst(const Packet& a)
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
ei_preduxp(const Packet* vecs) { return vecs[0]; }
preduxp(const Packet* vecs) { return vecs[0]; }
/** \internal \returns the sum of the elements of \a a*/
template<typename Packet> inline typename ei_unpacket_traits<Packet>::type ei_predux(const Packet& 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
@@ -103,36 +272,36 @@ template<typename Packet> inline typename ei_unpacket_traits<Packet>::type ei_pr
/** \internal \returns a * b + c (coeff-wise) */
template<typename Packet> inline Packet
ei_pmadd(const Packet& a,
pmadd(const Packet& a,
const Packet& b,
const Packet& c)
{ return ei_padd(ei_pmul(a, b),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 Scalar, int LoadMode>
inline typename ei_packet_traits<Scalar>::type ei_ploadt(const Scalar* from)
template<typename Packet, int LoadMode>
inline Packet ploadt(const typename unpacket_traits<Packet>::type* from)
{
if(LoadMode == Aligned)
return ei_pload(from);
return pload<Packet>(from);
else
return ei_ploadu(from);
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 ei_pstoret(Scalar* to, const Packet& from)
inline void pstoret(Scalar* to, const Packet& from)
{
if(LoadMode == Aligned)
ei_pstore(to, from);
pstore(to, from);
else
ei_pstoreu(to, from);
pstoreu(to, from);
}
/** \internal default implementation of ei_palign() allowing partial specialization */
/** \internal default implementation of palign() allowing partial specialization */
template<int Offset,typename PacketType>
struct ei_palign_impl
struct palign_impl
{
// by default data are aligned, so there is nothing to be done :)
inline static void run(PacketType&, const PacketType&) {}
@@ -141,10 +310,22 @@ struct ei_palign_impl
/** \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 ei_palign(PacketType& first, const PacketType& second)
inline void palign(PacketType& first, const PacketType& second)
{
ei_palign_impl<Offset,PacketType>::run(first,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
#endif // EIGEN_GENERIC_PACKET_MATH_H

View File

@@ -0,0 +1,95 @@
// 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>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_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); \
}
}
namespace Eigen
{
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

View File

@@ -1,8 +1,8 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -26,15 +26,28 @@
#ifndef EIGEN_IO_H
#define EIGEN_IO_H
enum { Raw, AlignCols };
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
* - \b flags can be either Raw (default) or AlignCols which aligns all the columns
* - \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
@@ -45,12 +58,12 @@ enum { Raw, AlignCols };
* Example: \include IOFormat.cpp
* Output: \verbinclude IOFormat.out
*
* \sa MatrixBase::format(), class WithFormat
* \sa DenseBase::format(), class WithFormat
*/
struct IOFormat
{
/** Default contructor, see class IOFormat for the meaning of the parameters */
IOFormat(int _precision=4, int _flags=Raw,
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="")
@@ -73,18 +86,19 @@ struct IOFormat
};
/** \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 MatrixBase::format()
* 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 MatrixBase::format(), class IOFormat
* \sa DenseBase::format(), class IOFormat
*/
template<typename ExpressionType>
class WithFormat
@@ -97,7 +111,7 @@ class WithFormat
friend std::ostream & operator << (std::ostream & s, const WithFormat& wf)
{
return ei_print_matrix(s, wf.m_matrix.eval(), wf.m_format);
return internal::print_matrix(s, wf.m_matrix.eval(), wf.m_format);
}
protected:
@@ -114,41 +128,99 @@ class WithFormat
*/
template<typename Derived>
inline const WithFormat<Derived>
MatrixBase<Derived>::format(const IOFormat& fmt) const
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()
{
return cast<RealScalar,int>(std::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 & ei_print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt)
std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt)
{
if(_m.size() == 0)
{
s << fmt.matPrefix << fmt.matSuffix;
return s;
}
const typename Derived::Nested m = _m;
typedef typename Derived::Scalar Scalar;
typedef typename Derived::Index Index;
int width = 0;
if (fmt.flags & AlignCols)
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(int j = 1; j < m.cols(); ++j)
for(int i = 0; i < m.rows(); ++i)
for(Index j = 1; j < m.cols(); ++j)
for(Index i = 0; i < m.rows(); ++i)
{
std::stringstream sstr;
sstr.precision(fmt.precision);
if(explicit_precision) sstr.precision(explicit_precision);
sstr << m.coeff(i,j);
width = std::max<int>(width, int(sstr.str().length()));
width = std::max<Index>(width, Index(sstr.str().length()));
}
}
s.precision(fmt.precision);
std::streamsize old_precision = 0;
if(explicit_precision) old_precision = s.precision(explicit_precision);
s << fmt.matPrefix;
for(int i = 0; i < m.rows(); ++i)
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(int j = 1; j < m.cols(); ++j)
for(Index j = 1; j < m.cols(); ++j)
{
s << fmt.coeffSeparator;
if (width) s.width(width);
@@ -159,26 +231,29 @@ std::ostream & ei_print_matrix(std::ostream & s, const Derived& _m, const IOForm
s << fmt.rowSeparator;
}
s << fmt.matSuffix;
if(explicit_precision) s.precision(old_precision);
return s;
}
/** \relates MatrixBase
} // 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 MatrixBase::format().
* 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 MatrixBase::format()
* \sa DenseBase::format()
*/
template<typename Derived>
std::ostream & operator <<
(std::ostream & s,
const MatrixBase<Derived> & m)
const DenseBase<Derived> & m)
{
return ei_print_matrix(s, m.eval(), EIGEN_DEFAULT_IO_FORMAT);
return internal::print_matrix(s, m.eval(), EIGEN_DEFAULT_IO_FORMAT);
}
#endif // EIGEN_IO_H

View File

@@ -1,8 +1,8 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -27,88 +27,179 @@
#define EIGEN_MAP_H
/** \class Map
* \ingroup Core_Module
*
* \brief A matrix or vector expression mapping an existing array of data.
*
* \param MatrixType the equivalent matrix type of the mapped data
* \param _PacketAccess allows to enforce aligned loads and stores if set to ForceAligned.
* The default is AsRequested. This parameter is internaly used by Eigen
* in expressions such as \code Map<...>(...) += other; \endcode and most
* of the time this is the only way it is used.
* \param PlainObjectType the equivalent matrix type of the mapped data
* \param MapOptions specifies whether the pointer is \c Aligned, or \c Unaligned.
* The default is \c Unaligned.
* \param StrideType optionnally 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.
* 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 Matrix::Map() but can also be used directly.
*
* \sa Matrix::Map()
* \sa Matrix::Map(), \ref TopicStorageOrders
*/
template<typename MatrixType, int _PacketAccess>
struct ei_traits<Map<MatrixType, _PacketAccess> > : public ei_traits<MatrixType>
{
enum {
PacketAccess = _PacketAccess,
Flags = ei_traits<MatrixType>::Flags & ~AlignedBit
};
typedef typename ei_meta_if<int(PacketAccess)==ForceAligned,
Map<MatrixType, _PacketAccess>&,
Map<MatrixType, ForceAligned> >::ret AlignedDerivedType;
};
template<typename MatrixType, int PacketAccess> class Map
: public MapBase<Map<MatrixType, PacketAccess> >
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 = int(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,
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:
_EIGEN_GENERIC_PUBLIC_INTERFACE(Map, MapBase<Map>)
typedef typename ei_traits<Map>::AlignedDerivedType AlignedDerivedType;
typedef MapBase<Map> Base;
inline int stride() const { return this->innerSize(); }
EIGEN_DENSE_PUBLIC_INTERFACE(Map)
AlignedDerivedType forceAligned()
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
{
if (PacketAccess==ForceAligned)
return *this;
else
return Map<MatrixType,ForceAligned>(Base::m_data, Base::m_rows.value(), Base::m_cols.value());
return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
}
inline Map(const Scalar* data) : Base(data) {}
inline Map(const Scalar* data, int size) : Base(data, size) {}
inline Map(const Scalar* data, int rows, int cols) : Base(data, rows, cols) {}
inline void resize(int rows, int cols)
inline Index outerStride() const
{
EIGEN_ONLY_USED_FOR_DEBUG(rows);
EIGEN_ONLY_USED_FOR_DEBUG(cols);
ei_assert(rows == this->rows());
ei_assert(cols == this->cols());
return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
: IsVectorAtCompileTime ? this->size()
: int(Flags)&RowMajorBit ? this->cols()
: this->rows();
}
inline void resize(int size)
/** 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)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(MatrixType)
EIGEN_ONLY_USED_FOR_DEBUG(size);
ei_assert(size == this->size());
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;
};
/** Constructor copying an existing array of data.
* Only for fixed-size matrices and vectors.
* \param data The array of data to copy
*
* \sa Matrix::Map(const Scalar *)
*/
template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols>
inline Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>
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)
{
_set_noalias(Eigen::Map<Matrix>(data));
this->_set_noalias(Eigen::Map<const Matrix>(data));
}
#endif // EIGEN_MAP_H

View File

@@ -1,8 +1,8 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -26,149 +26,228 @@
#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)
/** \class MapBase
* \ingroup Core_Module
*
* \brief Base class for Map and Block expression with direct access
*
* Expression classes inheriting MapBase must define the constant \c PacketAccess,
* and type \c AlignedDerivedType in their respective ei_traits<> specialization structure.
* The value of \c PacketAccess can be either:
* - \b ForceAligned which enforces both aligned loads and stores
* - \b AsRequested which is the default behavior
* The type \c AlignedDerivedType should correspond to the equivalent expression type
* with \c PacketAccess being \c ForceAligned.
*
* \sa class Map, class Block
*/
template<typename Derived> class MapBase
: public MatrixBase<Derived>
template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
: public internal::dense_xpr_base<Derived>::type
{
public:
typedef MatrixBase<Derived> Base;
typedef typename internal::dense_xpr_base<Derived>::type Base;
enum {
IsRowMajor = (int(ei_traits<Derived>::Flags) & RowMajorBit) ? 1 : 0,
PacketAccess = ei_traits<Derived>::PacketAccess,
RowsAtCompileTime = ei_traits<Derived>::RowsAtCompileTime,
ColsAtCompileTime = ei_traits<Derived>::ColsAtCompileTime,
RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
SizeAtCompileTime = Base::SizeAtCompileTime
};
typedef typename ei_traits<Derived>::AlignedDerivedType AlignedDerivedType;
typedef typename ei_traits<Derived>::Scalar Scalar;
typedef typename Base::PacketScalar PacketScalar;
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;
inline int rows() const { return m_rows.value(); }
inline int cols() const { return m_cols.value(); }
using Base::rows;
using Base::cols;
using Base::size;
using Base::coeff;
using Base::coeffRef;
using Base::lazyAssign;
using Base::eval;
inline int stride() const { return derived().stride(); }
using Base::innerStride;
using Base::outerStride;
using Base::rowStride;
using Base::colStride;
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; }
/** \returns an expression equivalent to \c *this but having the \c PacketAccess constant
* set to \c ForceAligned. Must be reimplemented by the derived class. */
AlignedDerivedType forceAligned() { return derived().forceAligned(); }
inline const Scalar& coeff(int row, int col) const
inline const Scalar& coeff(Index row, Index col) const
{
if(IsRowMajor)
return m_data[col + row * stride()];
else // column-major
return m_data[row + col * stride()];
return m_data[col * colStride() + row * rowStride()];
}
inline Scalar& coeffRef(int row, int col)
inline const Scalar& coeff(Index index) const
{
if(IsRowMajor)
return const_cast<Scalar*>(m_data)[col + row * stride()];
else // column-major
return const_cast<Scalar*>(m_data)[row + col * stride()];
EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
return m_data[index * innerStride()];
}
inline const Scalar coeff(int index) const
inline const Scalar& coeffRef(Index row, Index col) const
{
ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit));
if ( ((RowsAtCompileTime == 1) == IsRowMajor) )
return m_data[index];
else
return m_data[index*stride()];
return this->m_data[col * colStride() + row * rowStride()];
}
inline Scalar& coeffRef(int index)
inline const Scalar& coeffRef(Index index) const
{
return *const_cast<Scalar*>(m_data + index);
EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
return this->m_data[index * innerStride()];
}
template<int LoadMode>
inline PacketScalar packet(int row, int col) const
inline PacketScalar packet(Index row, Index col) const
{
return ei_ploadt<Scalar, int(PacketAccess) == ForceAligned ? Aligned : LoadMode>
(m_data + (IsRowMajor ? col + row * stride()
: row + col * stride()));
return internal::ploadt<PacketScalar, LoadMode>
(m_data + (col * colStride() + row * rowStride()));
}
template<int LoadMode>
inline PacketScalar packet(int index) const
inline PacketScalar packet(Index index) const
{
return ei_ploadt<Scalar, int(PacketAccess) == ForceAligned ? Aligned : LoadMode>(m_data + index);
EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
return internal::ploadt<PacketScalar, LoadMode>(m_data + index * innerStride());
}
template<int StoreMode>
inline void writePacket(int row, int col, const PacketScalar& x)
{
ei_pstoret<Scalar, PacketScalar, int(PacketAccess) == ForceAligned ? Aligned : StoreMode>
(const_cast<Scalar*>(m_data) + (IsRowMajor ? col + row * stride()
: row + col * stride()), x);
}
template<int StoreMode>
inline void writePacket(int index, const PacketScalar& x)
{
ei_pstoret<Scalar, PacketScalar, int(PacketAccess) == ForceAligned ? Aligned : StoreMode>
(const_cast<Scalar*>(m_data) + index, x);
}
inline MapBase(const Scalar* data) : m_data(data), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
inline MapBase(PointerType data) : m_data(data), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
{
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
checkSanity();
}
inline MapBase(const Scalar* data, int size)
inline MapBase(PointerType data, Index size)
: m_data(data),
m_rows(RowsAtCompileTime == Dynamic ? size : RowsAtCompileTime),
m_cols(ColsAtCompileTime == Dynamic ? size : ColsAtCompileTime)
m_rows(RowsAtCompileTime == Dynamic ? size : Index(RowsAtCompileTime)),
m_cols(ColsAtCompileTime == Dynamic ? size : Index(ColsAtCompileTime))
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
ei_assert(size > 0 || data == 0);
ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
eigen_assert(size >= 0);
eigen_assert(data == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
checkSanity();
}
inline MapBase(const Scalar* data, int rows, int cols)
inline MapBase(PointerType data, Index rows, Index cols)
: m_data(data), m_rows(rows), m_cols(cols)
{
ei_assert( (data == 0)
|| ( rows > 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
&& cols > 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
eigen_assert( (data == 0)
|| ( rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
&& cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
checkSanity();
}
template<typename OtherDerived>
Derived& operator+=(const MatrixBase<OtherDerived>& other)
{ return derived() = forceAligned() + other; }
template<typename OtherDerived>
Derived& operator-=(const MatrixBase<OtherDerived>& other)
{ return derived() = forceAligned() - other; }
Derived& operator*=(const Scalar& other)
{ return derived() = forceAligned() * other; }
Derived& operator/=(const Scalar& other)
{ return derived() = forceAligned() / other; }
protected:
const Scalar* EIGEN_RESTRICT m_data;
const ei_int_if_dynamic<RowsAtCompileTime> m_rows;
const ei_int_if_dynamic<ColsAtCompileTime> m_cols;
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) % (sizeof(Scalar)*internal::packet_traits<Scalar>::size)) == 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);
}
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=;
};
#endif // EIGEN_MAPBASE_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,8 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -25,8 +26,8 @@
#ifndef EIGEN_MATRIX_H
#define EIGEN_MATRIX_H
/** \class Matrix
* \ingroup Core_Module
*
* \brief The matrix class, also used for vectors and row-vectors
*
@@ -36,17 +37,18 @@
* The %Matrix class encompasses \em both fixed-size and dynamic-size objects (\ref fixedsize "note").
*
* The first three template parameters are required:
* \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
* \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.
* \param _Options A combination of either \b RowMajor or \b ColMajor, and of either
* \tparam _Options \anchor matrix_tparam_options A combination of either \b RowMajor or \b ColMajor, and of either
* \b AutoAlign or \b DontAlign.
* The former controls storage order, and defaults to column-major. The latter controls alignment, which is required
* The former controls \ref TopicStorageOrders "storage order", and defaults to column-major. The latter controls alignment, which is required
* for vectorization. It defaults to aligning matrices except for fixed sizes that aren't a multiple of the packet size.
* \param _MaxRows Maximum number of rows. Defaults to \a _Rows (\ref maxrows "note").
* \param _MaxCols Maximum number of columns. Defaults to \a _Cols (\ref maxrows "note").
* \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:
*
@@ -57,6 +59,9 @@
* \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:
@@ -74,6 +79,9 @@
* 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>
@@ -102,153 +110,71 @@
* 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
* \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 ei_traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _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 = ei_compute_matrix_flags<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ret,
CoeffReadCost = NumTraits<Scalar>::ReadCost
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 MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
: public PlainObjectBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
{
public:
EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix)
/** \brief Base class typedef.
* \sa PlainObjectBase
*/
typedef PlainObjectBase<Matrix> Base;
enum { Options = _Options };
friend class Eigen::Map<Matrix, Unaligned>;
typedef class Eigen::Map<Matrix, Unaligned> UnalignedMapType;
friend class Eigen::Map<Matrix, Aligned>;
typedef class Eigen::Map<Matrix, Aligned> AlignedMapType;
protected:
ei_matrix_storage<Scalar, MaxSizeAtCompileTime, RowsAtCompileTime, ColsAtCompileTime, Options> m_storage;
EIGEN_DENSE_PUBLIC_INTERFACE(Matrix)
public:
enum { NeedsToAlign = (Options&AutoAlign) == AutoAlign
&& SizeAtCompileTime!=Dynamic && ((sizeof(Scalar)*SizeAtCompileTime)%16)==0 };
typedef typename Base::PlainObject PlainObject;
enum { NeedsToAlign = (!(Options&DontAlign))
&& SizeAtCompileTime!=Dynamic && ((static_cast<int>(sizeof(Scalar))*SizeAtCompileTime)%16)==0 };
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
EIGEN_STRONG_INLINE int rows() const { return m_storage.rows(); }
EIGEN_STRONG_INLINE int cols() const { return m_storage.cols(); }
using Base::base;
using Base::coeffRef;
EIGEN_STRONG_INLINE int stride(void) const
{
if(Flags & RowMajorBit)
return m_storage.cols();
else
return m_storage.rows();
}
EIGEN_STRONG_INLINE const Scalar& coeff(int row, int 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(int index) const
{
return m_storage.data()[index];
}
EIGEN_STRONG_INLINE Scalar& coeffRef(int row, int 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(int index)
{
return m_storage.data()[index];
}
template<int LoadMode>
EIGEN_STRONG_INLINE PacketScalar packet(int row, int col) const
{
return ei_ploadt<Scalar, LoadMode>
(m_storage.data() + (Flags & RowMajorBit
? col + row * m_storage.cols()
: row + col * m_storage.rows()));
}
template<int LoadMode>
EIGEN_STRONG_INLINE PacketScalar packet(int index) const
{
return ei_ploadt<Scalar, LoadMode>(m_storage.data() + index);
}
template<int StoreMode>
EIGEN_STRONG_INLINE void writePacket(int row, int col, const PacketScalar& x)
{
ei_pstoret<Scalar, PacketScalar, StoreMode>
(m_storage.data() + (Flags & RowMajorBit
? col + row * m_storage.cols()
: row + col * m_storage.rows()), x);
}
template<int StoreMode>
EIGEN_STRONG_INLINE void writePacket(int index, const PacketScalar& x)
{
ei_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.
/**
* \brief Assigns matrices to each other.
*
* Makes sense for dynamic-size matrices only.
* \note This is a special case of the templated operator=. Its purpose is
* to prevent a default operator= from hiding the templated operator=.
*
* 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.
*
* \sa resize(int) for vectors.
* \callgraph
*/
inline void resize(int rows, int cols)
EIGEN_STRONG_INLINE Matrix& operator=(const Matrix& other)
{
ei_assert(rows > 0 && cols > 0 && "a matrix cannot be resized to 0 size");
ei_assert((MaxRowsAtCompileTime == Dynamic || MaxRowsAtCompileTime >= rows)
&& (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
&& (MaxColsAtCompileTime == Dynamic || MaxColsAtCompileTime >= cols)
&& (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
m_storage.resize(rows * cols, rows, cols);
return Base::_set(other);
}
/** Resizes \c *this to a vector of length \a size
*
* \sa resize(int,int) for the details.
*/
inline void resize(int size)
{
ei_assert(size>0 && "a vector cannot be resized to 0 length");
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix)
if(RowsAtCompileTime == 1)
m_storage.resize(size, 1, size);
else
m_storage.resize(size, size, 1);
}
/** Copies the value of the expression \a other into \c *this with automatic resizing.
/** \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.
@@ -260,23 +186,28 @@ class Matrix
template<typename OtherDerived>
EIGEN_STRONG_INLINE Matrix& operator=(const MatrixBase<OtherDerived>& other)
{
return _set(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=.
/* 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)
*/
EIGEN_STRONG_INLINE Matrix& operator=(const Matrix& other)
template<typename OtherDerived>
EIGEN_STRONG_INLINE Matrix& operator=(const EigenBase<OtherDerived> &other)
{
return _set(other);
return Base::operator=(other);
}
EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Matrix, +=)
EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Matrix, -=)
EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Matrix, *=)
EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Matrix, /=)
template<typename OtherDerived>
EIGEN_STRONG_INLINE Matrix& operator=(const ReturnByValue<OtherDerived>& func)
{
return Base::operator=(func);
}
/** Default constructor.
/** \brief Default constructor.
*
* For fixed-size matrices, does nothing.
*
@@ -284,89 +215,66 @@ class 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(int,int)
* \sa resize(Index,Index)
*/
EIGEN_STRONG_INLINE explicit Matrix() : m_storage()
EIGEN_STRONG_INLINE explicit Matrix() : Base()
{
_check_template_params();
Base::_check_template_params();
EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
}
#ifndef EIGEN_PARSED_BY_DOXYGEN
/** \internal */
Matrix(ei_constructor_without_unaligned_array_assert)
: m_storage(ei_constructor_without_unaligned_array_assert())
{}
#endif
// 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 }
/** Constructs a vector or row-vector with given dimension. \only_for_vectors
/** \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(int dim)
: m_storage(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim)
EIGEN_STRONG_INLINE explicit Matrix(Index dim)
: Base(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim)
{
_check_template_params();
Base::_check_template_params();
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix)
ei_assert(dim > 0);
ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim);
eigen_assert(dim >= 0);
eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim);
EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
}
/** This constructor has two very different behaviors, depending on the type of *this.
#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.
*
* \li When Matrix is a fixed-size vector type of size 2, this constructor constructs
* an initialized vector. The parameters \a x, \a y are copied into the first and second
* coords of the vector respectively.
* \li Otherwise, this constructor constructs an uninitialized matrix with \a x rows and
* \a y 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.
*/
EIGEN_STRONG_INLINE Matrix(int x, int y) : m_storage(x*y, x, y)
{
_check_template_params();
if((RowsAtCompileTime == 1 && ColsAtCompileTime == 2)
|| (RowsAtCompileTime == 2 && ColsAtCompileTime == 1))
{
m_storage.data()[0] = Scalar(x);
m_storage.data()[1] = Scalar(y);
}
else
{
ei_assert(x > 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == x)
&& y > 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == y));
}
}
/** constructs an initialized 2D vector with given coefficients */
EIGEN_STRONG_INLINE Matrix(const float& x, const float& y)
{
_check_template_params();
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 2)
m_storage.data()[0] = x;
m_storage.data()[1] = y;
}
/** constructs an initialized 2D vector with given coefficients */
EIGEN_STRONG_INLINE Matrix(const double& x, const double& y)
{
_check_template_params();
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 2)
m_storage.data()[0] = x;
m_storage.data()[1] = y;
}
/** constructs an initialized 3D vector with given coefficients */
* 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)
{
_check_template_params();
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;
}
/** constructs an initialized 4D vector with given coefficients */
/** \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)
{
_check_template_params();
Base::_check_template_params();
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 4)
m_storage.data()[0] = x;
m_storage.data()[1] = y;
@@ -376,147 +284,84 @@ class Matrix
explicit Matrix(const Scalar *data);
/** Constructor copying the value of the expression \a other */
/** \brief Constructor copying the value of the expression \a other */
template<typename OtherDerived>
EIGEN_STRONG_INLINE Matrix(const MatrixBase<OtherDerived>& other)
: m_storage(other.rows() * other.cols(), other.rows(), other.cols())
: Base(other.rows() * other.cols(), other.rows(), other.cols())
{
_check_template_params();
_set_noalias(other);
// 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);
}
/** Copy constructor */
/** \brief Copy constructor */
EIGEN_STRONG_INLINE Matrix(const Matrix& other)
: Base(), m_storage(other.rows() * other.cols(), other.rows(), other.cols())
: Base(other.rows() * other.cols(), other.rows(), other.cols())
{
_check_template_params();
_set_noalias(other);
Base::_check_template_params();
Base::_set_noalias(other);
}
/** Destructor */
inline ~Matrix() {}
/** Override MatrixBase::swap() since for dynamic-sized matrices of same type it is enough to swap the
* data pointers.
*/
inline void swap(Matrix& other)
/** \brief Copy constructor with in-place evaluation */
template<typename OtherDerived>
EIGEN_STRONG_INLINE Matrix(const ReturnByValue<OtherDerived>& other)
{
if (Base::SizeAtCompileTime==Dynamic)
m_storage.swap(other.m_storage);
else
this->Base::swap(other);
Base::_check_template_params();
Base::resize(other.rows(), other.cols());
other.evalTo(*this);
}
/** \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
/** \brief Copy constructor for generic expressions.
* \sa MatrixBase::operator=(const EigenBase<OtherDerived>&)
*/
//@{
inline static const UnalignedMapType Map(const Scalar* data)
{ return UnalignedMapType(data); }
inline static UnalignedMapType Map(Scalar* data)
{ return UnalignedMapType(data); }
inline static const UnalignedMapType Map(const Scalar* data, int size)
{ return UnalignedMapType(data, size); }
inline static UnalignedMapType Map(Scalar* data, int size)
{ return UnalignedMapType(data, size); }
inline static const UnalignedMapType Map(const Scalar* data, int rows, int cols)
{ return UnalignedMapType(data, rows, cols); }
inline static UnalignedMapType Map(Scalar* data, int rows, int cols)
{ return UnalignedMapType(data, rows, cols); }
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;
}
inline static const AlignedMapType MapAligned(const Scalar* data)
{ return AlignedMapType(data); }
inline static AlignedMapType MapAligned(Scalar* data)
{ return AlignedMapType(data); }
inline static const AlignedMapType MapAligned(const Scalar* data, int size)
{ return AlignedMapType(data, size); }
inline static AlignedMapType MapAligned(Scalar* data, int size)
{ return AlignedMapType(data, size); }
inline static const AlignedMapType MapAligned(const Scalar* data, int rows, int cols)
{ return AlignedMapType(data, rows, cols); }
inline static AlignedMapType MapAligned(Scalar* data, int rows, int cols)
{ return AlignedMapType(data, rows, cols); }
//@}
/** \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()); }
/////////// Geometry module ///////////
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
private:
/** \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 MatrixBase<OtherDerived>& other)
{
if(RowsAtCompileTime == 1)
{
ei_assert(other.isVector());
resize(1, other.size());
}
else if(ColsAtCompileTime == 1)
{
ei_assert(other.isVector());
resize(other.size(), 1);
}
else resize(other.rows(), other.cols());
}
protected:
template <typename Derived, typename OtherDerived, bool IsVector>
friend struct internal::conservative_resize_like_impl;
/** \internal 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()
*/
template<typename OtherDerived>
EIGEN_STRONG_INLINE Matrix& _set(const MatrixBase<OtherDerived>& other)
{
_resize_to_match(other);
return Base::operator=(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 Matrix& _set_noalias(const MatrixBase<OtherDerived>& other)
{
_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 ei_assign_selector<Matrix,OtherDerived,false>::run(*this, other.derived());
}
static EIGEN_STRONG_INLINE void _check_template_params()
{
EIGEN_STATIC_ASSERT((_Rows > 0
&& _Cols > 0
&& _MaxRows <= _Rows
&& _MaxCols <= _Cols
&& (_Options & (AutoAlign|RowMajor)) == _Options),
INVALID_MATRIX_TEMPLATE_PARAMETERS)
}
using Base::m_storage;
};
/** \defgroup matrixtypedefs Global matrix typedefs
@@ -547,11 +392,20 @@ 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_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)

View File

@@ -1,8 +1,8 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -27,16 +27,18 @@
#define EIGEN_MATRIXBASE_H
/** \class MatrixBase
* \ingroup Core_Module
*
* \brief Base class for all matrices, vectors, and expressions
* \brief Base class for all dense matrices, vectors, and expressions
*
* This class is the base that is inherited by all matrix, vector, and expression
* types. Most of the Eigen API is contained in this class. Other important classes for
* the Eigen API are Matrix, Cwise, and PartialRedux.
* 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 the \ref Array module.
* Note that some methods are defined in other modules such as the \ref LU_Module LU module
* for all functions related to matrix inversions.
*
* \param Derived is the derived type, e.g. a matrix type, or an expression, etc.
* \tparam Derived is the derived type, e.g. a matrix type, or an expression, etc.
*
* When writing a function taking Eigen objects as argument, if you want your function
* to take as argument any matrix, vector, or expression, just let it take a
@@ -51,578 +53,468 @@
}
* \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
class InnerIterator;
typedef typename ei_traits<Derived>::Scalar Scalar;
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
#endif // not EIGEN_PARSED_BY_DOXYGEN
enum {
RowsAtCompileTime = ei_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 = ei_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 = (ei_size_at_compile_time<ei_traits<Derived>::RowsAtCompileTime,
ei_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 = ei_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 = ei_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 = (ei_size_at_compile_time<ei_traits<Derived>::MaxRowsAtCompileTime,
ei_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 = ei_traits<Derived>::RowsAtCompileTime == 1
|| ei_traits<Derived>::ColsAtCompileTime == 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 = ei_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".
*/
CoeffReadCost = ei_traits<Derived>::CoeffReadCost
/**< This is a rough measure of how expensive it is to read one coefficient from
* this expression.
*/
};
/** Default constructor. Just checks at compile-time for self-consistency of the flags. */
MatrixBase()
{
ei_assert(ei_are_flags_consistent<Flags>::ret);
}
#ifndef EIGEN_PARSED_BY_DOXYGEN
/** This is the "real scalar" type; if the \a Scalar type is already real numbers
* (e.g. int, float or double) then \a RealScalar is just the same as \a Scalar. If
* \a Scalar is \a std::complex<T> then RealScalar is \a T.
*
* \sa class NumTraits
*/
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;
/** type of the equivalent square matrix */
typedef Matrix<Scalar,EIGEN_ENUM_MAX(RowsAtCompileTime,ColsAtCompileTime),
EIGEN_ENUM_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType;
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
/** \returns the number of rows. \sa cols(), RowsAtCompileTime */
inline int rows() const { return derived().rows(); }
/** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
inline int cols() const { return derived().cols(); }
/** \returns the number of coefficients, which is \a rows()*cols().
* \sa rows(), cols(), SizeAtCompileTime. */
inline int size() const { return rows() * cols(); }
/** \returns the number of nonzero coefficients which is in practice the number
* of stored coefficients. */
inline int nonZeros() const { return derived.nonZeros(); }
/** \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. */
inline bool isVector() const { return rows()==1 || cols()==1; }
/** \returns the size of the storage major dimension,
* i.e., the number of columns for a columns major matrix, and the number of rows otherwise */
int outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); }
/** \returns the size of the inner dimension according to the storage order,
* i.e., the number of rows for a columns major matrix, and the number of cols otherwise */
int innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); }
#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 guaranteed however, that the return type of eval() is either
* PlainMatrixType or const PlainMatrixType&.
*/
typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType;
/** \internal the column-major 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!
* The only difference from PlainMatrixType is that PlainMatrixType_ColMajor is guaranteed to be column-major.
*/
typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType_ColMajor;
/** \internal Represents a matrix with all coefficients equal to one another*/
typedef CwiseNullaryOp<ei_scalar_constant_op<Scalar>,Derived> ConstantReturnType;
/** \internal Represents a scalar multiple of a matrix */
typedef CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, Derived> ScalarMultipleReturnType;
/** \internal Represents a quotient of a matrix by a scalar*/
typedef CwiseUnaryOp<ei_scalar_quotient1_op<Scalar>, Derived> ScalarQuotient1ReturnType;
/** \internal the return type of MatrixBase::conjugate() */
typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex,
const CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Derived>,
const Derived&
>::ret ConjugateReturnType;
/** \internal the return type of MatrixBase::real() */
typedef CwiseUnaryOp<ei_scalar_real_op<Scalar>, Derived> RealReturnType;
/** \internal the return type of MatrixBase::imag() */
typedef CwiseUnaryOp<ei_scalar_imag_op<Scalar>, Derived> ImagReturnType;
/** \internal the return type of MatrixBase::adjoint() */
typedef Eigen::Transpose<NestByValue<typename ei_cleantype<ConjugateReturnType>::type> >
AdjointReturnType;
/** \internal the return type of MatrixBase::eigenvalues() */
typedef Matrix<typename NumTraits<typename ei_traits<Derived>::Scalar>::Real, ei_traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType;
/** \internal expression tyepe of a column */
typedef Block<Derived, ei_traits<Derived>::RowsAtCompileTime, 1> ColXpr;
/** \internal expression tyepe of a column */
typedef Block<Derived, 1, ei_traits<Derived>::ColsAtCompileTime> RowXpr;
/** \internal the return type of identity */
typedef CwiseNullaryOp<ei_scalar_identity_op<Scalar>,Derived> IdentityReturnType;
/** \internal the return type of unit vectors */
typedef Block<CwiseNullaryOp<ei_scalar_identity_op<Scalar>, SquareMatrixType>,
ei_traits<Derived>::RowsAtCompileTime,
ei_traits<Derived>::ColsAtCompileTime> BasisReturnType;
/** 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()); }
/** Copies \a other into *this. \returns a reference to *this. */
template<typename OtherDerived>
Derived& operator=(const MatrixBase<OtherDerived>& other);
/** \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)
*/
inline Derived& operator=(const MatrixBase& other)
{
return this->operator=<Derived>(other);
}
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
/** Copies \a other into *this without evaluating other. \returns a reference to *this. */
template<typename OtherDerived>
Derived& lazyAssign(const MatrixBase<OtherDerived>& other);
/** Overloaded for cache friendly product evaluation */
template<typename Lhs, typename Rhs>
Derived& lazyAssign(const Product<Lhs,Rhs,CacheFriendlyProduct>& product);
/** Overloaded for cache friendly product evaluation */
template<typename OtherDerived>
Derived& lazyAssign(const Flagged<OtherDerived, 0, EvalBeforeNestingBit | EvalBeforeAssigningBit>& other)
{ return lazyAssign(other._expression()); }
template<typename ProductDerived, typename Lhs, typename Rhs>
Derived& lazyAssign(const ProductBase<ProductDerived, Lhs,Rhs>& other);
#endif // not EIGEN_PARSED_BY_DOXYGEN
CommaInitializer<Derived> operator<< (const Scalar& s);
template<typename OtherDerived>
CommaInitializer<Derived> operator<< (const MatrixBase<OtherDerived>& other);
const Scalar coeff(int row, int col) const;
const Scalar operator()(int row, int col) const;
Scalar& coeffRef(int row, int col);
Scalar& operator()(int row, int col);
const Scalar coeff(int index) const;
const Scalar operator[](int index) const;
const Scalar operator()(int index) const;
Scalar& coeffRef(int index);
Scalar& operator[](int index);
Scalar& operator()(int index);
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename OtherDerived>
void copyCoeff(int row, int col, const MatrixBase<OtherDerived>& other);
template<typename OtherDerived>
void copyCoeff(int index, const MatrixBase<OtherDerived>& other);
template<typename OtherDerived, int StoreMode, int LoadMode>
void copyPacket(int row, int col, const MatrixBase<OtherDerived>& other);
template<typename OtherDerived, int StoreMode, int LoadMode>
void copyPacket(int index, const MatrixBase<OtherDerived>& other);
#endif // not EIGEN_PARSED_BY_DOXYGEN
template<int LoadMode>
PacketScalar packet(int row, int col) const;
template<int StoreMode>
void writePacket(int row, int col, const PacketScalar& x);
template<int LoadMode>
PacketScalar packet(int index) const;
template<int StoreMode>
void writePacket(int index, const PacketScalar& x);
const Scalar x() const;
const Scalar y() const;
const Scalar z() const;
const Scalar w() const;
Scalar& x();
Scalar& y();
Scalar& z();
Scalar& w();
const CwiseUnaryOp<ei_scalar_opposite_op<typename ei_traits<Derived>::Scalar>,Derived> operator-() const;
template<typename OtherDerived>
const CwiseBinaryOp<ei_scalar_sum_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived>
operator+(const MatrixBase<OtherDerived> &other) const;
template<typename OtherDerived>
const CwiseBinaryOp<ei_scalar_difference_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived>
operator-(const MatrixBase<OtherDerived> &other) const;
template<typename OtherDerived>
Derived& operator+=(const MatrixBase<OtherDerived>& other);
template<typename OtherDerived>
Derived& operator-=(const MatrixBase<OtherDerived>& other);
template<typename Lhs,typename Rhs>
Derived& operator+=(const Flagged<Product<Lhs,Rhs,CacheFriendlyProduct>, 0, EvalBeforeNestingBit | EvalBeforeAssigningBit>& other);
Derived& operator*=(const Scalar& other);
Derived& operator/=(const Scalar& other);
const ScalarMultipleReturnType operator*(const Scalar& scalar) const;
const CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived>
operator/(const Scalar& scalar) const;
inline friend const CwiseUnaryOp<ei_scalar_multiple_op<typename ei_traits<Derived>::Scalar>, Derived>
operator*(const Scalar& scalar, const MatrixBase& matrix)
{ return matrix*scalar; }
template<typename OtherDerived>
const typename ProductReturnType<Derived,OtherDerived>::Type
operator*(const MatrixBase<OtherDerived> &other) const;
template<typename OtherDerived>
Derived& operator*=(const MatrixBase<OtherDerived>& other);
const typename LazyProductReturnType<Derived,OtherDerived>::Type
lazyProduct(const MatrixBase<OtherDerived> &other) const;
template<typename OtherDerived>
typename ei_plain_matrix_type_column_major<OtherDerived>::type
solveTriangular(const MatrixBase<OtherDerived>& other) const;
Derived& operator*=(const EigenBase<OtherDerived>& other);
template<typename OtherDerived>
void solveTriangularInPlace(const MatrixBase<OtherDerived>& other) const;
void applyOnTheLeft(const EigenBase<OtherDerived>& other);
template<typename OtherDerived>
Scalar dot(const MatrixBase<OtherDerived>& other) const;
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;
const PlainMatrixType normalized() const;
RealScalar norm() const;
RealScalar stableNorm() const;
RealScalar blueNorm() const;
RealScalar hypotNorm() const;
const PlainObject normalized() const;
void normalize();
Eigen::Transpose<Derived> transpose();
const Eigen::Transpose<Derived> transpose() const;
void transposeInPlace();
const AdjointReturnType adjoint() const;
void adjointInPlace();
typedef Diagonal<Derived> DiagonalReturnType;
DiagonalReturnType diagonal();
typedef const Diagonal<const Derived> ConstDiagonalReturnType;
const ConstDiagonalReturnType diagonal() const;
RowXpr row(int i);
const RowXpr row(int i) const;
template<int Index> struct DiagonalIndexReturnType { typedef Diagonal<Derived,Index> Type; };
template<int Index> struct ConstDiagonalIndexReturnType { typedef const Diagonal<const Derived,Index> Type; };
ColXpr col(int i);
const ColXpr col(int i) const;
template<int Index> typename DiagonalIndexReturnType<Index>::Type diagonal();
template<int Index> typename ConstDiagonalIndexReturnType<Index>::Type diagonal() const;
Minor<Derived> minor(int row, int col);
const Minor<Derived> minor(int row, int col) 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
typename BlockReturnType<Derived>::Type block(int startRow, int startCol, int blockRows, int blockCols);
const typename BlockReturnType<Derived>::Type
block(int startRow, int startCol, int blockRows, int blockCols) const;
#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
typename BlockReturnType<Derived>::SubVectorType segment(int start, int size);
const typename BlockReturnType<Derived>::SubVectorType segment(int start, int size) const;
template<unsigned int Mode> struct TriangularViewReturnType { typedef TriangularView<Derived, Mode> Type; };
template<unsigned int Mode> struct ConstTriangularViewReturnType { typedef const TriangularView<const Derived, Mode> Type; };
typename BlockReturnType<Derived,Dynamic>::SubVectorType start(int size);
const typename BlockReturnType<Derived,Dynamic>::SubVectorType start(int size) const;
template<unsigned int Mode> typename TriangularViewReturnType<Mode>::Type triangularView();
template<unsigned int Mode> typename ConstTriangularViewReturnType<Mode>::Type triangularView() const;
typename BlockReturnType<Derived,Dynamic>::SubVectorType end(int size);
const typename BlockReturnType<Derived,Dynamic>::SubVectorType end(int size) 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; };
typename BlockReturnType<Derived>::Type corner(CornerType type, int cRows, int cCols);
const typename BlockReturnType<Derived>::Type corner(CornerType type, int cRows, int cCols) const;
template<unsigned int UpLo> typename SelfAdjointViewReturnType<UpLo>::Type selfadjointView();
template<unsigned int UpLo> typename ConstSelfAdjointViewReturnType<UpLo>::Type selfadjointView() const;
template<int BlockRows, int BlockCols>
typename BlockReturnType<Derived, BlockRows, BlockCols>::Type block(int startRow, int startCol);
template<int BlockRows, int BlockCols>
const typename BlockReturnType<Derived, BlockRows, BlockCols>::Type block(int startRow, int startCol) const;
template<int CRows, int CCols>
typename BlockReturnType<Derived, CRows, CCols>::Type corner(CornerType type);
template<int CRows, int CCols>
const typename BlockReturnType<Derived, CRows, CCols>::Type corner(CornerType type) const;
template<int Size> typename BlockReturnType<Derived,Size>::SubVectorType start(void);
template<int Size> const typename BlockReturnType<Derived,Size>::SubVectorType start() const;
template<int Size> typename BlockReturnType<Derived,Size>::SubVectorType end();
template<int Size> const typename BlockReturnType<Derived,Size>::SubVectorType end() const;
template<int Size> typename BlockReturnType<Derived,Size>::SubVectorType segment(int start);
template<int Size> const typename BlockReturnType<Derived,Size>::SubVectorType segment(int start) const;
DiagonalCoeffs<Derived> diagonal();
const DiagonalCoeffs<Derived> diagonal() const;
template<unsigned int Mode> Part<Derived, Mode> part();
template<unsigned int Mode> const Part<Derived, Mode> part() const;
static const ConstantReturnType
Constant(int rows, int cols, const Scalar& value);
static const ConstantReturnType
Constant(int size, const Scalar& value);
static const ConstantReturnType
Constant(const Scalar& value);
template<typename CustomNullaryOp>
static const CwiseNullaryOp<CustomNullaryOp, Derived>
NullaryExpr(int rows, int cols, const CustomNullaryOp& func);
template<typename CustomNullaryOp>
static const CwiseNullaryOp<CustomNullaryOp, Derived>
NullaryExpr(int size, const CustomNullaryOp& func);
template<typename CustomNullaryOp>
static const CwiseNullaryOp<CustomNullaryOp, Derived>
NullaryExpr(const CustomNullaryOp& func);
static const ConstantReturnType Zero(int rows, int cols);
static const ConstantReturnType Zero(int size);
static const ConstantReturnType Zero();
static const ConstantReturnType Ones(int rows, int cols);
static const ConstantReturnType Ones(int size);
static const ConstantReturnType Ones();
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(int rows, int cols);
static const BasisReturnType Unit(int size, int i);
static const BasisReturnType Unit(int i);
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 DiagonalMatrix<Derived> asDiagonal() const;
const DiagonalWrapper<const Derived> asDiagonal() const;
const PermutationWrapper<const Derived> asPermutation() const;
void fill(const Scalar& value);
Derived& setConstant(const Scalar& value);
Derived& setZero();
Derived& setOnes();
Derived& setRandom();
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;
template<typename OtherDerived>
bool isApprox(const MatrixBase<OtherDerived>& other,
RealScalar prec = precision<Scalar>()) const;
bool isMuchSmallerThan(const RealScalar& other,
RealScalar prec = precision<Scalar>()) const;
template<typename OtherDerived>
bool isMuchSmallerThan(const MatrixBase<OtherDerived>& other,
RealScalar prec = precision<Scalar>()) const;
bool isApproxToConstant(const Scalar& value, RealScalar prec = precision<Scalar>()) const;
bool isZero(RealScalar prec = precision<Scalar>()) const;
bool isOnes(RealScalar prec = precision<Scalar>()) const;
bool isIdentity(RealScalar prec = precision<Scalar>()) const;
bool isDiagonal(RealScalar prec = precision<Scalar>()) const;
bool isUpperTriangular(RealScalar prec = precision<Scalar>()) const;
bool isLowerTriangular(RealScalar prec = precision<Scalar>()) 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 = precision<Scalar>()) const;
bool isUnitary(RealScalar prec = precision<Scalar>()) const;
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 (cwise() == other).all(); }
{ 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 (cwise() != other).any(); }
{ return cwiseNotEqual(other).any(); }
NoAlias<Derived,Eigen::MatrixBase > noalias();
template<typename NewType>
const CwiseUnaryOp<ei_scalar_cast_op<typename ei_traits<Derived>::Scalar, NewType>, Derived> cast() const;
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();
/** \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 const typename ei_eval<Derived>::type eval() const
{ return typename ei_eval<Derived>::type(derived()); }
template<typename OtherDerived>
void swap(const MatrixBase<OtherDerived>& other);
template<unsigned int Added>
const Flagged<Derived, Added, 0> marked() const;
const Flagged<Derived, 0, EvalBeforeNestingBit | EvalBeforeAssigningBit> lazy() const;
/** \returns number of elements to skip to pass from one row (resp. column) to another
* for a row-major (resp. column-major) matrix.
* Combined with coeffRef() and the \ref flags flags, it allows a direct access to the data
* of the underlying matrix.
*/
inline int stride(void) const { return derived().stride(); }
inline const NestByValue<Derived> nestByValue() const;
ConjugateReturnType conjugate() const;
const RealReturnType real() const;
const ImagReturnType imag() const;
template<typename CustomUnaryOp>
const CwiseUnaryOp<CustomUnaryOp, Derived> unaryExpr(const CustomUnaryOp& func = CustomUnaryOp()) const;
template<typename CustomBinaryOp, typename OtherDerived>
const CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived>
binaryExpr(const MatrixBase<OtherDerived> &other, const CustomBinaryOp& func = CustomBinaryOp()) const;
Scalar sum() const;
Scalar trace() const;
typename ei_traits<Derived>::Scalar minCoeff() const;
typename ei_traits<Derived>::Scalar maxCoeff() const;
typename ei_traits<Derived>::Scalar minCoeff(int* row, int* col = 0) const;
typename ei_traits<Derived>::Scalar maxCoeff(int* row, int* col = 0) const;
template<typename BinaryOp>
typename ei_result_of<BinaryOp(typename ei_traits<Derived>::Scalar)>::type
redux(const BinaryOp& func) const;
template<typename Visitor>
void visit(Visitor& func) const;
#ifndef EIGEN_PARSED_BY_DOXYGEN
inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
inline Derived& derived() { return *static_cast<Derived*>(this); }
inline Derived& const_cast_derived() const
{ return *static_cast<Derived*>(const_cast<MatrixBase*>(this)); }
#endif // not EIGEN_PARSED_BY_DOXYGEN
const Cwise<Derived> cwise() const;
Cwise<Derived> cwise();
inline const WithFormat<Derived> format(const IOFormat& fmt) const;
/////////// Array module ///////////
bool all(void) const;
bool any(void) const;
int count() const;
const PartialRedux<Derived,Horizontal> rowwise() const;
const PartialRedux<Derived,Vertical> colwise() const;
static const CwiseNullaryOp<ei_scalar_random_op<Scalar>,Derived> Random(int rows, int cols);
static const CwiseNullaryOp<ei_scalar_random_op<Scalar>,Derived> Random(int size);
static const CwiseNullaryOp<ei_scalar_random_op<Scalar>,Derived> Random();
template<typename ThenDerived,typename ElseDerived>
const Select<Derived,ThenDerived,ElseDerived>
select(const MatrixBase<ThenDerived>& thenMatrix,
const MatrixBase<ElseDerived>& elseMatrix) const;
template<typename ThenDerived>
inline const Select<Derived,ThenDerived, NestByValue<typename ThenDerived::ConstantReturnType> >
select(const MatrixBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const;
template<typename ElseDerived>
inline const Select<Derived, NestByValue<typename ElseDerived::ConstantReturnType>, ElseDerived >
select(typename ElseDerived::Scalar thenScalar, const MatrixBase<ElseDerived>& elseMatrix) const;
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<Derived> array() const { return derived(); }
/////////// LU module ///////////
const LU<PlainMatrixType> lu() const;
const PlainMatrixType inverse() const;
void computeInverse(PlainMatrixType *result) const;
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<PlainMatrixType> llt() const;
const LDLT<PlainMatrixType> ldlt() const;
const LLT<PlainObject> llt() const;
const LDLT<PlainObject> ldlt() const;
/////////// QR module ///////////
const QR<PlainMatrixType> qr() const;
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 ///////////
SVD<PlainMatrixType> svd() const;
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>
PlainMatrixType cross(const MatrixBase<OtherDerived>& other) const;
PlainMatrixType unitOrthogonal(void) const;
Matrix<Scalar,3,1> eulerAngles(int a0, int a1, int a2) const;
/////////// Sparse module ///////////
// dense = spasre * dense
template<typename Derived1, typename Derived2>
Derived& lazyAssign(const SparseProduct<Derived1,Derived2,SparseTimeDenseProduct>& product);
// dense = dense * spasre
template<typename Derived1, typename Derived2>
Derived& lazyAssign(const SparseProduct<Derived1,Derived2,DenseTimeSparseProduct>& product);
#ifdef EIGEN_MATRIXBASE_PLUGIN
#include EIGEN_MATRIXBASE_PLUGIN
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;
#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(sizeof(typename OtherDerived::Scalar)==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);}
// mixing arrays and matrices is not legal
template<typename OtherDerived> Derived& operator-=(const ArrayBase<OtherDerived>& )
{EIGEN_STATIC_ASSERT(sizeof(typename OtherDerived::Scalar)==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);}
};
#endif // EIGEN_MATRIXBASE_H

View File

@@ -1,240 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_MATRIXSTORAGE_H
#define EIGEN_MATRIXSTORAGE_H
struct ei_constructor_without_unaligned_array_assert {};
/** \internal
* Static array automatically aligned if the total byte size is a multiple of 16 and the matrix options require auto alignment
*/
template <typename T, int Size, int MatrixOptions,
bool Align = (MatrixOptions&AutoAlign) && (((Size*sizeof(T))&0xf)==0)
> struct ei_matrix_array
{
EIGEN_ALIGN_128 T array[Size];
ei_matrix_array()
{
#ifndef EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
ei_assert((reinterpret_cast<size_t>(array) & 0xf) == 0
&& "this assertion is explained here: http://eigen.tuxfamily.org/api/UnalignedArrayAssert.html **** READ THIS WEB PAGE !!! ****");
#endif
}
ei_matrix_array(ei_constructor_without_unaligned_array_assert) {}
};
template <typename T, int Size, int MatrixOptions> struct ei_matrix_array<T,Size,MatrixOptions,false>
{
T array[Size];
ei_matrix_array() {}
ei_matrix_array(ei_constructor_without_unaligned_array_assert) {}
};
/** \internal
*
* \class ei_matrix_storage
*
* \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 ei_matrix_storage;
// purely fixed-size matrix
template<typename T, int Size, int _Rows, int _Cols, int _Options> class ei_matrix_storage
{
ei_matrix_array<T,Size,_Options> m_data;
public:
inline explicit ei_matrix_storage() {}
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
: m_data(ei_constructor_without_unaligned_array_assert()) {}
inline ei_matrix_storage(int,int,int) {}
inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); }
inline static int rows(void) {return _Rows;}
inline static int cols(void) {return _Cols;}
inline void resize(int,int,int) {}
inline const T *data() const { return m_data.array; }
inline T *data() { return m_data.array; }
};
// dynamic-size matrix with fixed-size storage
template<typename T, int Size, int _Options> class ei_matrix_storage<T, Size, Dynamic, Dynamic, _Options>
{
ei_matrix_array<T,Size,_Options> m_data;
int m_rows;
int m_cols;
public:
inline explicit ei_matrix_storage() : m_rows(0), m_cols(0) {}
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
: m_data(ei_constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
inline ei_matrix_storage(int, int rows, int cols) : m_rows(rows), m_cols(cols) {}
inline ~ei_matrix_storage() {}
inline void swap(ei_matrix_storage& other)
{ std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
inline int rows(void) const {return m_rows;}
inline int cols(void) const {return m_cols;}
inline void resize(int, int rows, int 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 ei_matrix_storage<T, Size, Dynamic, _Cols, _Options>
{
ei_matrix_array<T,Size,_Options> m_data;
int m_rows;
public:
inline explicit ei_matrix_storage() : m_rows(0) {}
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
: m_data(ei_constructor_without_unaligned_array_assert()), m_rows(0) {}
inline ei_matrix_storage(int, int rows, int) : m_rows(rows) {}
inline ~ei_matrix_storage() {}
inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
inline int rows(void) const {return m_rows;}
inline int cols(void) const {return _Cols;}
inline void resize(int /*size*/, int rows, int)
{
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 ei_matrix_storage<T, Size, _Rows, Dynamic, _Options>
{
ei_matrix_array<T,Size,_Options> m_data;
int m_cols;
public:
inline explicit ei_matrix_storage() : m_cols(0) {}
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
: m_data(ei_constructor_without_unaligned_array_assert()), m_cols(0) {}
inline ei_matrix_storage(int, int, int cols) : m_cols(cols) {}
inline ~ei_matrix_storage() {}
inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
inline int rows(void) const {return _Rows;}
inline int cols(void) const {return m_cols;}
inline void resize(int, int, int 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 ei_matrix_storage<T, Dynamic, Dynamic, Dynamic, _Options>
{
T *m_data;
int m_rows;
int m_cols;
public:
inline explicit ei_matrix_storage() : m_data(0), m_rows(0), m_cols(0) {}
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
: m_data(0), m_rows(0), m_cols(0) {}
inline ei_matrix_storage(int size, int rows, int cols)
: m_data(ei_aligned_new<T>(size)), m_rows(rows), m_cols(cols) {}
inline ~ei_matrix_storage() { ei_aligned_delete(m_data, m_rows*m_cols); }
inline void swap(ei_matrix_storage& other)
{ std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
inline int rows(void) const {return m_rows;}
inline int cols(void) const {return m_cols;}
void resize(int size, int rows, int cols)
{
if(size != m_rows*m_cols)
{
ei_aligned_delete(m_data, m_rows*m_cols);
m_data = ei_aligned_new<T>(size);
}
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 ei_matrix_storage<T, Dynamic, _Rows, Dynamic, _Options>
{
T *m_data;
int m_cols;
public:
inline explicit ei_matrix_storage() : m_data(0), m_cols(0) {}
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
inline ei_matrix_storage(int size, int, int cols) : m_data(ei_aligned_new<T>(size)), m_cols(cols) {}
inline ~ei_matrix_storage() { ei_aligned_delete(m_data, _Rows*m_cols); }
inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
inline static int rows(void) {return _Rows;}
inline int cols(void) const {return m_cols;}
void resize(int size, int, int cols)
{
if(size != _Rows*m_cols)
{
ei_aligned_delete(m_data, _Rows*m_cols);
m_data = ei_aligned_new<T>(size);
}
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 ei_matrix_storage<T, Dynamic, Dynamic, _Cols, _Options>
{
T *m_data;
int m_rows;
public:
inline explicit ei_matrix_storage() : m_data(0), m_rows(0) {}
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
inline ei_matrix_storage(int size, int rows, int) : m_data(ei_aligned_new<T>(size)), m_rows(rows) {}
inline ~ei_matrix_storage() { ei_aligned_delete(m_data, _Cols*m_rows); }
inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
inline int rows(void) const {return m_rows;}
inline static int cols(void) {return _Cols;}
void resize(int size, int rows, int)
{
if(size != m_rows*_Cols)
{
ei_aligned_delete(m_data, _Cols*m_rows);
m_data = ei_aligned_new<T>(size);
}
m_rows = rows;
}
inline const T *data() const { return m_data; }
inline T *data() { return m_data; }
};
#endif // EIGEN_MATRIX_H

View File

@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
@@ -27,6 +27,7 @@
#define EIGEN_NESTBYVALUE_H
/** \class NestByValue
* \ingroup Core_Module
*
* \brief Expression which must be nested by value
*
@@ -37,67 +38,74 @@
*
* \sa MatrixBase::nestByValue()
*/
namespace internal {
template<typename ExpressionType>
struct ei_traits<NestByValue<ExpressionType> > : public ei_traits<ExpressionType>
struct traits<NestByValue<ExpressionType> > : public traits<ExpressionType>
{};
}
template<typename ExpressionType> class NestByValue
: public MatrixBase<NestByValue<ExpressionType> >
: public internal::dense_xpr_base< NestByValue<ExpressionType> >::type
{
public:
EIGEN_GENERIC_PUBLIC_INTERFACE(NestByValue)
typedef typename internal::dense_xpr_base<NestByValue>::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(NestByValue)
inline NestByValue(const ExpressionType& matrix) : m_expression(matrix) {}
inline int rows() const { return m_expression.rows(); }
inline int cols() const { return m_expression.cols(); }
inline int stride() const { return m_expression.stride(); }
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 Scalar coeff(int row, int col) const
inline const CoeffReturnType coeff(Index row, Index col) const
{
return m_expression.coeff(row, col);
}
inline Scalar& coeffRef(int row, int col)
inline Scalar& coeffRef(Index row, Index col)
{
return m_expression.const_cast_derived().coeffRef(row, col);
}
inline const Scalar coeff(int index) const
inline const CoeffReturnType coeff(Index index) const
{
return m_expression.coeff(index);
}
inline Scalar& coeffRef(int index)
inline Scalar& coeffRef(Index index)
{
return m_expression.const_cast_derived().coeffRef(index);
}
template<int LoadMode>
inline const PacketScalar packet(int row, int col) const
inline const PacketScalar packet(Index row, Index col) const
{
return m_expression.template packet<LoadMode>(row, col);
}
template<int LoadMode>
inline void writePacket(int row, int col, const PacketScalar& x)
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(int index) const
inline const PacketScalar packet(Index index) const
{
return m_expression.template packet<LoadMode>(index);
}
template<int LoadMode>
inline void writePacket(int index, const PacketScalar& x)
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;
};
@@ -106,7 +114,7 @@ template<typename ExpressionType> class NestByValue
*/
template<typename Derived>
inline const NestByValue<Derived>
MatrixBase<Derived>::nestByValue() const
DenseBase<Derived>::nestByValue() const
{
return NestByValue<Derived>(derived());
}

136
Eigen/src/Core/NoAlias.h Normal file
View File

@@ -0,0 +1,136 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_NOALIAS_H
#define EIGEN_NOALIAS_H
/** \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();
}
#endif // EIGEN_NOALIAS_H

View File

@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -26,117 +26,135 @@
#define EIGEN_NUMTRAITS_H
/** \class NumTraits
* \ingroup Core_Module
*
* \brief Holds some data about the various numeric (i.e. scalar) types allowed by Eigen.
* \brief Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
*
* \param T the numeric type about which this class provides data. Recall that Eigen allows
* only the following types for \a T: \c int, \c float, \c double,
* \c std::complex<float>, \c std::complex<double>, and \c long \c double (especially
* useful to enforce x87 arithmetics when SSE is the default).
* \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 FloatingPoint, giving the "floating-point type" of \a T. If \a T is
* \c int, then \a FloatingPoint is a typedef to \c double. Otherwise, \a FloatingPoint
* is a typedef to \a T.
* \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 \a HasFloatingPoint. It is equal to \c 0 if \a T is \c int,
* and to \c 1 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 NumTraits;
template<> struct NumTraits<int>
template<typename T> struct GenericNumTraits
{
typedef int Real;
typedef double FloatingPoint;
enum {
IsInteger = std::numeric_limits<T>::is_integer,
IsSigned = std::numeric_limits<T>::is_signed,
IsComplex = 0,
HasFloatingPoint = 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;
inline static Real epsilon() { return std::numeric_limits<T>::epsilon(); }
inline static Real dummy_precision()
{
// make sure to override this for floating-point types
return Real(0);
}
inline static T highest() { return std::numeric_limits<T>::max(); }
inline static T lowest() { return IsInteger ? std::numeric_limits<T>::min() : (-std::numeric_limits<T>::max()); }
#ifdef EIGEN2_SUPPORT
enum {
HasFloatingPoint = !IsInteger
};
typedef NonInteger FloatingPoint;
#endif
};
template<typename T> struct NumTraits : GenericNumTraits<T>
{};
template<> struct NumTraits<float>
: GenericNumTraits<float>
{
typedef float Real;
typedef float FloatingPoint;
enum {
IsComplex = 0,
HasFloatingPoint = 1,
ReadCost = 1,
AddCost = 1,
MulCost = 1
};
inline static float dummy_precision() { return 1e-5f; }
};
template<> struct NumTraits<double>
template<> struct NumTraits<double> : GenericNumTraits<double>
{
typedef double Real;
typedef double FloatingPoint;
enum {
IsComplex = 0,
HasFloatingPoint = 1,
ReadCost = 1,
AddCost = 1,
MulCost = 1
};
};
template<typename _Real> struct NumTraits<std::complex<_Real> >
{
typedef _Real Real;
typedef std::complex<_Real> FloatingPoint;
enum {
IsComplex = 1,
HasFloatingPoint = NumTraits<Real>::HasFloatingPoint,
ReadCost = 2,
AddCost = 2 * NumTraits<Real>::AddCost,
MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost
};
};
template<> struct NumTraits<long long int>
{
typedef long long int Real;
typedef long double FloatingPoint;
enum {
IsComplex = 0,
HasFloatingPoint = 0,
ReadCost = 1,
AddCost = 1,
MulCost = 1
};
inline static double dummy_precision() { return 1e-12; }
};
template<> struct NumTraits<long double>
: GenericNumTraits<long double>
{
typedef long double Real;
typedef long double FloatingPoint;
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 = 0,
HasFloatingPoint = 1,
ReadCost = 1,
AddCost = 1,
MulCost = 1
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
};
inline static Real epsilon() { return NumTraits<Real>::epsilon(); }
inline static 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
};
};
template<> struct NumTraits<bool>
{
typedef bool Real;
typedef float FloatingPoint;
enum {
IsComplex = 0,
HasFloatingPoint = 0,
ReadCost = 1,
AddCost = 1,
MulCost = 1
};
};
#endif // EIGEN_NUMTRAITS_H

View File

@@ -1,375 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_PART_H
#define EIGEN_PART_H
/** \nonstableyet
* \class Part
*
* \brief Expression of a triangular matrix extracted from a given matrix
*
* \param MatrixType the type of the object in which we are taking the triangular part
* \param Mode the kind of triangular matrix expression to construct. Can be UpperTriangular, StrictlyUpperTriangular,
* UnitUpperTriangular, LowerTriangular, StrictlyLowerTriangular, UnitLowerTriangular. This is in fact a bit field; it must have either
* UpperTriangularBit or LowerTriangularBit, and additionnaly it may have either ZeroDiagBit or
* UnitDiagBit.
*
* This class represents an expression of the upper or lower triangular part of
* a square matrix, possibly with a further assumption on the diagonal. It is the return type
* of MatrixBase::part() and most of the time this is the only way it is used.
*
* \sa MatrixBase::part()
*/
template<typename MatrixType, unsigned int Mode>
struct ei_traits<Part<MatrixType, Mode> > : ei_traits<MatrixType>
{
typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
enum {
Flags = (_MatrixTypeNested::Flags & (HereditaryBits) & (~(PacketAccessBit | DirectAccessBit | LinearAccessBit))) | Mode,
CoeffReadCost = _MatrixTypeNested::CoeffReadCost
};
};
template<typename MatrixType, unsigned int Mode> class Part
: public MatrixBase<Part<MatrixType, Mode> >
{
public:
EIGEN_GENERIC_PUBLIC_INTERFACE(Part)
inline Part(const MatrixType& matrix) : m_matrix(matrix)
{ ei_assert(ei_are_flags_consistent<Mode>::ret); }
/** \sa MatrixBase::operator+=() */
template<typename Other> Part& operator+=(const Other& other);
/** \sa MatrixBase::operator-=() */
template<typename Other> Part& operator-=(const Other& other);
/** \sa MatrixBase::operator*=() */
Part& operator*=(const typename ei_traits<MatrixType>::Scalar& other);
/** \sa MatrixBase::operator/=() */
Part& operator/=(const typename ei_traits<MatrixType>::Scalar& other);
/** \sa operator=(), MatrixBase::lazyAssign() */
template<typename Other> void lazyAssign(const Other& other);
/** \sa MatrixBase::operator=() */
template<typename Other> Part& operator=(const Other& other);
inline int rows() const { return m_matrix.rows(); }
inline int cols() const { return m_matrix.cols(); }
inline int stride() const { return m_matrix.stride(); }
inline Scalar coeff(int row, int col) const
{
// SelfAdjointBit doesn't play any role here: just because a matrix is selfadjoint doesn't say anything about
// each individual coefficient, except for the not-very-useful-here fact that diagonal coefficients are real.
if( ((Flags & LowerTriangularBit) && (col>row)) || ((Flags & UpperTriangularBit) && (row>col)) )
return (Scalar)0;
if(Flags & UnitDiagBit)
return col==row ? (Scalar)1 : m_matrix.coeff(row, col);
else if(Flags & ZeroDiagBit)
return col==row ? (Scalar)0 : m_matrix.coeff(row, col);
else
return m_matrix.coeff(row, col);
}
inline Scalar& coeffRef(int row, int col)
{
EIGEN_STATIC_ASSERT(!(Flags & UnitDiagBit), WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED)
EIGEN_STATIC_ASSERT(!(Flags & SelfAdjointBit), COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED)
ei_assert( (Mode==UpperTriangular && col>=row)
|| (Mode==LowerTriangular && col<=row)
|| (Mode==StrictlyUpperTriangular && col>row)
|| (Mode==StrictlyLowerTriangular && col<row));
return m_matrix.const_cast_derived().coeffRef(row, col);
}
/** \internal */
const MatrixType& _expression() const { return m_matrix; }
/** discard any writes to a row */
const Block<Part, 1, ColsAtCompileTime> row(int i) { return Base::row(i); }
const Block<Part, 1, ColsAtCompileTime> row(int i) const { return Base::row(i); }
/** discard any writes to a column */
const Block<Part, RowsAtCompileTime, 1> col(int i) { return Base::col(i); }
const Block<Part, RowsAtCompileTime, 1> col(int i) const { return Base::col(i); }
template<typename OtherDerived/*, int OtherMode*/>
void swap(const MatrixBase<OtherDerived>& other)
{
Part<SwapWrapper<MatrixType>,Mode>(SwapWrapper<MatrixType>(const_cast<MatrixType&>(m_matrix))).lazyAssign(other.derived());
}
protected:
const typename MatrixType::Nested m_matrix;
};
/** \nonstableyet
* \returns an expression of a triangular matrix extracted from the current matrix
*
* The parameter \a Mode can have the following values: \c UpperTriangular, \c StrictlyUpperTriangular, \c UnitUpperTriangular,
* \c LowerTriangular, \c StrictlyLowerTriangular, \c UnitLowerTriangular.
*
* \addexample PartExample \label How to extract a triangular part of an arbitrary matrix
*
* Example: \include MatrixBase_extract.cpp
* Output: \verbinclude MatrixBase_extract.out
*
* \sa class Part, part(), marked()
*/
template<typename Derived>
template<unsigned int Mode>
const Part<Derived, Mode> MatrixBase<Derived>::part() const
{
return derived();
}
template<typename MatrixType, unsigned int Mode>
template<typename Other>
inline Part<MatrixType, Mode>& Part<MatrixType, Mode>::operator=(const Other& other)
{
if(Other::Flags & EvalBeforeAssigningBit)
{
typename MatrixBase<Other>::PlainMatrixType other_evaluated(other.rows(), other.cols());
other_evaluated.template part<Mode>().lazyAssign(other);
lazyAssign(other_evaluated);
}
else
lazyAssign(other.derived());
return *this;
}
template<typename Derived1, typename Derived2, unsigned int Mode, int UnrollCount>
struct ei_part_assignment_impl
{
enum {
col = (UnrollCount-1) / Derived1::RowsAtCompileTime,
row = (UnrollCount-1) % Derived1::RowsAtCompileTime
};
inline static void run(Derived1 &dst, const Derived2 &src)
{
ei_part_assignment_impl<Derived1, Derived2, Mode, UnrollCount-1>::run(dst, src);
if(Mode == SelfAdjoint)
{
if(row == col)
dst.coeffRef(row, col) = ei_real(src.coeff(row, col));
else if(row < col)
dst.coeffRef(col, row) = ei_conj(dst.coeffRef(row, col) = src.coeff(row, col));
}
else
{
ei_assert(Mode == UpperTriangular || Mode == LowerTriangular || Mode == StrictlyUpperTriangular || Mode == StrictlyLowerTriangular);
if((Mode == UpperTriangular && row <= col)
|| (Mode == LowerTriangular && row >= col)
|| (Mode == StrictlyUpperTriangular && row < col)
|| (Mode == StrictlyLowerTriangular && row > col))
dst.copyCoeff(row, col, src);
}
}
};
template<typename Derived1, typename Derived2, unsigned int Mode>
struct ei_part_assignment_impl<Derived1, Derived2, Mode, 1>
{
inline static void run(Derived1 &dst, const Derived2 &src)
{
if(!(Mode & ZeroDiagBit))
dst.copyCoeff(0, 0, src);
}
};
// prevent buggy user code from causing an infinite recursion
template<typename Derived1, typename Derived2, unsigned int Mode>
struct ei_part_assignment_impl<Derived1, Derived2, Mode, 0>
{
inline static void run(Derived1 &, const Derived2 &) {}
};
template<typename Derived1, typename Derived2>
struct ei_part_assignment_impl<Derived1, Derived2, UpperTriangular, Dynamic>
{
inline static void run(Derived1 &dst, const Derived2 &src)
{
for(int j = 0; j < dst.cols(); ++j)
for(int i = 0; i <= j; ++i)
dst.copyCoeff(i, j, src);
}
};
template<typename Derived1, typename Derived2>
struct ei_part_assignment_impl<Derived1, Derived2, LowerTriangular, Dynamic>
{
inline static void run(Derived1 &dst, const Derived2 &src)
{
for(int j = 0; j < dst.cols(); ++j)
for(int i = j; i < dst.rows(); ++i)
dst.copyCoeff(i, j, src);
}
};
template<typename Derived1, typename Derived2>
struct ei_part_assignment_impl<Derived1, Derived2, StrictlyUpperTriangular, Dynamic>
{
inline static void run(Derived1 &dst, const Derived2 &src)
{
for(int j = 0; j < dst.cols(); ++j)
for(int i = 0; i < j; ++i)
dst.copyCoeff(i, j, src);
}
};
template<typename Derived1, typename Derived2>
struct ei_part_assignment_impl<Derived1, Derived2, StrictlyLowerTriangular, Dynamic>
{
inline static void run(Derived1 &dst, const Derived2 &src)
{
for(int j = 0; j < dst.cols(); ++j)
for(int i = j+1; i < dst.rows(); ++i)
dst.copyCoeff(i, j, src);
}
};
template<typename Derived1, typename Derived2>
struct ei_part_assignment_impl<Derived1, Derived2, SelfAdjoint, Dynamic>
{
inline static void run(Derived1 &dst, const Derived2 &src)
{
for(int j = 0; j < dst.cols(); ++j)
{
for(int i = 0; i < j; ++i)
dst.coeffRef(j, i) = ei_conj(dst.coeffRef(i, j) = src.coeff(i, j));
dst.coeffRef(j, j) = ei_real(src.coeff(j, j));
}
}
};
template<typename MatrixType, unsigned int Mode>
template<typename Other>
void Part<MatrixType, Mode>::lazyAssign(const Other& other)
{
const bool unroll = MatrixType::SizeAtCompileTime * Other::CoeffReadCost / 2 <= EIGEN_UNROLLING_LIMIT;
ei_assert(m_matrix.rows() == other.rows() && m_matrix.cols() == other.cols());
ei_part_assignment_impl
<MatrixType, Other, Mode,
unroll ? int(MatrixType::SizeAtCompileTime) : Dynamic
>::run(m_matrix.const_cast_derived(), other.derived());
}
/** \nonstableyet
* \returns a lvalue pseudo-expression allowing to perform special operations on \c *this.
*
* The \a Mode parameter can have the following values: \c UpperTriangular, \c StrictlyUpperTriangular, \c LowerTriangular,
* \c StrictlyLowerTriangular, \c SelfAdjoint.
*
* \addexample PartExample \label How to write to a triangular part of a matrix
*
* Example: \include MatrixBase_part.cpp
* Output: \verbinclude MatrixBase_part.out
*
* \sa class Part, MatrixBase::extract(), MatrixBase::marked()
*/
template<typename Derived>
template<unsigned int Mode>
inline Part<Derived, Mode> MatrixBase<Derived>::part()
{
return Part<Derived, Mode>(derived());
}
/** \returns true if *this is approximately equal to an upper triangular matrix,
* within the precision given by \a prec.
*
* \sa isLowerTriangular(), extract(), part(), marked()
*/
template<typename Derived>
bool MatrixBase<Derived>::isUpperTriangular(RealScalar prec) const
{
if(cols() != rows()) return false;
RealScalar maxAbsOnUpperTriangularPart = static_cast<RealScalar>(-1);
for(int j = 0; j < cols(); ++j)
for(int i = 0; i <= j; ++i)
{
RealScalar absValue = ei_abs(coeff(i,j));
if(absValue > maxAbsOnUpperTriangularPart) maxAbsOnUpperTriangularPart = absValue;
}
for(int j = 0; j < cols()-1; ++j)
for(int i = j+1; i < rows(); ++i)
if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnUpperTriangularPart, prec)) 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(), extract(), part(), marked()
*/
template<typename Derived>
bool MatrixBase<Derived>::isLowerTriangular(RealScalar prec) const
{
if(cols() != rows()) return false;
RealScalar maxAbsOnLowerTriangularPart = static_cast<RealScalar>(-1);
for(int j = 0; j < cols(); ++j)
for(int i = j; i < rows(); ++i)
{
RealScalar absValue = ei_abs(coeff(i,j));
if(absValue > maxAbsOnLowerTriangularPart) maxAbsOnLowerTriangularPart = absValue;
}
for(int j = 1; j < cols(); ++j)
for(int i = 0; i < j; ++i)
if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnLowerTriangularPart, prec)) return false;
return true;
}
template<typename MatrixType, unsigned int Mode>
template<typename Other>
inline Part<MatrixType, Mode>& Part<MatrixType, Mode>::operator+=(const Other& other)
{
return *this = m_matrix + other;
}
template<typename MatrixType, unsigned int Mode>
template<typename Other>
inline Part<MatrixType, Mode>& Part<MatrixType, Mode>::operator-=(const Other& other)
{
return *this = m_matrix - other;
}
template<typename MatrixType, unsigned int Mode>
inline Part<MatrixType, Mode>& Part<MatrixType, Mode>::operator*=
(const typename ei_traits<MatrixType>::Scalar& other)
{
return *this = m_matrix * other;
}
template<typename MatrixType, unsigned int Mode>
inline Part<MatrixType, Mode>& Part<MatrixType, Mode>::operator/=
(const typename ei_traits<MatrixType>::Scalar& other)
{
return *this = m_matrix / other;
}
#endif // EIGEN_PART_H

View File

@@ -0,0 +1,696 @@
// 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>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_PERMUTATIONMATRIX_H
#define EIGEN_PERMUTATIONMATRIX_H
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;
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 indices().size(); }
/** \returns the number of columns */
inline Index cols() const { return indices().size(); }
/** \returns the size of a side of the respective square matrix, i.e., the number of indices */
inline Index size() const { return 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:
const 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;
const 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();
}
#endif // EIGEN_PERMUTATIONMATRIX_H

View File

@@ -0,0 +1,740 @@
// 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>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_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 internal {
template <typename Derived, typename OtherDerived = Derived, bool IsVector = static_cast<bool>(Derived::IsVectorAtCompileTime)> struct conservative_resize_like_impl;
template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl;
} // end namespace internal
/**
* \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
*/
template<typename Derived>
class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
{
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 = (!(Options&DontAlign))
&& SizeAtCompileTime!=Dynamic && ((static_cast<int>(sizeof(Scalar))*SizeAtCompileTime)%16)==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
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
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();
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();
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.
*
* These methods do not allow to specify strides. If you need to specify strides, you have to
* use the Map class directly.
*
* \see class Map
*/
//@{
inline static ConstMapType Map(const Scalar* data)
{ return ConstMapType(data); }
inline static MapType Map(Scalar* data)
{ return MapType(data); }
inline static ConstMapType Map(const Scalar* data, Index size)
{ return ConstMapType(data, size); }
inline static MapType Map(Scalar* data, Index size)
{ return MapType(data, size); }
inline static ConstMapType Map(const Scalar* data, Index rows, Index cols)
{ return ConstMapType(data, rows, cols); }
inline static MapType Map(Scalar* data, Index rows, Index cols)
{ return MapType(data, rows, cols); }
inline static ConstAlignedMapType MapAligned(const Scalar* data)
{ return ConstAlignedMapType(data); }
inline static AlignedMapType MapAligned(Scalar* data)
{ return AlignedMapType(data); }
inline static ConstAlignedMapType MapAligned(const Scalar* data, Index size)
{ return ConstAlignedMapType(data, size); }
inline static AlignedMapType MapAligned(Scalar* data, Index size)
{ return AlignedMapType(data, size); }
inline static ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols)
{ return ConstAlignedMapType(data, rows, cols); }
inline static AlignedMapType MapAligned(Scalar* data, Index rows, Index cols)
{ return AlignedMapType(data, rows, cols); }
template<int Outer, int Inner>
inline static 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>
inline static 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>
inline static 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>
inline static 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>
inline static 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>
inline static 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>
inline static 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>
inline static 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>
inline static 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>
inline static 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>
inline static 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>
inline static 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");
#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_assert(rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
&& cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == 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
EIGEN_STRONG_INLINE static 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
{
_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
#endif // EIGEN_DENSESTORAGEBASE_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,288 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_PRODUCTBASE_H
#define EIGEN_PRODUCTBASE_H
/** \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,1); }
template<typename Dest>
inline void subTo(Dest& dst) const { scaleAndAddTo(dst,-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);
return derived().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);
return derived().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:
const LhsNested m_lhs;
const 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,m_alpha); }
template<typename Dest>
inline void addTo(Dest& dst) const { scaleAndAddTo(dst,m_alpha); }
template<typename Dest>
inline void subTo(Dest& dst) const { scaleAndAddTo(dst,-m_alpha); }
template<typename Dest>
inline void scaleAndAddTo(Dest& dst,Scalar alpha) const { m_prod.derived().scaleAndAddTo(dst,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();
}
#endif // EIGEN_PRODUCTBASE_H

163
Eigen/src/Core/Random.h Normal file
View File

@@ -0,0 +1,163 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_RANDOM_H
#define EIGEN_RANDOM_H
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();
}
#endif // EIGEN_RANDOM_H

View File

@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
@@ -26,92 +26,379 @@
#ifndef EIGEN_REDUX_H
#define EIGEN_REDUX_H
template<typename BinaryOp, typename Derived, int Start, int Length>
struct ei_redux_impl
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 ei_result_of<BinaryOp(typename Derived::Scalar)>::type Scalar;
typedef typename Derived::Scalar Scalar;
static Scalar run(const Derived &mat, const BinaryOp& func)
EIGEN_STRONG_INLINE static Scalar run(const Derived &mat, const Func& func)
{
return func(
ei_redux_impl<BinaryOp, Derived, Start, HalfLength>::run(mat, func),
ei_redux_impl<BinaryOp, Derived, Start+HalfLength, Length - HalfLength>::run(mat, 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 BinaryOp, typename Derived, int Start>
struct ei_redux_impl<BinaryOp, Derived, Start, 1>
template<typename Func, typename Derived, int Start>
struct redux_novec_unroller<Func, Derived, Start, 1>
{
enum {
col = Start / Derived::RowsAtCompileTime,
row = Start % Derived::RowsAtCompileTime
outer = Start / Derived::InnerSizeAtCompileTime,
inner = Start % Derived::InnerSizeAtCompileTime
};
typedef typename ei_result_of<BinaryOp(typename Derived::Scalar)>::type Scalar;
typedef typename Derived::Scalar Scalar;
static Scalar run(const Derived &mat, const BinaryOp &)
EIGEN_STRONG_INLINE static Scalar run(const Derived &mat, const Func&)
{
return mat.coeff(row, col);
return mat.coeffByOuterInner(outer, inner);
}
};
template<typename BinaryOp, typename Derived, int Start>
struct ei_redux_impl<BinaryOp, Derived, Start, Dynamic>
// 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 ei_result_of<BinaryOp(typename Derived::Scalar)>::type Scalar;
static Scalar run(const Derived& mat, const BinaryOp& func)
typedef typename Derived::Scalar Scalar;
EIGEN_STRONG_INLINE static 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;
EIGEN_STRONG_INLINE static PacketScalar run(const Derived &mat, const Func& func)
{
ei_assert(mat.rows()>0 && mat.cols()>0 && "you are using a non initialized matrix");
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;
EIGEN_STRONG_INLINE static 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.coeff(0,0);
for(int i = 1; i < mat.rows(); ++i)
res = func(res, mat.coeff(i, 0));
for(int j = 1; j < mat.cols(); ++j)
for(int i = 0; i < mat.rows(); ++i)
res = func(res, mat.coeff(i, j));
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 = first_aligned(mat);
enum {
alignment = bool(Derived::Flags & DirectAccessBit) || bool(Derived::Flags & AlignedBit)
? Aligned : Unaligned
};
const Index alignedSize = ((size-alignedStart)/packetSize)*packetSize;
const Index alignedEnd = alignedStart + alignedSize;
Scalar res;
if(alignedSize)
{
PacketScalar packet_res = mat.template packet<alignment>(alignedStart);
for(Index index = alignedStart + packetSize; index < alignedEnd; index += packetSize)
packet_res = func.packetOp(packet_res, mat.template packet<alignment>(index));
res = func.predux(packet_res);
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
};
EIGEN_STRONG_INLINE static 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 assiociative operator. Both current STL and TR1 functor styles are handled.
* an associative operator. Both current STL and TR1 functor styles are handled.
*
* \sa MatrixBase::sum(), MatrixBase::minCoeff(), MatrixBase::maxCoeff(), MatrixBase::colwise(), MatrixBase::rowwise()
* \sa DenseBase::sum(), DenseBase::minCoeff(), DenseBase::maxCoeff(), MatrixBase::colwise(), MatrixBase::rowwise()
*/
template<typename Derived>
template<typename BinaryOp>
typename ei_result_of<BinaryOp(typename ei_traits<Derived>::Scalar)>::type
MatrixBase<Derived>::redux(const BinaryOp& func) const
template<typename Func>
EIGEN_STRONG_INLINE typename internal::result_of<Func(typename internal::traits<Derived>::Scalar)>::type
DenseBase<Derived>::redux(const Func& func) const
{
const bool unroll = SizeAtCompileTime * CoeffReadCost
+ (SizeAtCompileTime-1) * ei_functor_traits<BinaryOp>::Cost
<= EIGEN_UNROLLING_LIMIT;
return ei_redux_impl<BinaryOp, Derived, 0, unroll ? int(SizeAtCompileTime) : Dynamic>
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>
inline typename ei_traits<Derived>::Scalar
MatrixBase<Derived>::minCoeff() const
EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
DenseBase<Derived>::minCoeff() const
{
return this->redux(Eigen::ei_scalar_min_op<Scalar>());
return this->redux(Eigen::internal::scalar_min_op<Scalar>());
}
/** \returns the maximum of all coefficients of *this
*/
template<typename Derived>
inline typename ei_traits<Derived>::Scalar
MatrixBase<Derived>::maxCoeff() const
EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
DenseBase<Derived>::maxCoeff() const
{
return this->redux(Eigen::ei_scalar_max_op<Scalar>());
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();
}
#endif // EIGEN_REDUX_H

179
Eigen/src/Core/Replicate.h Normal file
View File

@@ -0,0 +1,179 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_REPLICATE_H
#define EIGEN_REPLICATE_H
/**
* \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;
typedef typename nested<MatrixType>::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
{
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, int rowFactor, int 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);
}
protected:
const typename MatrixType::Nested 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);
}
#endif // EIGEN_REPLICATE_H

View File

@@ -0,0 +1,99 @@
// 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>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_RETURNBYVALUE_H
#define EIGEN_RETURNBYVALUE_H
/** \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();
}
#endif // EIGEN_RETURNBYVALUE_H

230
Eigen/src/Core/Reverse.h Normal file
View File

@@ -0,0 +1,230 @@
// 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>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_REVERSE_H
#define EIGEN_REVERSE_H
/** \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));
}
protected:
const 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();
}
#endif // EIGEN_REVERSE_H

View File

@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -25,9 +25,8 @@
#ifndef EIGEN_SELECT_H
#define EIGEN_SELECT_H
/** \array_module \ingroup Array
*
* \class Select
/** \class Select
* \ingroup Core_Module
*
* \brief Expression of a coefficient wise version of the C++ ternary operator ?:
*
@@ -36,15 +35,19 @@
* \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 MatrixBase::select() and most of the time this is the only way it is used.
* It is the return type of DenseBase::select() and most of the time this is the only way it is used.
*
* \sa MatrixBase::select(const MatrixBase<ThenDerived>&, const MatrixBase<ElseDerived>&) const
* \sa DenseBase::select(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&) const
*/
namespace internal {
template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType>
struct ei_traits<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
struct traits<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
: traits<ThenMatrixType>
{
typedef typename ei_traits<ThenMatrixType>::Scalar Scalar;
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;
@@ -54,41 +57,43 @@ struct ei_traits<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
MaxRowsAtCompileTime = ConditionMatrixType::MaxRowsAtCompileTime,
MaxColsAtCompileTime = ConditionMatrixType::MaxColsAtCompileTime,
Flags = (unsigned int)ThenMatrixType::Flags & ElseMatrixType::Flags & HereditaryBits,
CoeffReadCost = ei_traits<typename ei_cleantype<ConditionMatrixNested>::type>::CoeffReadCost
+ EIGEN_ENUM_MAX(ei_traits<typename ei_cleantype<ThenMatrixNested>::type>::CoeffReadCost,
ei_traits<typename ei_cleantype<ElseMatrixNested>::type>::CoeffReadCost)
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 : ei_no_assignment_operator,
public MatrixBase<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
class Select : internal::no_assignment_operator,
public internal::dense_xpr_base< Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >::type
{
public:
EIGEN_GENERIC_PUBLIC_INTERFACE(Select)
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)
{
ei_assert(m_condition.rows() == m_then.rows() && m_condition.rows() == m_else.rows());
ei_assert(m_condition.cols() == m_then.cols() && m_condition.cols() == m_else.cols());
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());
}
int rows() const { return m_condition.rows(); }
int cols() const { return m_condition.cols(); }
Index rows() const { return m_condition.rows(); }
Index cols() const { return m_condition.cols(); }
const Scalar coeff(int i, int j) const
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(int i) const
const Scalar coeff(Index i) const
{
if (m_condition.coeff(i))
return m_then.coeff(i);
@@ -103,9 +108,7 @@ class Select : ei_no_assignment_operator,
};
/** \array_module
*
* \returns a matrix where each coefficient (i,j) is equal to \a thenMatrix(i,j)
/** \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
@@ -116,43 +119,39 @@ class Select : ei_no_assignment_operator,
template<typename Derived>
template<typename ThenDerived,typename ElseDerived>
inline const Select<Derived,ThenDerived,ElseDerived>
MatrixBase<Derived>::select(const MatrixBase<ThenDerived>& thenMatrix,
const MatrixBase<ElseDerived>& elseMatrix) const
DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
const DenseBase<ElseDerived>& elseMatrix) const
{
return Select<Derived,ThenDerived,ElseDerived>(derived(), thenMatrix.derived(), elseMatrix.derived());
}
/** \array_module
*
* Version of MatrixBase::select(const MatrixBase&, const MatrixBase&) with
/** Version of DenseBase::select(const DenseBase&, const DenseBase&) with
* the \em else expression being a scalar value.
*
* \sa MatrixBase::select(const MatrixBase<ThenDerived>&, const MatrixBase<ElseDerived>&) const, class Select
* \sa DenseBase::select(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&) const, class Select
*/
template<typename Derived>
template<typename ThenDerived>
inline const Select<Derived,ThenDerived, NestByValue<typename ThenDerived::ConstantReturnType> >
MatrixBase<Derived>::select(const MatrixBase<ThenDerived>& thenMatrix,
inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
typename ThenDerived::Scalar elseScalar) const
{
return Select<Derived,ThenDerived,NestByValue<typename ThenDerived::ConstantReturnType> >(
return Select<Derived,ThenDerived,typename ThenDerived::ConstantReturnType>(
derived(), thenMatrix.derived(), ThenDerived::Constant(rows(),cols(),elseScalar));
}
/** \array_module
*
* Version of MatrixBase::select(const MatrixBase&, const MatrixBase&) with
/** Version of DenseBase::select(const DenseBase&, const DenseBase&) with
* the \em then expression being a scalar value.
*
* \sa MatrixBase::select(const MatrixBase<ThenDerived>&, const MatrixBase<ElseDerived>&) const, class Select
* \sa DenseBase::select(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&) const, class Select
*/
template<typename Derived>
template<typename ElseDerived>
inline const Select<Derived, NestByValue<typename ElseDerived::ConstantReturnType>, ElseDerived >
MatrixBase<Derived>::select(typename ElseDerived::Scalar thenScalar,
const MatrixBase<ElseDerived>& elseMatrix) const
inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
DenseBase<Derived>::select(typename ElseDerived::Scalar thenScalar,
const DenseBase<ElseDerived>& elseMatrix) const
{
return Select<Derived,NestByValue<typename ElseDerived::ConstantReturnType>,ElseDerived>(
return Select<Derived,typename ElseDerived::ConstantReturnType,ElseDerived>(
derived(), ElseDerived::Constant(rows(),cols(),thenScalar), elseMatrix.derived());
}

View File

@@ -0,0 +1,325 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_SELFADJOINTMATRIX_H
#define EIGEN_SELFADJOINTMATRIX_H
/** \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(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::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:
const 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
};
inline static 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>
{
inline static 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
};
inline static 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>
{
inline static 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;
inline static 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>
{
inline static 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();
}
#endif // EIGEN_SELFADJOINTMATRIX_H

View File

@@ -0,0 +1,195 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_SELFCWISEBINARYOP_H
#define EIGEN_SELFCWISEBINARYOP_H
/** \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);
}
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();
}
#endif // EIGEN_SELFCWISEBINARYOP_H

View File

@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -25,225 +25,177 @@
#ifndef EIGEN_SOLVETRIANGULAR_H
#define EIGEN_SOLVETRIANGULAR_H
template<typename XprType> struct ei_is_part { enum {value=false}; };
template<typename XprType, unsigned int Mode> struct ei_is_part<Part<XprType,Mode> > { enum {value=true}; };
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 TriangularPart = (int(Lhs::Flags) & LowerTriangularBit)
? LowerTriangular
: (int(Lhs::Flags) & UpperTriangularBit)
? UpperTriangular
: -1,
int StorageOrder = ei_is_part<Lhs>::value ? -1 // this is to solve ambiguous specializations
: int(Lhs::Flags) & (RowMajorBit|SparseBit)
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 ei_solve_triangular_selector;
struct triangular_solver_selector;
// transform a Part xpr to a Flagged xpr
template<typename Lhs, unsigned int LhsMode, typename Rhs, int UpLo, int StorageOrder>
struct ei_solve_triangular_selector<Part<Lhs,LhsMode>,Rhs,UpLo,StorageOrder>
template<typename Lhs, typename Rhs, int Side, int Mode>
struct triangular_solver_selector<Lhs,Rhs,Side,Mode,NoUnrolling,1>
{
static void run(const Part<Lhs,LhsMode>& lhs, Rhs& other)
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)
{
ei_solve_triangular_selector<Flagged<Lhs,LhsMode,0>,Rhs>::run(lhs._expression(), other);
}
};
ActualLhsType actualLhs = LhsProductTraits::extract(lhs);
// forward substitution, row-major
template<typename Lhs, typename Rhs, int UpLo>
struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,RowMajor|IsDense>
{
typedef typename Rhs::Scalar Scalar;
static void run(const Lhs& lhs, Rhs& other)
{
const bool IsLowerTriangular = (UpLo==LowerTriangular);
const int size = lhs.cols();
/* We perform the inverse product per block of 4 rows such that we perfectly match
* our optimized matrix * vector product. blockyStart represents the number of rows
* we have process first using the non-block version.
*/
int blockyStart = (std::max(size-5,0)/4)*4;
if (IsLowerTriangular)
blockyStart = size - blockyStart;
// FIXME find a way to allow an inner stride if packet_traits<Scalar>::size==1
bool useRhsDirectly = Rhs::InnerStrideAtCompileTime==1 || rhs.innerStride()==1;
RhsScalar* actualRhs;
if(useRhsDirectly)
{
actualRhs = &rhs.coeffRef(0);
}
else
blockyStart -= 1;
for(int c=0 ; c<other.cols() ; ++c)
{
// process first rows using the non block version
if(!(Lhs::Flags & UnitDiagBit))
{
if (IsLowerTriangular)
other.coeffRef(0,c) = other.coeff(0,c)/lhs.coeff(0, 0);
else
other.coeffRef(size-1,c) = other.coeff(size-1, c)/lhs.coeff(size-1, size-1);
}
for(int i=(IsLowerTriangular ? 1 : size-2); IsLowerTriangular ? i<blockyStart : i>blockyStart; i += (IsLowerTriangular ? 1 : -1) )
{
Scalar tmp = other.coeff(i,c)
- (IsLowerTriangular ? ((lhs.row(i).start(i)) * other.col(c).start(i)).coeff(0,0)
: ((lhs.row(i).end(size-i-1)) * other.col(c).end(size-i-1)).coeff(0,0));
if (Lhs::Flags & UnitDiagBit)
other.coeffRef(i,c) = tmp;
else
other.coeffRef(i,c) = tmp/lhs.coeff(i,i);
}
actualRhs = ei_aligned_stack_new(RhsScalar,rhs.size());
MappedRhs(actualRhs,rhs.size()) = rhs;
}
// now let's process the remaining rows 4 at once
for(int i=blockyStart; IsLowerTriangular ? i<size : i>0; )
{
int startBlock = i;
int endBlock = startBlock + (IsLowerTriangular ? 4 : -4);
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);
/* Process the i cols times 4 rows block, and keep the result in a temporary vector */
// FIXME use fixed size block but take care to small fixed size matrices...
Matrix<Scalar,Dynamic,1> btmp(4);
if (IsLowerTriangular)
btmp = lhs.block(startBlock,0,4,i) * other.col(c).start(i);
else
btmp = lhs.block(i-3,i+1,4,size-1-i) * other.col(c).end(size-1-i);
/* Let's process the 4x4 sub-matrix as usual.
* btmp stores the diagonal coefficients used to update the remaining part of the result.
*/
{
Scalar tmp = other.coeff(startBlock,c)-btmp.coeff(IsLowerTriangular?0:3);
if (Lhs::Flags & UnitDiagBit)
other.coeffRef(i,c) = tmp;
else
other.coeffRef(i,c) = tmp/lhs.coeff(i,i);
}
i += IsLowerTriangular ? 1 : -1;
for (;IsLowerTriangular ? i<endBlock : i>endBlock; i += IsLowerTriangular ? 1 : -1)
{
int remainingSize = IsLowerTriangular ? i-startBlock : startBlock-i;
Scalar tmp = other.coeff(i,c)
- btmp.coeff(IsLowerTriangular ? remainingSize : 3-remainingSize)
- ( lhs.row(i).segment(IsLowerTriangular ? startBlock : i+1, remainingSize)
* other.col(c).segment(IsLowerTriangular ? startBlock : i+1, remainingSize)).coeff(0,0);
if (Lhs::Flags & UnitDiagBit)
other.coeffRef(i,c) = tmp;
else
other.coeffRef(i,c) = tmp/lhs.coeff(i,i);
}
}
if(!useRhsDirectly)
{
rhs = MappedRhs(actualRhs, rhs.size());
ei_aligned_stack_delete(RhsScalar, actualRhs, rhs.size());
}
}
};
// Implements the following configurations:
// - inv(LowerTriangular, ColMajor) * Column vector
// - inv(LowerTriangular,UnitDiag,ColMajor) * Column vector
// - inv(UpperTriangular, ColMajor) * Column vector
// - inv(UpperTriangular,UnitDiag,ColMajor) * Column vector
template<typename Lhs, typename Rhs, int UpLo>
struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,ColMajor|IsDense>
// 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 ei_packet_traits<Scalar>::type Packet;
enum { PacketSize = ei_packet_traits<Scalar>::size };
static void run(const Lhs& lhs, Rhs& other)
typedef typename Rhs::Index Index;
typedef blas_traits<Lhs> LhsProductTraits;
typedef typename LhsProductTraits::DirectLinearAccessType ActualLhsType;
static void run(const Lhs& lhs, Rhs& rhs)
{
static const bool IsLowerTriangular = (UpLo==LowerTriangular);
const int size = lhs.cols();
for(int c=0 ; c<other.cols() ; ++c)
{
/* let's perform the inverse product per block of 4 columns such that we perfectly match
* our optimized matrix * vector product. blockyEnd represents the number of rows
* we can process using the block version.
*/
int blockyEnd = (std::max(size-5,0)/4)*4;
if (!IsLowerTriangular)
blockyEnd = size-1 - blockyEnd;
for(int i=IsLowerTriangular ? 0 : size-1; IsLowerTriangular ? i<blockyEnd : i>blockyEnd;)
{
/* Let's process the 4x4 sub-matrix as usual.
* btmp stores the diagonal coefficients used to update the remaining part of the result.
*/
int startBlock = i;
int endBlock = startBlock + (IsLowerTriangular ? 4 : -4);
Matrix<Scalar,4,1> btmp;
for (;IsLowerTriangular ? i<endBlock : i>endBlock;
i += IsLowerTriangular ? 1 : -1)
{
if(!(Lhs::Flags & UnitDiagBit))
other.coeffRef(i,c) /= lhs.coeff(i,i);
int remainingSize = IsLowerTriangular ? endBlock-i-1 : i-endBlock-1;
if (remainingSize>0)
other.col(c).segment((IsLowerTriangular ? i : endBlock) + 1, remainingSize) -=
other.coeffRef(i,c)
* Block<Lhs,Dynamic,1>(lhs, (IsLowerTriangular ? i : endBlock) + 1, i, remainingSize, 1);
btmp.coeffRef(IsLowerTriangular ? i-startBlock : remainingSize) = -other.coeffRef(i,c);
}
/* Now we can efficiently update the remaining part of the result as a matrix * vector product.
* NOTE in order to reduce both compilation time and binary size, let's directly call
* the fast product implementation. It is equivalent to the following code:
* other.col(c).end(size-endBlock) += (lhs.block(endBlock, startBlock, size-endBlock, endBlock-startBlock)
* * other.col(c).block(startBlock,endBlock-startBlock)).lazy();
*/
// FIXME this is cool but what about conjugate/adjoint expressions ? do we want to evaluate them ?
// this is a more general problem though.
ei_cache_friendly_product_colmajor_times_vector(
IsLowerTriangular ? size-endBlock : endBlock+1,
&(lhs.const_cast_derived().coeffRef(IsLowerTriangular ? endBlock : 0, IsLowerTriangular ? startBlock : endBlock+1)),
lhs.stride(),
btmp, &(other.coeffRef(IsLowerTriangular ? endBlock : 0, c)));
// if (IsLowerTriangular)
// other.col(c).end(size-endBlock) += (lhs.block(endBlock, startBlock, size-endBlock, endBlock-startBlock)
// * other.col(c).block(startBlock,endBlock-startBlock)).lazy();
// else
// other.col(c).end(size-endBlock) += (lhs.block(endBlock, startBlock, size-endBlock, endBlock-startBlock)
// * other.col(c).block(startBlock,endBlock-startBlock)).lazy();
}
/* Now we have to process the remaining part as usual */
int i;
for(i=blockyEnd; IsLowerTriangular ? i<size-1 : i>0; i += (IsLowerTriangular ? 1 : -1) )
{
if(!(Lhs::Flags & UnitDiagBit))
other.coeffRef(i,c) /= lhs.coeff(i,i);
/* NOTE we cannot use lhs.col(i).end(size-i-1) because Part::coeffRef gets called by .col() to
* get the address of the start of the row
*/
if(IsLowerTriangular)
other.col(c).end(size-i-1) -= other.coeffRef(i,c) * Block<Lhs,Dynamic,1>(lhs, i+1,i, size-i-1,1);
else
other.col(c).start(i) -= other.coeffRef(i,c) * Block<Lhs,Dynamic,1>(lhs, 0,i, i, 1);
}
if(!(Lhs::Flags & UnitDiagBit))
other.coeffRef(i,c) /= lhs.coeff(i,i);
}
const ActualLhsType actualLhs = LhsProductTraits::extract(lhs);
triangular_solve_matrix<Scalar,Index,Side,Mode,LhsProductTraits::NeedToConjugate,(int(Lhs::Flags) & RowMajorBit) ? RowMajor : ColMajor,
(Rhs::Flags&RowMajorBit) ? RowMajor : ColMajor>
::run(lhs.rows(), Side==OnTheLeft? rhs.cols() : rhs.rows(), &actualLhs.coeffRef(0,0), actualLhs.outerStride(), &rhs.coeffRef(0,0), rhs.outerStride());
}
};
/** "in-place" version of MatrixBase::solveTriangular() where the result is written in \a other
/***************************************************************************
* 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
*
* The parameter is only marked 'const' to make the C++ compiler accept a temporary expression here.
* \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 MatrixBase:solveTriangular() for the details.
* See TriangularView:solve() for the details.
*/
template<typename Derived>
template<typename OtherDerived>
void MatrixBase<Derived>::solveTriangularInPlace(const MatrixBase<OtherDerived>& _other) const
template<typename MatrixType, unsigned int Mode>
template<int Side, typename OtherDerived>
void TriangularView<MatrixType,Mode>::solveInPlace(const MatrixBase<OtherDerived>& _other) const
{
MatrixBase<OtherDerived>& other = _other.const_cast_derived();
ei_assert(derived().cols() == derived().rows());
ei_assert(derived().cols() == other.rows());
ei_assert(!(Flags & ZeroDiagBit));
ei_assert(Flags & (UpperTriangularBit|LowerTriangularBit));
OtherDerived& other = _other.const_cast_derived();
eigen_assert(cols() == rows());
eigen_assert( (Side==OnTheLeft && cols() == other.rows()) || (Side==OnTheRight && cols() == other.cols()) );
eigen_assert(!(Mode & ZeroDiag));
eigen_assert(Mode & (Upper|Lower));
enum { copy = ei_traits<OtherDerived>::Flags & RowMajorBit };
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);
typedef typename ei_meta_if<copy,
typename ei_plain_matrix_type_column_major<OtherDerived>::type, OtherDerived&>::ret OtherCopy;
OtherCopy otherCopy(other.derived());
ei_solve_triangular_selector<Derived, typename ei_unref<OtherCopy>::type>::run(derived(), otherCopy);
internal::triangular_solver_selector<MatrixType, typename internal::remove_reference<OtherCopy>::type,
Side, Mode>::run(nestedExpression(), otherCopy);
if (copy)
other = otherCopy;
@@ -251,43 +203,68 @@ void MatrixBase<Derived>::solveTriangularInPlace(const MatrixBase<OtherDerived>&
/** \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.
* 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.
*
* It is required that \c *this be marked as either an upper or a lower triangular matrix, which
* can be done by marked(), and that is automatically the case with expressions such as those returned
* by extract().
*
* \addexample SolveTriangular \label How to solve a triangular system (aka. how to multiply the inverse of a triangular matrix by another one)
*
* Example: \include MatrixBase_marked.cpp
* Output: \verbinclude MatrixBase_marked.out
*
* This function is essentially a wrapper to the faster solveTriangularInPlace() function creating
* a temporary copy of \a other, calling solveTriangularInPlace() on the copy and returning it.
* Therefore, if \a other is not needed anymore, it is quite faster to call solveTriangularInPlace()
* instead of solveTriangular().
* 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 solveTriangularInPlace()) offer
* 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.
*
* \b Tips: to perform a \em "right-inverse-multiply" you can simply transpose the operation, e.g.:
* \code
* M * T^1 <=> T.transpose().solveTriangularInPlace(M.transpose());
* \endcode
*
* \sa solveTriangularInPlace(), marked(), extract()
* \sa TriangularView::solveInPlace()
*/
template<typename Derived>
template<typename OtherDerived>
typename ei_plain_matrix_type_column_major<OtherDerived>::type
MatrixBase<Derived>::solveTriangular(const MatrixBase<OtherDerived>& other) const
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
{
typename ei_plain_matrix_type_column_major<OtherDerived>::type res(other);
solveTriangularInPlace(res);
return res;
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;
const typename Rhs::Nested m_rhs;
};
} // namespace internal
#endif // EIGEN_SOLVETRIANGULAR_H

186
Eigen/src/Core/StableNorm.h Normal file
View File

@@ -0,0 +1,186 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_STABLENORM_H
#define EIGEN_STABLENORM_H
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
{
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,std::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
{
static Index nmax = -1;
static RealScalar b1, b2, s1m, s2m, overfl, rbig, relerr;
if(nmax <= 0)
{
int nbig, ibeta, it, iemin, iemax, iexp;
RealScalar abig, eps;
// This program calculates the machine-dependent constants
// bl, b2, slm, s2m, relerr overfl, nmax
// from the "basic" machine-dependent numbers
// nbig, 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
nbig = std::numeric_limits<Index>::max(); // largest integer
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(std::pow(RealScalar(ibeta),RealScalar(iexp))); // lower boundary of midrange
iexp = (iemax + 1 - it)/2;
b2 = RealScalar(std::pow(RealScalar(ibeta),RealScalar(iexp))); // upper boundary of midrange
iexp = (2-iemin)/2;
s1m = RealScalar(std::pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for lower range
iexp = - ((iemax+it)/2);
s2m = RealScalar(std::pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for upper range
overfl = rbig*s2m; // overflow boundary for abig
eps = RealScalar(std::pow(double(ibeta), 1-it));
relerr = internal::sqrt(eps); // tolerance for neglecting asml
abig = RealScalar(1.0/eps - 1.0);
if (RealScalar(nbig)>abig) nmax = int(abig); // largest safe n
else nmax = nbig;
}
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)
{
eigen_assert(false && "overflow");
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 = std::min(abig, amed);
abig = std::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>());
}
#endif // EIGEN_STABLENORM_H

119
Eigen/src/Core/Stride.h Normal file
View File

@@ -0,0 +1,119 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_STRIDE_H
#define EIGEN_STRIDE_H
/** \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) {}
};
#endif // EIGEN_STRIDE_H

View File

@@ -1,271 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_SUM_H
#define EIGEN_SUM_H
/***************************************************************************
* Part 1 : the logic deciding a strategy for vectorization and unrolling
***************************************************************************/
template<typename Derived>
struct ei_sum_traits
{
private:
enum {
PacketSize = ei_packet_traits<typename Derived::Scalar>::size
};
public:
enum {
Vectorization = (int(Derived::Flags)&ActualPacketAccessBit)
&& (int(Derived::Flags)&LinearAccessBit)
? LinearVectorization
: NoVectorization
};
private:
enum {
Cost = Derived::SizeAtCompileTime * Derived::CoeffReadCost
+ (Derived::SizeAtCompileTime-1) * NumTraits<typename Derived::Scalar>::AddCost,
UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Vectorization) == int(NoVectorization) ? 1 : int(PacketSize))
};
public:
enum {
Unrolling = Cost <= UnrollingLimit
? CompleteUnrolling
: NoUnrolling
};
};
/***************************************************************************
* Part 2 : unrollers
***************************************************************************/
/*** no vectorization ***/
template<typename Derived, int Start, int Length>
struct ei_sum_novec_unroller
{
enum {
HalfLength = Length/2
};
typedef typename Derived::Scalar Scalar;
inline static Scalar run(const Derived &mat)
{
return ei_sum_novec_unroller<Derived, Start, HalfLength>::run(mat)
+ ei_sum_novec_unroller<Derived, Start+HalfLength, Length-HalfLength>::run(mat);
}
};
template<typename Derived, int Start>
struct ei_sum_novec_unroller<Derived, Start, 1>
{
enum {
col = Start / Derived::RowsAtCompileTime,
row = Start % Derived::RowsAtCompileTime
};
typedef typename Derived::Scalar Scalar;
inline static Scalar run(const Derived &mat)
{
return mat.coeff(row, col);
}
};
/*** vectorization ***/
template<typename Derived, int Start, int Length>
struct ei_sum_vec_unroller
{
enum {
PacketSize = ei_packet_traits<typename Derived::Scalar>::size,
HalfLength = Length/2
};
typedef typename Derived::Scalar Scalar;
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
inline static PacketScalar run(const Derived &mat)
{
return ei_padd(
ei_sum_vec_unroller<Derived, Start, HalfLength>::run(mat),
ei_sum_vec_unroller<Derived, Start+HalfLength, Length-HalfLength>::run(mat) );
}
};
template<typename Derived, int Start>
struct ei_sum_vec_unroller<Derived, Start, 1>
{
enum {
index = Start * ei_packet_traits<typename Derived::Scalar>::size,
row = int(Derived::Flags)&RowMajorBit
? index / int(Derived::ColsAtCompileTime)
: index % Derived::RowsAtCompileTime,
col = int(Derived::Flags)&RowMajorBit
? index % int(Derived::ColsAtCompileTime)
: index / Derived::RowsAtCompileTime,
alignment = (Derived::Flags & AlignedBit) ? Aligned : Unaligned
};
typedef typename Derived::Scalar Scalar;
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
inline static PacketScalar run(const Derived &mat)
{
return mat.template packet<alignment>(row, col);
}
};
/***************************************************************************
* Part 3 : implementation of all cases
***************************************************************************/
template<typename Derived,
int Vectorization = ei_sum_traits<Derived>::Vectorization,
int Unrolling = ei_sum_traits<Derived>::Unrolling
>
struct ei_sum_impl;
template<typename Derived>
struct ei_sum_impl<Derived, NoVectorization, NoUnrolling>
{
typedef typename Derived::Scalar Scalar;
static Scalar run(const Derived& mat)
{
ei_assert(mat.rows()>0 && mat.cols()>0 && "you are using a non initialized matrix");
Scalar res;
res = mat.coeff(0, 0);
for(int i = 1; i < mat.rows(); ++i)
res += mat.coeff(i, 0);
for(int j = 1; j < mat.cols(); ++j)
for(int i = 0; i < mat.rows(); ++i)
res += mat.coeff(i, j);
return res;
}
};
template<typename Derived>
struct ei_sum_impl<Derived, NoVectorization, CompleteUnrolling>
: public ei_sum_novec_unroller<Derived, 0, Derived::SizeAtCompileTime>
{};
template<typename Derived>
struct ei_sum_impl<Derived, LinearVectorization, NoUnrolling>
{
typedef typename Derived::Scalar Scalar;
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
static Scalar run(const Derived& mat)
{
const int size = mat.size();
const int packetSize = ei_packet_traits<Scalar>::size;
const int alignedStart = (Derived::Flags & AlignedBit)
|| !(Derived::Flags & DirectAccessBit)
? 0
: ei_alignmentOffset(&mat.const_cast_derived().coeffRef(0), size);
enum {
alignment = (Derived::Flags & DirectAccessBit) || (Derived::Flags & AlignedBit)
? Aligned : Unaligned
};
const int alignedSize = ((size-alignedStart)/packetSize)*packetSize;
const int alignedEnd = alignedStart + alignedSize;
Scalar res;
if(alignedSize)
{
PacketScalar packet_res = mat.template packet<alignment>(alignedStart);
for(int index = alignedStart + packetSize; index < alignedEnd; index += packetSize)
packet_res = ei_padd(packet_res, mat.template packet<alignment>(index));
res = ei_predux(packet_res);
}
else // too small to vectorize anything.
// since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize.
{
res = Scalar(0);
}
for(int index = 0; index < alignedStart; ++index)
res += mat.coeff(index);
for(int index = alignedEnd; index < size; ++index)
res += mat.coeff(index);
return res;
}
};
template<typename Derived>
struct ei_sum_impl<Derived, LinearVectorization, CompleteUnrolling>
{
typedef typename Derived::Scalar Scalar;
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
enum {
PacketSize = ei_packet_traits<Scalar>::size,
Size = Derived::SizeAtCompileTime,
VectorizationSize = (Size / PacketSize) * PacketSize
};
static Scalar run(const Derived& mat)
{
Scalar res = ei_predux(ei_sum_vec_unroller<Derived, 0, Size / PacketSize>::run(mat));
if (VectorizationSize != Size)
res += ei_sum_novec_unroller<Derived, VectorizationSize, Size-VectorizationSize>::run(mat);
return res;
}
};
/***************************************************************************
* Part 4 : implementation of MatrixBase methods
***************************************************************************/
/** \returns the sum of all coefficients of *this
*
* \sa trace()
*/
template<typename Derived>
inline typename ei_traits<Derived>::Scalar
MatrixBase<Derived>::sum() const
{
return ei_sum_impl<Derived>::run(derived());
}
/** \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>
inline typename ei_traits<Derived>::Scalar
MatrixBase<Derived>::trace() const
{
return diagonal().sum();
}
#endif // EIGEN_SUM_H

View File

@@ -1,5 +1,5 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
@@ -26,54 +26,58 @@
#define EIGEN_SWAP_H
/** \class SwapWrapper
* \ingroup Core_Module
*
* \internal
*
* \brief Internal helper class for swapping two expressions
*/
namespace internal {
template<typename ExpressionType>
struct ei_traits<SwapWrapper<ExpressionType> >
{
typedef typename ExpressionType::Scalar Scalar;
enum {
RowsAtCompileTime = ExpressionType::RowsAtCompileTime,
ColsAtCompileTime = ExpressionType::ColsAtCompileTime,
MaxRowsAtCompileTime = ExpressionType::MaxRowsAtCompileTime,
MaxColsAtCompileTime = ExpressionType::MaxColsAtCompileTime,
Flags = ExpressionType::Flags,
CoeffReadCost = ExpressionType::CoeffReadCost
};
};
struct traits<SwapWrapper<ExpressionType> > : traits<ExpressionType> {};
}
template<typename ExpressionType> class SwapWrapper
: public MatrixBase<SwapWrapper<ExpressionType> >
: public internal::dense_xpr_base<SwapWrapper<ExpressionType> >::type
{
public:
EIGEN_GENERIC_PUBLIC_INTERFACE(SwapWrapper)
typedef typename ei_packet_traits<Scalar>::type Packet;
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 int rows() const { return m_expression.rows(); }
inline int cols() const { return m_expression.cols(); }
inline int stride() const { return m_expression.stride(); }
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 Scalar& coeffRef(int row, int col)
inline Scalar& coeffRef(Index row, Index col)
{
return m_expression.const_cast_derived().coeffRef(row, col);
}
inline Scalar& coeffRef(int index)
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(int row, int col, const MatrixBase<OtherDerived>& other)
void copyCoeff(Index row, Index col, const DenseBase<OtherDerived>& other)
{
OtherDerived& _other = other.const_cast_derived();
ei_internal_assert(row >= 0 && row < rows()
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);
@@ -81,20 +85,20 @@ template<typename ExpressionType> class SwapWrapper
}
template<typename OtherDerived>
void copyCoeff(int index, const MatrixBase<OtherDerived>& other)
void copyCoeff(Index index, const DenseBase<OtherDerived>& other)
{
OtherDerived& _other = other.const_cast_derived();
ei_internal_assert(index >= 0 && index < m_expression.size());
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(int row, int col, const MatrixBase<OtherDerived>& other)
void copyPacket(Index row, Index col, const DenseBase<OtherDerived>& other)
{
OtherDerived& _other = other.const_cast_derived();
ei_internal_assert(row >= 0 && row < rows()
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,
@@ -104,10 +108,10 @@ template<typename ExpressionType> class SwapWrapper
}
template<typename OtherDerived, int StoreMode, int LoadMode>
void copyPacket(int index, const MatrixBase<OtherDerived>& other)
void copyPacket(Index index, const DenseBase<OtherDerived>& other)
{
OtherDerived& _other = other.const_cast_derived();
ei_internal_assert(index >= 0 && index < m_expression.size());
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)
@@ -119,24 +123,4 @@ template<typename ExpressionType> class SwapWrapper
ExpressionType& m_expression;
};
/** swaps *this with the expression \a other.
*
* \note \a other is only marked for internal reasons, but of course
* it gets const-casted. One reason is that one will often call swap
* on temporary objects (hence non-const references are forbidden).
* Another reason is that lazyAssign takes a const argument anyway.
*/
template<typename Derived>
template<typename OtherDerived>
void MatrixBase<Derived>::swap(const MatrixBase<OtherDerived>& other)
{
(SwapWrapper<Derived>(derived())).lazyAssign(other);
}
#endif // EIGEN_SWAP_H

View File

@@ -1,7 +1,8 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -26,6 +27,7 @@
#define EIGEN_TRANSPOSE_H
/** \class Transpose
* \ingroup Core_Module
*
* \brief Expression of the transpose of a matrix
*
@@ -37,108 +39,190 @@
*
* \sa MatrixBase::transpose(), MatrixBase::adjoint()
*/
namespace internal {
template<typename MatrixType>
struct ei_traits<Transpose<MatrixType> >
struct traits<Transpose<MatrixType> > : traits<MatrixType>
{
typedef typename MatrixType::Scalar Scalar;
typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
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,
Flags = ((int(_MatrixTypeNested::Flags) ^ RowMajorBit)
& ~(LowerTriangularBit | UpperTriangularBit))
| (int(_MatrixTypeNested::Flags)&UpperTriangularBit ? LowerTriangularBit : 0)
| (int(_MatrixTypeNested::Flags)&LowerTriangularBit ? UpperTriangularBit : 0),
CoeffReadCost = _MatrixTypeNested::CoeffReadCost
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 MatrixBase<Transpose<MatrixType> >
: 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(const MatrixType& matrix) : m_matrix(matrix) {}
inline Transpose(MatrixType& matrix) : m_matrix(matrix) {}
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Transpose)
inline int rows() const { return m_matrix.cols(); }
inline int cols() const { return m_matrix.rows(); }
inline int nonZeros() const { return m_matrix.nonZeros(); }
inline int stride(void) const { return m_matrix.stride(); }
inline Index rows() const { return m_matrix.cols(); }
inline Index cols() const { return m_matrix.rows(); }
inline Scalar& coeffRef(int row, int col)
{
return m_matrix.const_cast_derived().coeffRef(col, row);
}
/** \returns the nested expression */
const typename internal::remove_all<typename MatrixType::Nested>::type&
nestedExpression() const { return m_matrix; }
inline const Scalar coeff(int row, int col) const
{
return m_matrix.coeff(col, row);
}
inline const Scalar coeff(int index) const
{
return m_matrix.coeff(index);
}
inline Scalar& coeffRef(int index)
{
return m_matrix.const_cast_derived().coeffRef(index);
}
template<int LoadMode>
inline const PacketScalar packet(int row, int col) const
{
return m_matrix.template packet<LoadMode>(col, row);
}
template<int LoadMode>
inline void writePacket(int row, int col, const PacketScalar& x)
{
m_matrix.const_cast_derived().template writePacket<LoadMode>(col, row, x);
}
template<int LoadMode>
inline const PacketScalar packet(int index) const
{
return m_matrix.template packet<LoadMode>(index);
}
template<int LoadMode>
inline void writePacket(int index, const PacketScalar& x)
{
m_matrix.const_cast_derived().template writePacket<LoadMode>(index, x);
}
/** \returns the nested expression */
typename internal::remove_all<typename MatrixType::Nested>::type&
nestedExpression() { return m_matrix.const_cast_derived(); }
protected:
const 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 const CoeffReturnType coeff(Index row, Index col) const
{
return derived().nestedExpression().coeff(col, row);
}
inline const 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
*
* \sa adjoint(), class DiagonalCoeffs */
* \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>
MatrixBase<Derived>::transpose()
DenseBase<Derived>::transpose()
{
return derived();
}
/** This is the const version of transpose(). \sa adjoint() */
/** This is the const version of transpose().
*
* Make sure you read the warning for transpose() !
*
* \sa transposeInPlace(), adjoint() */
template<typename Derived>
inline const Transpose<Derived>
MatrixBase<Derived>::transpose() const
inline const typename DenseBase<Derived>::ConstTransposeReturnType
DenseBase<Derived>::transpose() const
{
return derived();
return ConstTransposeReturnType(derived());
}
/** \returns an expression of the adjoint (i.e. conjugate transpose) of *this.
@@ -146,57 +230,197 @@ MatrixBase<Derived>::transpose() const
* Example: \include MatrixBase_adjoint.cpp
* Output: \verbinclude MatrixBase_adjoint.out
*
* \sa transpose(), conjugate(), class Transpose, class ei_scalar_conjugate_op */
* \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 conjugate().nestByValue();
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 ei_inplace_transpose_selector;
struct inplace_transpose_selector;
template<typename MatrixType>
struct ei_inplace_transpose_selector<MatrixType,true> { // square matrix
struct inplace_transpose_selector<MatrixType,true> { // square matrix
static void run(MatrixType& m) {
m.template part<StrictlyUpperTriangular>().swap(m.transpose());
m.template triangularView<StrictlyUpper>().swap(m.transpose());
}
};
template<typename MatrixType>
struct ei_inplace_transpose_selector<MatrixType,false> { // non square matrix
struct inplace_transpose_selector<MatrixType,false> { // non square matrix
static void run(MatrixType& m) {
if (m.rows()==m.cols())
m.template part<StrictlyUpperTriangular>().swap(m.transpose());
m.template triangularView<StrictlyUpper>().swap(m.transpose());
else
m = m.transpose().eval();
}
};
/** This is the "in place" version of transpose: it transposes \c *this.
} // 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.
*
* In most cases it is probably better to simply use the transposed expression
* of a matrix. However, when transposing 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 .transpose() requires special care:
* \code m = m.transpose().eval(); \endcode
* - no temporary object is created (currently only for squared matrices)
* - it allows future optimizations (cache friendliness, etc.)
* 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() */
* \sa transpose(), adjoint(), adjointInPlace() */
template<typename Derived>
inline void MatrixBase<Derived>::transposeInPlace()
inline void DenseBase<Derived>::transposeInPlace()
{
ei_inplace_transpose_selector<Derived>::run(derived());
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 = 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 = blas_traits<DerivedA>::IsTransposed != DestIsTransposed
|| 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 (blas_traits<OtherDerived>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(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==(Scalar*)extract_data(src.lhs())))
|| ((blas_traits<DerivedB>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(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
#endif // EIGEN_TRANSPOSE_H

View File

@@ -0,0 +1,447 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2010-2011 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_TRANSPOSITIONS_H
#define EIGEN_TRANSPOSITIONS_H
/** \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;
const 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;
};
#endif // EIGEN_TRANSPOSITIONS_H

View File

@@ -0,0 +1,834 @@
// 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>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_TRIANGULARMATRIX_H
#define EIGEN_TRIANGULARMATRIX_H
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_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, UpperSelfadjoint, or LowerSelfadjoint. This is in fact a bit field;
* it must have either Upper or Lower, and additionnaly it may have either
* UnitDiag or Selfadjoint.
*
* This class represents a triangular part of a matrix, not necessarily square. Strictly speaking, for rectangular
* matrices one should speak ok "trapezoid" parts. This class is the return type
* 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() */
inline TriangularView<typename MatrixType::AdjointReturnType,TransposeMode> adjoint()
{ return m_matrix.adjoint(); }
/** \sa MatrixBase::adjoint() const */
inline const TriangularView<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)
{
TriangularView<SwapWrapper<MatrixType>,Mode>(const_cast<MatrixType&>(m_matrix)).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);
const 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
};
inline static 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) = 1;
else
dst.coeffRef(row, col) = 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>
{
inline static 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;
inline static 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) = 0;
}
}
};
template<typename Derived1, typename Derived2, bool ClearOpposite>
struct triangular_assignment_selector<Derived1, Derived2, Lower, Dynamic, ClearOpposite>
{
typedef typename Derived1::Index Index;
inline static 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) = 0;
}
}
};
template<typename Derived1, typename Derived2, bool ClearOpposite>
struct triangular_assignment_selector<Derived1, Derived2, StrictlyUpper, Dynamic, ClearOpposite>
{
typedef typename Derived1::Index Index;
inline static 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) = 0;
}
}
};
template<typename Derived1, typename Derived2, bool ClearOpposite>
struct triangular_assignment_selector<Derived1, Derived2, StrictlyLower, Dynamic, ClearOpposite>
{
typedef typename Derived1::Index Index;
inline static 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) = 0;
}
}
};
template<typename Derived1, typename Derived2, bool ClearOpposite>
struct triangular_assignment_selector<Derived1, Derived2, UnitUpper, Dynamic, ClearOpposite>
{
typedef typename Derived1::Index Index;
inline static 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;
inline static 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;
}
#endif // EIGEN_TRIANGULARMATRIX_H

View File

@@ -0,0 +1,296 @@
// 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>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_VECTORBLOCK_H
#define EIGEN_VECTORBLOCK_H
/** \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);
}
#endif // EIGEN_VECTORBLOCK_H

Some files were not shown because too many files have changed in this diff Show More