Compare commits

..

161 Commits
2.0.5 ... 2.0

Author SHA1 Message Date
Antonio Sanchez
2bcca69afa Add CI for building docs 2025-10-17 21:58:59 -07:00
Thomas Capricelli
2827b35b29 simplify/uniformize eigen_gen_docs 2013-10-18 12:56:28 +02:00
Thomas Capricelli
3664ba0811 add piwik code to documentation (web stats engine) 2012-08-21 22:38:14 +02:00
Thomas Capricelli
ebef1f829d uniformize eigen_gen_docs between branches / cleaning 2012-04-03 14:23:16 +02:00
Gael Guennebaud
d2deedd5a8 bug #411: fix link to UnalignedArrayAssert.html 2012-01-25 16:33:35 +01:00
Thomas Capricelli
8c78edc04c eigen_gen_docs: dont try to update permissions on server 2011-12-06 15:52:55 +01:00
Benoit Jacob
b029007996 Added tag 2.0.17 for changeset 8ebe822a20 2011-12-06 08:18:58 -05:00
Benoit Jacob
8ebe822a20 bump 2011-12-06 08:18:54 -05:00
Thomas Capricelli
bd7475cc0c fix typo in doc for ParametrizedLine 2011-06-23 00:39:40 +02:00
Gael Guennebaud
e5203d46fe fix aligned_allocator::allocate interface 2011-06-14 08:52:38 +02:00
Gael Guennebaud
7065c3a398 Added tag 2.0.16 for changeset f90db64e6a 2011-05-28 10:16:30 +02:00
Gael Guennebaud
f90db64e6a bump to 2.0.16 2011-05-28 10:16:08 +02:00
Gael Guennebaud
d6293e6385 fix perf regression introduced by changeset 7852a48a2f
(matrix-vector product did not use the nesting rules....)
2011-05-27 22:05:39 +02:00
Gael Guennebaud
aaaa9301a8 fix bug #250 (gcc 4.6 compilation) 2011-04-19 16:35:48 +02:00
Gael Guennebaud
780f312228 fix LS documentation 2011-02-24 19:03:49 +01:00
Piotr Trojanek
ced86f3bfc class/struct mismatch for different template invocations 2011-01-16 00:32:13 +01:00
Benoit Jacob
1869a02f52 add part<SelfAdjoint>... it's never too late and I need this for eigen2support 2011-01-25 19:49:38 -05:00
DJ Marcin
0c8a25ef94 fix operator& precedence bug 2010-08-23 22:32:49 -04:00
Gael Guennebaud
70f355b51a backport fix on 3x3 triadiagonalization, this fix #149 2010-07-22 21:26:09 +02:00
Benoit Jacob
2d0963fb00 Added tag 2.0.15 for changeset 907fba9ea9 2010-07-16 22:25:12 -04:00
Benoit Jacob
907fba9ea9 bump 2010-07-16 22:25:08 -04:00
Gael Guennebaud
7e0b7b1f25 uncomment tests (sorry) 2010-07-16 11:50:40 +02:00
Gael Guennebaud
5ac00624ed adapted pactch from Nick Lewycky fixing a couple of issue with CLang 2010-07-15 22:48:44 +02:00
Gael Guennebaud
c0a0d2d181 add unit tests for 0 matrix 2010-07-15 20:00:50 +02:00
Gael Guennebaud
ec39a39cb6 fix LLT for zero matrix 2010-07-15 20:00:34 +02:00
Gael Guennebaud
ccc6731f86 fix use of rank in QR 2010-07-15 19:59:21 +02:00
Gael Guennebaud
b09bb50aeb fix QR solving with m>n 2010-07-15 19:52:11 +02:00
Gael Guennebaud
c7b8de77c0 fix aligned_delete for null pointers 2010-07-15 09:28:29 +02:00
Gael Guennebaud
c44bbabdcc fix LU and QR solve when rank==0, fix LLT when the matrix is purely 0 2010-07-12 16:42:38 +02:00
Gael Guennebaud
468863f3a0 fix bad Map in row-vector by matrix products 2010-07-09 20:27:05 +02:00
Gael Guennebaud
81f36b0e21 disable MSVC optimization when the underlying compiler is ICC 2010-07-09 19:36:43 +02:00
Benoit Jacob
c196a49f67 Added tag 2.0.14 for changeset e18e51d891 2010-06-22 22:23:39 -04:00
Benoit Jacob
e18e51d891 bump 2010-06-22 22:22:11 -04:00
Stuart Glaser
58fc972ed3 LU on limited-size matrices no longer allocates for temporaries. 2010-06-21 21:29:45 -07:00
Benoit Jacob
e7b6a4bcba fix bug introduced yesterday preventing vectorization of vectors when the storage order is not "the right one".
expand a little the vectorization_logic test and backport EIGEN_DEBUG_ASSIGN.
2010-06-22 09:24:07 -04:00
Benoit Jacob
eaa81c135a fix brain dead computation of the aligned bit.
When using a max-size that is fixed and not a multiple of 16 bit, we're not aligned.
2010-06-21 21:07:53 -04:00
Benoit Jacob
ad8b6c2342 fix #127: remove static keywords that had no effect anyway since the forward-declaration wasn't static,
and that would have been bad if they had taken effect.
2010-06-16 08:28:34 -04:00
Benoit Jacob
37fe67372b Added tag 2.0.13 for changeset ee499a855c 2010-06-10 08:06:38 -04:00
Benoit Jacob
ee499a855c bump version 2010-06-10 08:06:06 -04:00
Benoit Jacob
bc0ce37395 mention that that issue has been solved in GCC 4.5 2010-06-10 08:02:20 -04:00
Benoit Jacob
65c0b2a04d install the Eigen and Dense public headers !!!!! 2010-06-10 08:02:02 -04:00
Benoit Jacob
93d8d0e1b5 add unit test for bug #132 2010-06-09 20:50:18 -04:00
Benoit Jacob
501063d9e9 Fix bug #132
In the matrix-vector products, we were calling coeffRef on the vector xpr without checking it has DirectAccess.

Will add unit test (since it's in 2.0, just import the test case provided in the bug report).

Confirming that this can't happen in the devel branch, and that if we tried to call coeffRef on an xpr
without DirectAccess, that would not compile (since the DenseCoeffsBase class was introduced).
2010-06-09 19:39:05 -04:00
Gael Guennebaud
c76c8d6917 fix issue #125 2010-05-31 22:53:02 +02:00
Thomas Capricelli
0bb8688d70 sync .hgignore with tip 2010-05-26 02:37:52 +02:00
Thomas Capricelli
ea87337647 fix readcost for complex types (backport from tip) 2010-05-26 02:34:55 +02:00
Piotr Trojanek
12557fb2a2 more std:: namespace fixups for 2.0 branch 2010-05-01 09:25:36 +09:00
Benoit Jacob
8a95876825 with QCC, don't try passing --version 2010-04-29 07:58:47 -04:00
Benoit Jacob
82d7c4e1d0 forgot hg add 2010-04-26 07:54:19 -04:00
Benoit Jacob
8d4b0aae04 Fix bug #93: add platform check for how to link to the standard math library.
This allows to support QNX.
2010-04-19 11:30:46 -04:00
Gael Guennebaud
4785e27d6a fix btl compilation 2010-04-01 12:34:55 +02:00
Benoit Jacob
20b544b444 disable all alignment with QCC/QNX in eigen 2.0 2010-03-06 00:31:55 -05:00
Piotr Trojanek
135013c608 EIGEN_ALIGN std:: fixup 2010-03-04 16:38:37 +01:00
Piotr Trojanek
1625a5e3f8 fixups for clean QCC compilation (add std:: in front of size_t, memcpy, etc.) 2010-03-05 11:21:11 +01:00
Piotr Trojanek
47a61bbd80 posix_memalign check for QNX 2010-03-04 17:12:30 +01:00
Benoit Jacob
12bcfae0c5 clarify EIGEN_DONT_ALIGN docs wrt versions 2010-02-28 15:56:50 -05:00
Benoit Jacob
5f42104e0a really fix the LDLt, at the expense of letting isPositiveDefinite() always return true (it was fundamentally broken anyway, especially as in 2.0 we don't even pivot at all).
also, fix compilation
2010-02-23 18:10:31 -05:00
Benoit Jacob
6b3f81b414 precision improvement. Wtf were we using sqrt(precision) for the cutoff? Replaced by precision*biggest. 2010-02-23 16:26:39 -05:00
Gael Guennebaud
1f4b8e6a36 compilation fix in ldlt() for non matrix types
(transplanted from 608959aa6f
)
2010-02-21 10:29:19 +01:00
Benoit Jacob
e1f61b40c8 oops, this had to be done here, not at the end. 2010-02-12 09:02:25 -05:00
Benoit Jacob
f369dc873e 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:57:04 -05:00
Benoit Jacob
c03bca21c4 Added tag 2.0.12 for changeset ed6eb5a625 2010-02-11 21:39:46 -05:00
Benoit Jacob
ed6eb5a625 bump 2010-02-11 21:39:41 -05:00
Benoit Jacob
9488a12125 work around brain dead ICC 2010-02-11 19:32:56 -05:00
Piotr Trojanek
7b44957c4b std:: namespace fixup for more restricive compilers such as QNX's QCC 2010-02-10 22:27:35 +01:00
Hauke Heibel
743ad75595 BenchTimer backport (clock_gettime & QueryPerformanceCounter). 2010-02-03 21:55:01 +01:00
Benoit Jacob
a9eabed421 Patch by 'Wolf' from the issue tracker:
Fix bug #90, missing type cast in LU, allow to use LU with MPFR.
2010-02-02 07:06:15 -05:00
Benoit Jacob
cd34a1d351 backport bug fix by Jitse. 2010-01-28 14:00:09 -05:00
Benoit Jacob
3e963ee69d EIGEN_ENUM_MIN ---> EIGEN_SIZE_MIN 2010-01-26 20:37:57 -05:00
Benoit Jacob
6cc9dc17f2 In LU / Inverse, decouple the output type from the input type.
This has long been done in the default branch
2010-01-26 18:45:23 -05:00
Gael Guennebaud
7852a48a2f fix matrix product with EIGEN_DEFAULT_TO_ROW_MAJOR 2010-01-25 21:56:01 +01:00
Benoit Jacob
d209120180 * Introduce EIGEN_DEFAULT_TO_ROW_MAJOR tests option
---> Now only product_large fails with EIGEN_DEFAULT_TO_ROW_MAJOR.
* Fix EIGEN_NO_ASSERTION_CHECKING tests option
* Fix a crash in Tridiagonalization on row-major matrices + SSE
* Fix inverse test (numeric stability noise)
* Extend map test (see previous fixes in MapBase)
* Fix vectorization_logic test for row-major
* Disable sparse tests with EIGEN_DEFAULT_TO_ROW_MAJOR
2010-01-25 14:00:02 -05:00
Thomas Capricelli
55c0707b1d fix the script again (definitely?) + cleaning 2010-01-22 19:28:33 +01:00
Benoit Jacob
72044ca925 fix a super nasty bug: on row-major expressions that are NOT vectors but that
do have LinearAccess, the MapBase::coeff(int) and MapBase::coeffRef(int)
methods were broken.
2010-01-21 23:33:20 -05:00
Benoit Jacob
c2b8ca7493 if EIGEN_DONT_ALIGN then don't try to vectorize (was giving a #error later on). 2010-01-21 22:32:16 -05:00
Gael Guennebaud
018cb8975a fix plugin doc 2010-01-17 19:55:08 +01:00
Benoit Jacob
3ab280ce4e add missing semicolon in the example 2010-01-17 12:40:19 -05:00
Benoit Jacob
b40030753b Added tag 2.0.11 for changeset 5f73a8df20 2010-01-10 11:30:40 -05:00
Benoit Jacob
5f73a8df20 bump 2010-01-10 11:30:10 -05:00
Thomas Capricelli
8a6d5f10dc backport from tip : actually stop on compile failure 2010-01-06 17:17:40 +01:00
Benoit Jacob
ba6ed5fa5f Fix CoeffReadCost in Part: it must account for the cost of the
conditional jump. This makes Part considered an "expensive" xpr
 that must be evaluated in operations such as Product.
This fixes bug #80.
2010-01-02 13:04:04 -05:00
Benoit Jacob
e4c88c14ec clarify docs as requested on the forum 2010-01-02 12:54:55 -05:00
Benoit Jacob
74207a31fa backport the fix to bug #79, and the unit test 2010-01-02 12:45:49 -05:00
Benoit Jacob
6fd9248c09 add Intel copyright info 2009-12-15 08:43:31 -05:00
Benoit Jacob
4262117f84 backport 4x4 inverse changes:
- use cofactors
 - use Intel's SSE code in the float case
2009-12-15 08:16:48 -05:00
Gael Guennebaud
b581cb870c fix #74: sparse triangular solver for lower/row-major matrices 2009-12-14 10:20:35 +01:00
Gael Guennebaud
72fc81dd9d backport quaternion slerp precision fix 2009-12-05 18:28:17 +01:00
Gael Guennebaud
f36650b00a fix MSVC10 compilation issues 2009-12-02 19:34:37 +01:00
Benoit Jacob
8d31f58ea1 fix bug #70
Was trying to apply stupid invertibility check to top-left 2x2 corner.
2009-11-26 15:33:07 -05:00
Benoit Jacob
a161a70696 Added tag 2.0.10 for changeset 8f1ce52e76 2009-11-25 08:54:17 -05:00
Benoit Jacob
8f1ce52e76 bump 2009-11-25 08:46:42 -05:00
Benoit Jacob
268df314f1 make the inverse_4x4 test pass more consistently 2009-11-25 08:43:20 -05:00
Benoit Jacob
522022ebfc wow, restore Gael's changeset 5455d6fbe8
that I had accidentally undone in my changeset c64ca6870e
.
2009-11-25 08:31:25 -05:00
Thomas Capricelli
d048d7e712 fix bitbucket url after recent change 2009-11-24 23:08:16 +01:00
Benoit Jacob
cd3c8a9404 typo 2009-11-23 11:23:30 -05:00
Benoit Jacob
ec8f37ac75 improve precision test 2009-11-23 11:20:48 -05:00
Benoit Jacob
fc7f39980c backport improvement in 4x4 inverse precisio, and rigorous precision test 2009-11-23 10:27:10 -05:00
Gael Guennebaud
70af59c455 an attempt to fix compilation with recent MSVC 2009-11-23 10:29:40 +01:00
Benoit Jacob
f4dd399499 fix warnings 2009-11-16 14:15:47 -05:00
Benoit Jacob
153557527e backport: init-by-zero option: resize with same size must be a NOP 2009-11-16 13:47:02 -05:00
Benoit Jacob
6aad7f80ff avoid infinite loop, optimization not important, so a plain for loop is the safe way 2009-11-12 14:09:53 -05:00
Benoit Jacob
e3f6c3115a backport the initialize-by-0 option 2009-11-12 12:53:24 -05:00
Benoit Jacob
a2c838ff8f fix PowerPC platform detection 2009-11-11 10:52:00 -05:00
Thomas Capricelli
1e2f56c35a backport of b53c2fcc99
: fix install dir for *.pc

Ingmar Vanhassel <ingmar@exherbo.org>:
Packages that don't install architecture-specific files should install
their pkg-config file to datadir, not libdir.
2009-11-11 15:35:12 +01:00
Hauke Heibel
808c4e9581 Fixed the packport of 62 - Packet4f/d/i does not exist in 2.0. 2009-11-05 10:49:49 +01:00
Hauke Heibel
65331c3884 backporting3979f6d8aad001174160774b49b747430a7686b5
: fixed bug #62
2009-11-04 17:49:34 +01:00
Benoit Jacob
e158cdd61d fix Matrix::Map/MapAligned documentation, and rephrase the tutorial on Map 2009-10-31 14:45:50 -04:00
Benoit Jacob
c64ca6870e this explicit keyword can't hurt 2009-10-31 11:49:20 -04:00
Benoit Jacob
6a90f6c5f0 * 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:48:33 -04:00
Gael Guennebaud
22dd13fdb9 backporting fix of #65 2009-10-29 14:26:38 +01:00
Gael Guennebaud
5455d6fbe8 backporting fix of #65 2009-10-29 14:26:00 +01:00
Benoit Jacob
de693cf34a remove extra ; 2009-10-28 10:04:13 -04:00
Benoit Jacob
21c4e0802d fix potential warning 2009-10-28 09:45:09 -04:00
Benoit Jacob
241b9d34a7 Hey, I was insomniac too ;)
This restores much of the performance benefit of Euler's method, without compromising accuracy (tested on 1e+7 matrices). Namely, my benchmark now runs in 1.5 s instead of 2.2 s. The same in the default branch runs in 1.08 s instead of 1.9 s, so the default branch benefits even more!
2009-10-28 03:50:29 -04:00
Benoit Jacob
9e15a6da2e Fix 4x4 matrix inversion. Applying Euler's trick is more tricky than what "high performance matrix inversion" websites would have you believe. Our 4x4 matrix inversion wasn't numerically stable, because in applying the Euler trick we didn't take the 2x2 block of biggest determinant. As a result, with float, we got relative errors above 1% every 1000 random matrices, and we got completely wrong results every 10000 matrices.
Note that this decreases the performance, but we're still significantly faster than the brutal cofactors approach.
2009-10-27 07:35:25 -04:00
Benoit Jacob
3d365a75cd Added tag 2.0.9 for changeset 38bc82a6f7 2009-10-24 19:38:58 -04:00
Benoit Jacob
38bc82a6f7 bump 2009-10-24 16:35:46 -04:00
Benoit Jacob
6173eb67ff really fix pkgconfig support and make install.
* mistake: was using the install dir instead of binary dir
* was also using INCLUDE_INSTALL_DIR before it was set, so on a first cmake run, the pkgconfig file was bad
2009-10-24 16:16:48 -04:00
Benoit Jacob
9f89431cea install NewStdVector 2009-10-23 19:58:37 -04:00
Benoit Jacob
79e392472a Added tag 2.0.8 for changeset e1c96f3fe0 2009-10-23 18:47:33 -04:00
Benoit Jacob
e1c96f3fe0 bump 2009-10-23 18:37:05 -04:00
Benoit Jacob
46f0fe3b4b SVD:
* implement default ctor, users were relying on the compiler generater one and reported issues on the forum
* turns out that we crash on 1x1 matrices but work on Nx1. No interest in fixing that, so just guard by assert and unit test.
2009-10-23 18:05:55 -04:00
Benoit Jacob
e17e4f3654 just this is enough 2009-10-23 17:51:32 -04:00
Benoit Jacob
2b006ae430 fix "make install"
aaargh
my shiny birthday release, it's broken already!
2009-10-23 17:47:12 -04:00
Benoit Jacob
df6923fd2b Added tag 2.0.7 for changeset 21d081c6da 2009-10-22 16:15:15 -04:00
Benoit Jacob
21d081c6da bump 2009-10-22 16:14:03 -04:00
Benoit Jacob
81fd1e9060 support gcc 3.3 2009-10-22 15:53:23 -04:00
Benoit Jacob
be8ae0d45f * CMakeLists: only pass -Wextra if it's supported (it's not on gcc 3.3)
* MapBase: put static first (fix gcc 3.3 warning)
* StdVector: add missing newline at end
2009-10-22 15:20:02 -04:00
Hauke Heibel
fc8b54c142 Code cleanup. 2009-10-22 20:06:05 +02:00
Hauke Heibel
76d578fb99 This does fix #61. See the comments in #61 for details. 2009-10-22 09:29:59 +02:00
Benoit Jacob
9af431e78e tentative fix for bug #61 2009-10-21 18:55:54 -04:00
Hauke Heibel
a4a3e511d0 Added missing resize case for m_outerSize==0. 2009-10-15 23:30:15 +02:00
Hauke Heibel
ffee27bf72 Fixed uninitialized variables in unit tests.
Fixed /W4 warning C4512 (LU was left out on purpose).
2009-10-14 08:33:36 +02:00
Benoit Jacob
5e24fbbead add assert for M>=N 2009-10-13 14:17:25 -04:00
Benoit Jacob
09364c8d05 fix compilation with gcc 3.3 2009-10-12 12:29:07 -04:00
Gael Guennebaud
3b8938ee1a backport d97d307fcf 2009-10-06 10:36:59 +02:00
Gael Guennebaud
e43d630d80 fix #10: the reallocateSparse function was half coded
(transplanted from 55de162cf6
)
2009-06-08 14:05:23 +02:00
Thomas Capricelli
eb1df142a3 backport changes in tip related to eigen_gen_docs 2009-10-04 03:38:13 +02:00
Thomas Capricelli
746d8b7ce9 update URL for adol-c (backport from tip) 2009-09-27 02:00:45 +02:00
Benoit Jacob
656c8faeb8 merge 2009-09-25 09:09:49 -04:00
Benoit Jacob
8084dbc86a copy the Memory.h file from the devel branch and remove some added trailing spaces.
This is now very harmless to do as the big change (EIGEN_ALIGN preprocessor stuff and the body of ei_aligned_malloc) was already introduced in 2.0.6.

Should address Björn's issue, and also improve FreeBSD platform detection.
2009-09-25 09:09:14 -04:00
Thomas Capricelli
79ebba4f52 clean tags... 2.0.6 was tagged three times, with two different values.
The best way to "push" a tag is to edit the .hgtags instead of using 'hg
tag xx' several times with the same value 'xx'.
2009-09-25 03:19:28 +02:00
Benoit Jacob
b362b45cff update .hgignore to ignore files created by eigen_gen_credits 2009-09-24 07:06:31 -04:00
Rhys Ulerich
c67b8b7ce0 Added pkgconfig support 2009-09-23 22:05:46 -04:00
Benoit Jacob
bcd621fcd5 Added tag 2.0.6 for changeset de88fb67d6 2009-09-23 12:11:26 -04:00
Benoit Jacob
de88fb67d6 bump that too 2009-09-23 12:11:19 -04:00
Benoit Jacob
4936720648 Added tag 2.0.6 for changeset 922e11e184 2009-09-23 12:08:22 -04:00
Benoit Jacob
922e11e184 bump 2009-09-23 12:08:16 -04:00
Benoit Jacob
8c2ace33c9 backport Rohit's vectorized quaternion product 2009-09-22 13:39:30 -04:00
Benoit Jacob
b66516e746 fix bug #42: add missing Transform::Identity() 2009-09-19 20:00:36 -04:00
Benoit Jacob
ecf64d2dc3 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:46:40 -04:00
Benoit Jacob
6af2c2c67a backported the following to 2.0:
* EIGEN_ALIGN and EIGEN_DONT_ALIGN and the corresponding logic in Macros.h
  (instead of using EIGEN_ARCH_WANTS_ALIGNMENT)
* The body of ei_aligned_malloc and ei_aligned_free

The reason for this backporting is that a user complained that with eigen 2.0 he got a warning at Memory.h:81 that the return value of posix_memalign was not used, and that function was declared with an attribute warn_unused_result.

Looking at this, it seemed that the body of this function was already overly complicated, and fixing this warning made it even worse, while the devel branch had a much simpler body and didn't suffer from that problem.

Then it was necessary to update ei_aligned_free too, and to backport EIGEN_ALIGN.

Inch' Allah....
2009-09-21 05:39:55 -04:00
Benoit Jacob
d0ac4fa479 explain how to get rid of it 2009-09-18 22:02:28 -04:00
Benoit Jacob
09f77b356d hg add the unit test 2009-09-16 14:29:44 -04:00
Benoit Jacob
8097487b9d backport bugfix in visitor (didn't work on rowvectors, fixed by splitting the vector case away from the matrix case) 2009-09-16 14:28:49 -04:00
Benoit Jacob
aaf1826384 backport: the first fix was the good one 2009-09-03 01:28:12 -04:00
Benoit Jacob
3590911de2 backport the fix to bug #50: compilation errors with swap 2009-09-02 17:04:34 -04:00
Benoit Jacob
21e97f07d8 update to reflect NewStdVector 2009-08-29 12:35:44 -04:00
Benoit Jacob
82df5b4a24 backport the new StdVector as NewStdVector
make StdVector be a wrapper around it if EIGEN_USE_NEW_STDVECTOR is defined
otherwise StdVector doesn't change ---> compatibility is preserved
backport unit-test
2009-08-29 12:13:52 -04:00
Benoit Jacob
35e88996c7 add missing parentheses after bug #42 2009-08-24 09:14:32 -04:00
Benoit Jacob
5dfb7204bd Added tag 2.0.5 for changeset e0cbf79e5a 2009-08-22 17:19:13 -04:00
115 changed files with 2435 additions and 532 deletions

41
.gitignore vendored Normal file
View File

@@ -0,0 +1,41 @@
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
*.patch
a
a.*
lapack/testing
lapack/reference
.*project
.settings
Makefile
!ci/build.gitlab-ci.yml
!scripts/buildtests.in
!Eigen/Core
!Eigen/src/Core

28
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,28 @@
# This file is part of Eigen, a lightweight C++ template library
# for linear algebra.
#
# Copyright (C) 2023, The Eigen Authors
#
# This Source Code Form is subject to the terms of the Mozilla
# Public License v. 2.0. If a copy of the MPL was not distributed
# with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
stages:
- build
- deploy
variables:
# CMake build directory.
EIGEN_CI_BUILDDIR: .build
# Specify the CMake build target.
EIGEN_CI_BUILD_TARGET: ""
# If a test regex is specified, that will be selected.
# Otherwise, we will try a label if specified.
EIGEN_CI_CTEST_REGEX: ""
EIGEN_CI_CTEST_LABEL: ""
EIGEN_CI_CTEST_ARGS: ""
include:
- "/ci/common.gitlab-ci.yml"
- "/ci/build.linux.gitlab-ci.yml"
- "/ci/deploy.gitlab-ci.yml"

View File

@@ -5,6 +5,7 @@ qrc_*cxx
*.diff
diff
*.save
save
*.old
*.gmo
*.qm
@@ -12,7 +13,7 @@ core
core.*
*.bak
*~
build
build*
*.moc.*
*.moc
ui_*
@@ -20,4 +21,5 @@ CMakeCache.txt
tags
.*.swp
activity.png
gmon.out
*.out
*.php*

View File

@@ -1,7 +1,13 @@
project(Eigen)
cmake_minimum_required(VERSION 2.6.2)
set(EIGEN_VERSION_NUMBER "2.0.5")
set(INCLUDE_INSTALL_DIR
"${CMAKE_INSTALL_PREFIX}/include/eigen2"
CACHE PATH
"The directory where we install the header files"
FORCE)
set(EIGEN_VERSION_NUMBER "2.0.17")
set(EIGEN_VERSION "${EIGEN_VERSION_NUMBER}")
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
@@ -12,16 +18,56 @@ if(NOT WIN32)
option(EIGEN_BUILD_LIB "Build the binary shared library" OFF)
endif(NOT WIN32)
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)
if(EIGEN_BUILD_LIB)
option(EIGEN_TEST_LIB "Build the unit tests using the library (disable -pedantic)" OFF)
endif(EIGEN_BUILD_LIB)
#############################################################################
# find how to link to the standard libraries #
#############################################################################
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()
set(CMAKE_INCLUDE_CURRENT_DIR ON)
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")
include(CheckCXXCompilerFlag)
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 -fno-exceptions -fno-check-new -fno-common -fstrict-aliasing")
check_cxx_compiler_flag("-Wextra" has_wextra)
if(has_wextra)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra")
endif()
if(NOT EIGEN_TEST_LIB)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
endif(NOT EIGEN_TEST_LIB)
@@ -71,6 +117,13 @@ endif(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
if(EIGEN_BUILD_PKGCONFIG)
configure_file(eigen2.pc.in eigen2.pc) # uses INCLUDE_INSTALL_DIR
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/eigen2.pc
DESTINATION share/pkgconfig
)
endif(EIGEN_BUILD_PKGCONFIG)
add_subdirectory(Eigen)
add_subdirectory(unsupported)

View File

@@ -1,4 +1,7 @@
set(Eigen_HEADERS Core LU Cholesky QR Geometry Sparse Array SVD LeastSquares QtAlignedMalloc StdVector)
set(Eigen_HEADERS Core LU Cholesky QR Geometry
Sparse Array SVD LeastSquares
QtAlignedMalloc StdVector NewStdVector
Eigen Dense)
if(EIGEN_BUILD_LIB)
set(Eigen_SRCS
@@ -20,12 +23,6 @@ if(CMAKE_COMPILER_IS_GNUCXX)
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)
install(FILES
${Eigen_HEADERS}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen

View File

@@ -15,7 +15,9 @@
#endif
#endif
#ifdef __GNUC__
// FIXME: this check should not be against __QNXNTO__, which is also defined
// while compiling with GCC for QNX target. Better solution is welcome!
#if defined(__GNUC__) && !defined(__QNXNTO__)
#define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__>=x && __GNUC_MINOR__>=y) || __GNUC__>x)
#else
#define EIGEN_GNUC_AT_LEAST(x,y) 0
@@ -26,7 +28,7 @@
#define EIGEN_SSE2_BUT_NOT_OLD_GCC
#endif
#ifndef EIGEN_DONT_VECTORIZE
#if !defined(EIGEN_DONT_VECTORIZE) && !defined(EIGEN_DONT_ALIGN)
#if defined (EIGEN_SSE2_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
#define EIGEN_VECTORIZE
#define EIGEN_VECTORIZE_SSE
@@ -50,6 +52,7 @@
#endif
#endif
#include <cstddef>
#include <cstdlib>
#include <cmath>
#include <complex>
@@ -77,6 +80,10 @@
namespace Eigen {
// 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

168
Eigen/NewStdVector Normal file
View File

@@ -0,0 +1,168 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <g.gael@free.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 {
// This one is needed to prevent reimplementing the whole std::vector.
template <class T>
class aligned_allocator_indirection : public aligned_allocator<T>
{
public:
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
template<class U>
struct rebind
{
typedef aligned_allocator_indirection<U> other;
};
aligned_allocator_indirection() throw() {}
aligned_allocator_indirection(const aligned_allocator_indirection& ) throw() : aligned_allocator<T>() {}
aligned_allocator_indirection(const aligned_allocator<T>& ) throw() {}
template<class U>
aligned_allocator_indirection(const aligned_allocator_indirection<U>& ) throw() {}
template<class U>
aligned_allocator_indirection(const aligned_allocator<U>& ) throw() {}
~aligned_allocator_indirection() throw() {}
};
#ifdef _MSC_VER
// sometimes, MSVC detects, at compile time, that the argument x
// in std::vector::resize(size_t s,T x) won't be aligned and generate an error
// even if this function is never called. Whence this little wrapper.
#define EIGEN_WORKAROUND_MSVC_STD_VECTOR(T) Eigen::ei_workaround_msvc_std_vector<T>
template<typename T> struct ei_workaround_msvc_std_vector : public T
{
inline ei_workaround_msvc_std_vector() : T() {}
inline ei_workaround_msvc_std_vector(const T& other) : T(other) {}
inline operator T& () { return *static_cast<T*>(this); }
inline operator const T& () const { return *static_cast<const T*>(this); }
template<typename OtherT>
inline T& operator=(const OtherT& other)
{ T::operator=(other); return *this; }
inline ei_workaround_msvc_std_vector& operator=(const ei_workaround_msvc_std_vector& other)
{ T::operator=(other); return *this; }
};
#else
#define EIGEN_WORKAROUND_MSVC_STD_VECTOR(T) T
#endif
}
namespace std {
#define EIGEN_STD_VECTOR_SPECIALIZATION_BODY \
public: \
typedef T value_type; \
typedef typename vector_base::allocator_type allocator_type; \
typedef typename vector_base::size_type size_type; \
typedef typename vector_base::iterator iterator; \
typedef typename vector_base::const_iterator const_iterator; \
explicit vector(const allocator_type& a = allocator_type()) : vector_base(a) {} \
template<typename InputIterator> \
vector(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) \
: vector_base(first, last, a) {} \
vector(const vector& c) : vector_base(c) {} \
explicit vector(size_type num, const value_type& val = value_type()) : vector_base(num, val) {} \
vector(iterator start, iterator end) : vector_base(start, end) {} \
vector& operator=(const vector& x) { \
vector_base::operator=(x); \
return *this; \
}
template<typename T>
class vector<T,Eigen::aligned_allocator<T> >
: public vector<EIGEN_WORKAROUND_MSVC_STD_VECTOR(T),
Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STD_VECTOR(T)> >
{
typedef vector<EIGEN_WORKAROUND_MSVC_STD_VECTOR(T),
Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STD_VECTOR(T)> > vector_base;
EIGEN_STD_VECTOR_SPECIALIZATION_BODY
void resize(size_type new_size)
{ resize(new_size, T()); }
#if defined(_VECTOR_)
// workaround MSVC std::vector implementation
void resize(size_type new_size, const value_type& x)
{
if (vector_base::size() < new_size)
vector_base::_Insert_n(vector_base::end(), new_size - vector_base::size(), x);
else if (new_size < vector_base::size())
vector_base::erase(vector_base::begin() + new_size, vector_base::end());
}
void push_back(const value_type& x)
{ vector_base::push_back(x); }
using vector_base::insert;
iterator insert(const_iterator position, const value_type& x)
{ return vector_base::insert(position,x); }
void insert(const_iterator position, size_type new_size, const value_type& x)
{ vector_base::insert(position, new_size, x); }
#elif defined(_GLIBCXX_VECTOR) && EIGEN_GNUC_AT_LEAST(4,2)
// workaround GCC std::vector implementation
void resize(size_type new_size, const value_type& x)
{
if (new_size < vector_base::size())
vector_base::_M_erase_at_end(this->_M_impl._M_start + new_size);
else
vector_base::insert(vector_base::end(), new_size - vector_base::size(), x);
}
#elif defined(_GLIBCXX_VECTOR) && (!EIGEN_GNUC_AT_LEAST(4,1))
// Note that before gcc-4.1 we already have: std::vector::resize(size_type,const T&),
// no no need to workaround !
using vector_base::resize;
#else
// either GCC 4.1 or non-GCC
// default implementation which should always work.
void resize(size_type new_size, const value_type& x)
{
if (new_size < vector_base::size())
vector_base::erase(vector_base::begin() + new_size, vector_base::end());
else if (new_size > vector_base::size())
vector_base::insert(vector_base::end(), new_size - vector_base::size(), x);
}
#endif
};
}
#endif // EIGEN_STDVECTOR_MODULE_H

View File

@@ -1,10 +1,23 @@
#ifndef EIGEN_QTMALLOC_MODULE_H
#define EIGEN_QTMALLOC_MODULE_H
#if (!EIGEN_MALLOC_ALREADY_ALIGNED)
#ifdef QVECTOR_H
#error You must include <Eigen/QtAlignedMalloc> before <QtCore/QVector>.
#endif
#ifdef Q_DECL_IMPORT
#define Q_DECL_IMPORT_ORIG Q_DECL_IMPORT
#undef Q_DECL_IMPORT
#define Q_DECL_IMPORT
#else
#define Q_DECL_IMPORT
#endif
#include "Core"
#if (!EIGEN_MALLOC_ALREADY_ALIGNED)
#include <QtCore/QVector>
inline void *qMalloc(size_t size)
{
@@ -26,4 +39,11 @@ inline void *qRealloc(void *ptr, size_t size)
#endif
#ifdef Q_DECL_IMPORT_ORIG
#define Q_DECL_IMPORT Q_DECL_IMPORT_ORIG
#undef Q_DECL_IMPORT_ORIG
#else
#undef Q_DECL_IMPORT
#endif
#endif // EIGEN_QTMALLOC_MODULE_H

View File

@@ -1,3 +1,7 @@
#ifdef EIGEN_USE_NEW_STDVECTOR
#include "NewStdVector"
#else
#ifndef EIGEN_STDVECTOR_MODULE_H
#define EIGEN_STDVECTOR_MODULE_H
@@ -139,3 +143,5 @@ class vector<T,DummyAlloc,true>
}
#endif // EIGEN_STDVECTOR_MODULE_H
#endif // EIGEN_USE_NEW_STDVECTOR

View File

@@ -139,7 +139,7 @@ inline bool MatrixBase<Derived>::any() const
template<typename Derived>
inline int MatrixBase<Derived>::count() const
{
return this->cast<bool>().cast<int>().sum();
return this->cast<bool>().template cast<int>().sum();
}
#endif // EIGEN_ALLANDANY_H

View File

@@ -43,6 +43,8 @@ struct ei_scalar_add_op {
inline const PacketScalar packetOp(const PacketScalar& a) const
{ return ei_padd(a, ei_pset1(m_other)); }
const Scalar m_other;
private:
ei_scalar_add_op& operator=(const ei_scalar_add_op&);
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_add_op<Scalar> >
@@ -138,6 +140,8 @@ struct ei_scalar_pow_op {
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;
private:
ei_scalar_pow_op& operator=(const ei_scalar_pow_op&);
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_pow_op<Scalar> >

View File

@@ -133,6 +133,8 @@ struct ei_member_redux {
inline result_type operator()(const MatrixBase<Derived>& mat) const
{ return mat.redux(m_functor); }
const BinaryOp m_functor;
private:
ei_member_redux& operator=(const ei_member_redux&);
};
/** \array_module \ingroup Array
@@ -158,13 +160,15 @@ template<typename ExpressionType, int Direction> class PartialRedux
public:
typedef typename ei_traits<ExpressionType>::Scalar Scalar;
typedef typename NumTraits<Scalar>::Real RealScalar;
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
template<template<typename _Scalar> class Functor,
typename Scalar = typename ei_traits<ExpressionType>::Scalar> struct ReturnType
{
typedef PartialReduxExpr<ExpressionType,
Functor<typename ei_traits<ExpressionType>::Scalar>,
Functor<Scalar>,
Direction
> Type;
};
@@ -215,7 +219,7 @@ template<typename ExpressionType, int Direction> class PartialRedux
* Output: \verbinclude PartialRedux_squaredNorm.out
*
* \sa MatrixBase::squaredNorm() */
const typename ReturnType<ei_member_squaredNorm>::Type squaredNorm() const
const typename ReturnType<ei_member_squaredNorm,RealScalar>::Type squaredNorm() const
{ return _expression(); }
/** \returns a row (or column) vector expression of the norm
@@ -225,7 +229,7 @@ template<typename ExpressionType, int Direction> class PartialRedux
* Output: \verbinclude PartialRedux_norm.out
*
* \sa MatrixBase::norm() */
const typename ReturnType<ei_member_norm>::Type norm() const
const typename ReturnType<ei_member_norm,RealScalar>::Type norm() const
{ return _expression(); }
/** \returns a row (or column) vector expression of the sum
@@ -290,6 +294,9 @@ template<typename ExpressionType, int Direction> class PartialRedux
protected:
ExpressionTypeNested m_matrix;
private:
PartialRedux& operator=(const PartialRedux&);
};
/** \array_module

View File

@@ -96,8 +96,7 @@ void LDLT<MatrixType>::compute(const MatrixType& a)
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>());
m_isPositiveDefinite = true; // always true. This decomposition is not rank-revealing anyway.
if (size<=1)
{
@@ -121,12 +120,6 @@ void LDLT<MatrixType>::compute(const MatrixType& a)
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)
{
m_isPositiveDefinite = false;
return;
}
int endSize = size-j-1;
if (endSize>0)
{
@@ -136,7 +129,8 @@ void LDLT<MatrixType>::compute(const MatrixType& a)
m_matrix.row(j).end(endSize) = a.row(j).end(endSize).conjugate()
- _temporary.end(endSize).transpose();
m_matrix.col(j).end(endSize) = m_matrix.row(j).end(endSize) / tmp;
if(tmp != RealScalar(0))
m_matrix.col(j).end(endSize) = m_matrix.row(j).end(endSize) / tmp;
}
}
}
@@ -192,7 +186,7 @@ template<typename Derived>
inline const LDLT<typename MatrixBase<Derived>::PlainMatrixType>
MatrixBase<Derived>::ldlt() const
{
return derived();
return LDLT<PlainMatrixType>(derived());
}
#endif // EIGEN_LDLT_H

View File

@@ -132,11 +132,12 @@ void LLT<MatrixType>::compute(const MatrixType& a)
m_isInitialized = true;
return;
}
m_matrix.col(0).end(size-1) = a.row(0).end(size-1).adjoint() / ei_real(m_matrix.coeff(0,0));
if(ei_real(m_matrix.coeff(0,0))>0)
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)
{
x = ei_real(a.coeff(j,j)) - m_matrix.row(j).start(j).squaredNorm();
if (x < cutoff)
if (x <= cutoff)
{
m_isPositiveDefinite = false;
continue;

View File

@@ -90,6 +90,28 @@ public:
? ( int(MayUnrollCompletely) && int(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) )
: int(NoUnrolling)
};
#ifdef EIGEN_DEBUG_ASSIGN
#define EIGEN_DEBUG_VAR(x) std::cerr << #x << " = " << x << std::endl;
static void debug()
{
EIGEN_DEBUG_VAR(DstIsAligned)
EIGEN_DEBUG_VAR(SrcIsAligned)
EIGEN_DEBUG_VAR(SrcAlignment)
EIGEN_DEBUG_VAR(InnerSize)
EIGEN_DEBUG_VAR(InnerMaxSize)
EIGEN_DEBUG_VAR(PacketSize)
EIGEN_DEBUG_VAR(MightVectorize)
EIGEN_DEBUG_VAR(MayInnerVectorize)
EIGEN_DEBUG_VAR(MayLinearVectorize)
EIGEN_DEBUG_VAR(MaySliceVectorize)
EIGEN_DEBUG_VAR(Vectorization)
EIGEN_DEBUG_VAR(UnrollingLimit)
EIGEN_DEBUG_VAR(MayUnrollCompletely)
EIGEN_DEBUG_VAR(MayUnrollInner)
EIGEN_DEBUG_VAR(Unrolling)
}
#endif
};
/***************************************************************************
@@ -400,6 +422,9 @@ template<typename OtherDerived>
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>
::lazyAssign(const MatrixBase<OtherDerived>& other)
{
#ifdef EIGEN_DEBUG_ASSIGN
ei_assign_traits<Derived, OtherDerived>::debug();
#endif
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)

View File

@@ -222,7 +222,7 @@ class Block<MatrixType,BlockRows,BlockCols,PacketAccess,HasDirectAccess>
class InnerIterator;
typedef typename ei_traits<Block>::AlignedDerivedType AlignedDerivedType;
friend class Block<MatrixType,BlockRows,BlockCols,PacketAccess==AsRequested?ForceAligned:AsRequested,HasDirectAccess>;
friend class Block<MatrixType,BlockRows,BlockCols,PacketAccess==int(AsRequested)?ForceAligned:AsRequested,HasDirectAccess>;
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)

View File

@@ -33,7 +33,7 @@ struct ei_L2_block_traits {
#ifndef EIGEN_EXTERN_INSTANTIATIONS
template<typename Scalar>
static void ei_cache_friendly_product(
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,
@@ -84,7 +84,7 @@ static void ei_cache_friendly_product(
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 bool resIsAligned = (PacketSize==1) || (((resStride%PacketSize) == 0) && (std::size_t(res)%16==0));
const int remainingSize = depth % PacketSize;
const int size = depth - remainingSize; // third dimension of the product clamped to packet boundaries
@@ -92,7 +92,7 @@ static void ei_cache_friendly_product(
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));
const bool needRhsCopy = (PacketSize>1) && ((rhsStride%PacketSize!=0) || (std::size_t(rhs)%16!=0));
Scalar* EIGEN_RESTRICT block = 0;
const int allocBlockSize = l2BlockRows*size;
block = ei_aligned_stack_new(Scalar, allocBlockSize);
@@ -172,7 +172,7 @@ static void ei_cache_friendly_product(
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));
std::memcpy(rhsCopy+l2BlockSizeAligned*(l1j-l2j),&(rhs[l1j*rhsStride+l2k]),(l2blockSizeEnd-l2k)*sizeof(Scalar));
}
// for each bw x 1 result's block
@@ -352,7 +352,7 @@ static void ei_cache_friendly_product(
* 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(
EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
int size,
const Scalar* lhs, int lhsStride,
const RhsType& rhs,
@@ -397,7 +397,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
int skipColumns = 0;
if (PacketSize>1)
{
ei_internal_assert(size_t(lhs+lhsAlignmentOffset)%sizeof(Packet)==0 || size<PacketSize);
ei_internal_assert(std::size_t(lhs+lhsAlignmentOffset)%sizeof(Packet)==0 || size<PacketSize);
while (skipColumns<PacketSize &&
alignedStart != ((lhsAlignmentOffset + alignmentStep*skipColumns)%PacketSize))
@@ -414,7 +414,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
// note that the skiped columns are processed later.
}
ei_internal_assert((alignmentPattern==NoneAligned) || (size_t(lhs+alignedStart+lhsStride*skipColumns)%sizeof(Packet))==0);
ei_internal_assert((alignmentPattern==NoneAligned) || (std::size_t(lhs+alignedStart+lhsStride*skipColumns)%sizeof(Packet))==0);
}
int offset1 = (FirstAligned && alignmentStep==1?3:1);
@@ -516,7 +516,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
res[j] += ei_pfirst(ptmp0) * lhs0[j];
// process aligned result's coeffs
if ((size_t(lhs0+alignedStart)%sizeof(Packet))==0)
if ((std::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
@@ -542,7 +542,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
// 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(
EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
const Scalar* lhs, int lhsStride,
const Scalar* rhs, int rhsSize,
ResType& res)
@@ -586,7 +586,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
int skipRows = 0;
if (PacketSize>1)
{
ei_internal_assert(size_t(lhs+lhsAlignmentOffset)%sizeof(Packet)==0 || size<PacketSize);
ei_internal_assert(std::size_t(lhs+lhsAlignmentOffset)%sizeof(Packet)==0 || size<PacketSize);
while (skipRows<PacketSize &&
alignedStart != ((lhsAlignmentOffset + alignmentStep*skipRows)%PacketSize))
@@ -603,7 +603,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
// note that the skiped columns are processed later.
}
ei_internal_assert((alignmentPattern==NoneAligned) || PacketSize==1
|| (size_t(lhs+alignedStart+lhsStride*skipRows)%sizeof(Packet))==0);
|| (std::size_t(lhs+alignedStart+lhsStride*skipRows)%sizeof(Packet))==0);
}
int offset1 = (FirstAligned && alignmentStep==1?3:1);
@@ -722,7 +722,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
if (alignedSize>alignedStart)
{
// process aligned rhs coeffs
if ((size_t(lhs0+alignedStart)%sizeof(Packet))==0)
if ((std::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

View File

@@ -116,6 +116,9 @@ struct CommaInitializer
int m_row; // current row id
int m_col; // current col id
int m_currentBlockRows; // current block height
private:
CommaInitializer& operator=(const CommaInitializer&);
};
/** \anchor MatrixBaseCommaInitRef

View File

@@ -32,7 +32,7 @@ namespace Eigen
{
#define EIGEN_INSTANTIATE_PRODUCT(TYPE) \
template static void ei_cache_friendly_product<TYPE>( \
template void ei_cache_friendly_product<TYPE>( \
int _rows, int _cols, int depth, \
bool _lhsRowMajor, const TYPE* _lhs, int _lhsStride, \
bool _rhsRowMajor, const TYPE* _rhs, int _rhsStride, \

View File

@@ -178,6 +178,9 @@ template<typename ExpressionType> class Cwise
protected:
ExpressionTypeNested m_matrix;
private:
Cwise& operator=(const Cwise&);
};
/** \returns a Cwise wrapper of *this providing additional coefficient-wise operations

View File

@@ -47,11 +47,11 @@ struct ei_traits<DiagonalCoeffs<MatrixType> >
typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
enum {
RowsAtCompileTime = int(MatrixType::SizeAtCompileTime) == Dynamic ? Dynamic
: EIGEN_ENUM_MIN(MatrixType::RowsAtCompileTime,
: EIGEN_SIZE_MIN(MatrixType::RowsAtCompileTime,
MatrixType::ColsAtCompileTime),
ColsAtCompileTime = 1,
MaxRowsAtCompileTime = int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic
: EIGEN_ENUM_MIN(MatrixType::MaxRowsAtCompileTime,
: EIGEN_SIZE_MIN(MatrixType::MaxRowsAtCompileTime,
MatrixType::MaxColsAtCompileTime),
MaxColsAtCompileTime = 1,
Flags = (unsigned int)_MatrixTypeNested::Flags & (HereditaryBits | LinearAccessBit),

View File

@@ -109,6 +109,9 @@ template<typename ExpressionType, unsigned int Added, unsigned int Removed> clas
protected:
ExpressionTypeNested m_matrix;
private:
Flagged& operator=(const Flagged&);
};
/** \returns an expression of *this with added flags

View File

@@ -279,6 +279,8 @@ struct ei_scalar_multiple_op {
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
{ return ei_pmul(a, ei_pset1(m_other)); }
const Scalar m_other;
private:
ei_scalar_multiple_op& operator=(const ei_scalar_multiple_op&);
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_multiple_op<Scalar> >
@@ -294,6 +296,8 @@ struct ei_scalar_quotient1_impl {
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
{ return ei_pmul(a, ei_pset1(m_other)); }
const Scalar m_other;
private:
ei_scalar_quotient1_impl& operator=(const ei_scalar_quotient1_impl&);
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_quotient1_impl<Scalar,true> >
@@ -306,6 +310,8 @@ struct ei_scalar_quotient1_impl<Scalar,false> {
EIGEN_STRONG_INLINE ei_scalar_quotient1_impl(const Scalar& other) : m_other(other) {}
EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a / m_other; }
const Scalar m_other;
private:
ei_scalar_quotient1_impl& operator=(const ei_scalar_quotient1_impl&);
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_quotient1_impl<Scalar,false> >
@@ -323,6 +329,8 @@ template<typename Scalar>
struct ei_scalar_quotient1_op : ei_scalar_quotient1_impl<Scalar, NumTraits<Scalar>::HasFloatingPoint > {
EIGEN_STRONG_INLINE ei_scalar_quotient1_op(const Scalar& other)
: ei_scalar_quotient1_impl<Scalar, NumTraits<Scalar>::HasFloatingPoint >(other) {}
private:
ei_scalar_quotient1_op& operator=(const ei_scalar_quotient1_op&);
};
// nullary functors
@@ -335,6 +343,8 @@ struct ei_scalar_constant_op {
EIGEN_STRONG_INLINE const Scalar operator() (int, int = 0) const { return m_other; }
EIGEN_STRONG_INLINE const PacketScalar packetOp() const { return ei_pset1(m_other); }
const Scalar m_other;
private:
ei_scalar_constant_op& operator=(const ei_scalar_constant_op&);
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_constant_op<Scalar> >

View File

@@ -66,11 +66,11 @@ template<typename Derived> class MapBase
inline const Scalar* data() const { return m_data; }
template<bool IsForceAligned,typename Dummy> struct force_aligned_impl {
AlignedDerivedType static run(MapBase& a) { return a.derived(); }
static AlignedDerivedType run(MapBase& a) { return a.derived(); }
};
template<typename Dummy> struct force_aligned_impl<false,Dummy> {
AlignedDerivedType static run(MapBase& a) { return a.derived()._convertToForceAligned(); }
static AlignedDerivedType run(MapBase& a) { return a.derived()._convertToForceAligned(); }
};
/** \returns an expression equivalent to \c *this but having the \c PacketAccess constant
@@ -99,7 +99,7 @@ template<typename Derived> class MapBase
inline const Scalar coeff(int index) const
{
ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit));
if ( ((RowsAtCompileTime == 1) == IsRowMajor) )
if ( ((RowsAtCompileTime == 1) == IsRowMajor) || !int(Derived::IsVectorAtCompileTime) )
return m_data[index];
else
return m_data[index*stride()];
@@ -108,7 +108,7 @@ template<typename Derived> class MapBase
inline Scalar& coeffRef(int index)
{
ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit));
if ( ((RowsAtCompileTime == 1) == IsRowMajor) )
if ( ((RowsAtCompileTime == 1) == IsRowMajor) || !int(Derived::IsVectorAtCompileTime) )
return const_cast<Scalar*>(m_data)[index];
else
return const_cast<Scalar*>(m_data)[index*stride()];

View File

@@ -35,16 +35,6 @@ template<typename T> inline T ei_random_amplitude()
else return static_cast<T>(10);
}
template<typename T> inline T ei_hypot(T x, T y)
{
T _x = ei_abs(x);
T _y = ei_abs(y);
T p = std::max(_x, _y);
T q = std::min(_x, _y);
T qp = q/p;
return p * ei_sqrt(T(1) + qp*qp);
}
/**************
*** int ***
**************/
@@ -54,7 +44,7 @@ template<> inline int machine_epsilon<int>() { return 0; }
inline int ei_real(int x) { return x; }
inline int ei_imag(int) { return 0; }
inline int ei_conj(int x) { return x; }
inline int ei_abs(int x) { return abs(x); }
inline int ei_abs(int x) { return std::abs(x); }
inline int ei_abs2(int x) { return x*x; }
inline int ei_sqrt(int) { ei_assert(false); return 0; }
inline int ei_exp(int) { ei_assert(false); return 0; }
@@ -67,7 +57,7 @@ inline int ei_pow(int x, int y) { return int(std::pow(double(x), y)); }
template<> inline int ei_random(int a, int b)
{
// We can't just do rand()%n as only the high-order bits are really random
return a + static_cast<int>((b-a+1) * (rand() / (RAND_MAX + 1.0)));
return a + static_cast<int>((b-a+1) * (std::rand() / (RAND_MAX + 1.0)));
}
template<> inline int ei_random()
{
@@ -292,4 +282,14 @@ inline bool ei_isApproxOrLessThan(long double a, long double b, long double prec
return a <= b || ei_isApprox(a, b, prec);
}
template<typename T> inline T ei_hypot(T x, T y)
{
T _x = ei_abs(x);
T _y = ei_abs(y);
T p = std::max(_x, _y);
T q = std::min(_x, _y);
T qp = q/p;
return p * ei_sqrt(T(1) + qp*qp);
}
#endif // EIGEN_MATHFUNCTIONS_H

View File

@@ -25,6 +25,11 @@
#ifndef EIGEN_MATRIX_H
#define EIGEN_MATRIX_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
/** \class Matrix
*
@@ -137,6 +142,9 @@ class Matrix
enum { NeedsToAlign = (Options&AutoAlign) == AutoAlign
&& SizeAtCompileTime!=Dynamic && ((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 int rows() const { return m_storage.rows(); }
EIGEN_STRONG_INLINE int cols() const { return m_storage.cols(); }
@@ -230,7 +238,14 @@ class Matrix
&& (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
&& (MaxColsAtCompileTime == Dynamic || MaxColsAtCompileTime >= cols)
&& (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
m_storage.resize(rows * cols, rows, cols);
#ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
int size = rows*cols;
bool size_changed = size != this->size();
m_storage.resize(size, rows, cols);
if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
#else
m_storage.resize(rows*cols, rows, cols);
#endif
}
/** Resizes \c *this to a vector of length \a size
@@ -240,10 +255,17 @@ class Matrix
inline void resize(int size)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix)
ei_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
}
/** Copies the value of the expression \a other into \c *this with automatic resizing.
@@ -287,13 +309,14 @@ class Matrix
EIGEN_STRONG_INLINE explicit Matrix() : m_storage()
{
_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())
{}
{EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED}
#endif
/** Constructs a vector or row-vector with given dimension. \only_for_vectors
@@ -309,6 +332,7 @@ class Matrix
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix)
ei_assert(dim > 0);
ei_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.
@@ -334,6 +358,7 @@ class Matrix
{
ei_assert(x > 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == x)
&& y > 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == y));
EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
}
}
/** constructs an initialized 2D vector with given coefficients */
@@ -395,18 +420,14 @@ class 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)
{
if (Base::SizeAtCompileTime==Dynamic)
m_storage.swap(other.m_storage);
else
this->Base::swap(other);
}
template<typename OtherDerived>
void swap(const MatrixBase<OtherDerived>& other);
/** \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 are convenience functions returning Map objects.
*
* \warning Do not use MapAligned in the Eigen 2.0. Mapping aligned arrays will be fully
* supported in Eigen 3.0 (already implemented in the development branch)
*
* \see class Map
*/
@@ -507,7 +528,9 @@ class Matrix
template<typename OtherDerived>
EIGEN_STRONG_INLINE Matrix& _set(const MatrixBase<OtherDerived>& other)
{
_set_selector(other.derived(), typename ei_meta_if<bool(int(OtherDerived::Flags) & EvalBeforeAssigningBit), ei_meta_true, ei_meta_false>::ret());
// this enum introduced to fix compilation with gcc 3.3
enum { cond = int(OtherDerived::Flags) & EvalBeforeAssigningBit };
_set_selector(other.derived(), typename ei_meta_if<bool(cond), ei_meta_true, ei_meta_false>::ret());
return *this;
}
@@ -540,8 +563,40 @@ class Matrix
&& (_Options & (AutoAlign|RowMajor)) == _Options),
INVALID_MATRIX_TEMPLATE_PARAMETERS)
}
template<typename MatrixType, typename OtherDerived, bool IsSameType, bool IsDynamicSize>
friend struct ei_matrix_swap_impl;
};
template<typename MatrixType, typename OtherDerived,
bool IsSameType = ei_is_same_type<MatrixType, OtherDerived>::ret,
bool IsDynamicSize = MatrixType::SizeAtCompileTime==Dynamic>
struct ei_matrix_swap_impl
{
static inline void run(MatrixType& matrix, MatrixBase<OtherDerived>& other)
{
matrix.base().swap(other);
}
};
template<typename MatrixType, typename OtherDerived>
struct ei_matrix_swap_impl<MatrixType, OtherDerived, true, true>
{
static inline void run(MatrixType& matrix, MatrixBase<OtherDerived>& other)
{
matrix.m_storage.swap(other.derived().m_storage);
}
};
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
template<typename OtherDerived>
inline void Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::swap(const MatrixBase<OtherDerived>& other)
{
// the Eigen:: here is to work around a stupid ICC 11.1 bug.
Eigen::ei_matrix_swap_impl<Matrix, OtherDerived>::run(*this, *const_cast<MatrixBase<OtherDerived>*>(&other));
}
/** \defgroup matrixtypedefs Global matrix typedefs
*
* \ingroup Core_Module

View File

@@ -136,12 +136,6 @@ template<typename Derived> class MatrixBase
*/
};
/** 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
@@ -165,7 +159,7 @@ template<typename Derived> class MatrixBase
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(); }
inline int 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
@@ -532,8 +526,11 @@ template<typename Derived> class MatrixBase
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;
typename ei_traits<Derived>::Scalar minCoeff(int* row, int* col) const;
typename ei_traits<Derived>::Scalar maxCoeff(int* row, int* col) const;
typename ei_traits<Derived>::Scalar minCoeff(int* index) const;
typename ei_traits<Derived>::Scalar maxCoeff(int* index) const;
template<typename BinaryOp>
typename ei_result_of<BinaryOp(typename ei_traits<Derived>::Scalar)>::type
@@ -586,7 +583,8 @@ template<typename Derived> class MatrixBase
const LU<PlainMatrixType> lu() const;
const PlainMatrixType inverse() const;
void computeInverse(PlainMatrixType *result) const;
template<typename ResultType>
void computeInverse(MatrixBase<ResultType> *result) const;
Scalar determinant() const;
/////////// Cholesky module ///////////
@@ -624,6 +622,24 @@ template<typename Derived> class MatrixBase
#ifdef EIGEN_MATRIXBASE_PLUGIN
#include EIGEN_MATRIXBASE_PLUGIN
#endif
protected:
/** Default constructor. Do nothing. */
MatrixBase()
{
/* 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(ei_are_flags_consistent<Flags>::ret,
INVALID_MATRIXBASE_TEMPLATE_PARAMETERS)
#endif
}
private:
explicit MatrixBase(int);
MatrixBase(int,int);
template<typename OtherDerived> explicit MatrixBase(const MatrixBase<OtherDerived>&);
};
#endif // EIGEN_MATRIXBASE_H

View File

@@ -41,7 +41,7 @@ template <typename T, int Size, int MatrixOptions,
{
#ifndef EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
ei_assert((reinterpret_cast<size_t>(array) & 0xf) == 0
&& "this assertion is explained here: http://eigen.tuxfamily.org/dox/UnalignedArrayAssert.html **** READ THIS WEB PAGE !!! ****");
&& "this assertion is explained here: http://eigen.tuxfamily.org/dox-2.0/UnalignedArrayAssert.html **** READ THIS WEB PAGE !!! ****");
#endif
}

View File

@@ -100,6 +100,9 @@ template<typename ExpressionType> class NestByValue
protected:
const ExpressionType m_expression;
private:
NestByValue& operator=(const NestByValue&);
};
/** \returns an expression of the temporary version of *this.

View File

@@ -94,7 +94,7 @@ template<typename _Real> struct NumTraits<std::complex<_Real> >
enum {
IsComplex = 1,
HasFloatingPoint = NumTraits<Real>::HasFloatingPoint,
ReadCost = 2,
ReadCost = 2 * NumTraits<_Real>::ReadCost,
AddCost = 2 * NumTraits<Real>::AddCost,
MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost
};

View File

@@ -50,7 +50,7 @@ struct ei_traits<Part<MatrixType, Mode> > : ei_traits<MatrixType>
typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
enum {
Flags = (_MatrixTypeNested::Flags & (HereditaryBits) & (~(PacketAccessBit | DirectAccessBit | LinearAccessBit))) | Mode,
CoeffReadCost = _MatrixTypeNested::CoeffReadCost
CoeffReadCost = _MatrixTypeNested::CoeffReadCost + ConditionalJumpCost
};
};
@@ -124,8 +124,10 @@ template<typename MatrixType, unsigned int Mode> class Part
}
protected:
const typename MatrixType::Nested m_matrix;
private:
Part& operator=(const Part&);
};
/** \nonstableyet

View File

@@ -66,11 +66,8 @@ struct ProductReturnType
template<typename Lhs, typename Rhs>
struct ProductReturnType<Lhs,Rhs,CacheFriendlyProduct>
{
typedef typename ei_nested<Lhs,Rhs::ColsAtCompileTime>::type LhsNested;
typedef typename ei_nested<Rhs,Lhs::RowsAtCompileTime,
typename ei_plain_matrix_type_column_major<Rhs>::type
>::type RhsNested;
typedef const Lhs& LhsNested;
typedef const Rhs& RhsNested;
typedef Product<LhsNested, RhsNested, CacheFriendlyProduct> Type;
};
@@ -128,7 +125,7 @@ struct ei_traits<Product<LhsNested, RhsNested, ProductMode> >
RowsAtCompileTime = _LhsNested::RowsAtCompileTime,
ColsAtCompileTime = _RhsNested::ColsAtCompileTime,
InnerSize = EIGEN_ENUM_MIN(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime),
InnerSize = EIGEN_SIZE_MIN(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime),
MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime,
MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime,
@@ -144,7 +141,7 @@ struct ei_traits<Product<LhsNested, RhsNested, ProductMode> >
EvalToRowMajor = RhsRowMajor && (ProductMode==(int)CacheFriendlyProduct ? LhsRowMajor : (!CanVectorizeLhs)),
RemovedBits = ~(EvalToRowMajor ? 0 : RowMajorBit),
RemovedBits = ~((EvalToRowMajor ? 0 : RowMajorBit)|DirectAccessBit),
Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits)
| EvalBeforeAssigningBit
@@ -190,6 +187,17 @@ template<typename LhsNested, typename RhsNested, int ProductMode> class Product
_LhsNested, _RhsNested, Scalar> ScalarCoeffImpl;
public:
typedef typename ei_nested<_LhsNested,_RhsNested::ColsAtCompileTime>::type LhsNestedX;
typedef typename ei_nested<_RhsNested,_LhsNested::RowsAtCompileTime>::type RhsNestedX;
typedef typename ei_cleantype<LhsNestedX>::type _LhsNestedX;
typedef typename ei_cleantype<RhsNestedX>::type _RhsNestedX;
enum {
LhsNestedFlags = _LhsNestedX::Flags,
RhsNestedFlags = _RhsNestedX::Flags
};
template<typename Lhs, typename Rhs>
inline Product(const Lhs& lhs, const Rhs& rhs)
@@ -525,11 +533,11 @@ static void ei_cache_friendly_product_rowmajor_times_vector(
template<typename ProductType,
int LhsRows = ei_traits<ProductType>::RowsAtCompileTime,
int LhsOrder = int(ei_traits<ProductType>::LhsFlags)&RowMajorBit ? RowMajor : ColMajor,
int LhsHasDirectAccess = int(ei_traits<ProductType>::LhsFlags)&DirectAccessBit? HasDirectAccess : NoDirectAccess,
int RhsCols = ei_traits<ProductType>::ColsAtCompileTime,
int RhsOrder = int(ei_traits<ProductType>::RhsFlags)&RowMajorBit ? RowMajor : ColMajor,
int RhsHasDirectAccess = int(ei_traits<ProductType>::RhsFlags)&DirectAccessBit? HasDirectAccess : NoDirectAccess>
int LhsOrder = int(ProductType::LhsNestedFlags)&RowMajorBit ? RowMajor : ColMajor,
int LhsHasDirectAccess = int(ProductType::LhsNestedFlags)&DirectAccessBit? HasDirectAccess : NoDirectAccess,
int RhsCols = ProductType::ColsAtCompileTime,
int RhsOrder = int(ProductType::RhsNestedFlags)&RowMajorBit ? RowMajor : ColMajor,
int RhsHasDirectAccess = int(ProductType::RhsNestedFlags)&DirectAccessBit? HasDirectAccess : NoDirectAccess>
struct ei_cache_friendly_product_selector
{
template<typename DestDerived>
@@ -546,9 +554,12 @@ struct ei_cache_friendly_product_selector<ProductType,LhsRows,ColMajor,NoDirectA
template<typename DestDerived>
inline static void run(DestDerived& res, const ProductType& product)
{
const int size = product.rhs().rows();
typename ProductType::LhsNestedX lhs(product.lhs());
typename ProductType::RhsNestedX rhs(product.rhs());
const int size = rhs.rows();
for (int k=0; k<size; ++k)
res += product.rhs().coeff(k) * product.lhs().col(k);
res += rhs.coeff(k) * lhs.col(k);
}
};
@@ -562,6 +573,9 @@ struct ei_cache_friendly_product_selector<ProductType,LhsRows,ColMajor,HasDirect
template<typename DestDerived>
inline static void run(DestDerived& res, const ProductType& product)
{
typename ProductType::LhsNestedX lhs(product.lhs());
typename ProductType::RhsNestedX rhs(product.rhs());
enum {
EvalToRes = (ei_packet_traits<Scalar>::size==1)
||((DestDerived::Flags&ActualPacketAccessBit) && (!(DestDerived::Flags & RowMajorBit))) };
@@ -571,15 +585,15 @@ struct ei_cache_friendly_product_selector<ProductType,LhsRows,ColMajor,HasDirect
else
{
_res = ei_aligned_stack_new(Scalar,res.size());
Map<Matrix<Scalar,DestDerived::RowsAtCompileTime,1> >(_res, res.size()) = res;
Map<Matrix<Scalar,DestDerived::RowsAtCompileTime,1,ColMajor> >(_res, res.size()) = res;
}
ei_cache_friendly_product_colmajor_times_vector(res.size(),
&product.lhs().const_cast_derived().coeffRef(0,0), product.lhs().stride(),
product.rhs(), _res);
&lhs.const_cast_derived().coeffRef(0,0), lhs.stride(),
rhs, _res);
if (!EvalToRes)
{
res = Map<Matrix<Scalar,DestDerived::SizeAtCompileTime,1> >(_res, res.size());
res = Map<Matrix<Scalar,DestDerived::SizeAtCompileTime,1,ColMajor> >(_res, res.size());
ei_aligned_stack_delete(Scalar, _res, res.size());
}
}
@@ -592,9 +606,12 @@ struct ei_cache_friendly_product_selector<ProductType,1,LhsOrder,LhsAccess,RhsCo
template<typename DestDerived>
inline static void run(DestDerived& res, const ProductType& product)
{
const int cols = product.lhs().cols();
typename ProductType::LhsNestedX lhs(product.lhs());
typename ProductType::RhsNestedX rhs(product.rhs());
const int cols = lhs.cols();
for (int j=0; j<cols; ++j)
res += product.lhs().coeff(j) * product.rhs().row(j);
res += lhs.coeff(j) * rhs.row(j);
}
};
@@ -608,6 +625,9 @@ struct ei_cache_friendly_product_selector<ProductType,1,LhsOrder,LhsAccess,RhsCo
template<typename DestDerived>
inline static void run(DestDerived& res, const ProductType& product)
{
typename ProductType::LhsNestedX lhs(product.lhs());
typename ProductType::RhsNestedX rhs(product.rhs());
enum {
EvalToRes = (ei_packet_traits<Scalar>::size==1)
||((DestDerived::Flags & ActualPacketAccessBit) && (DestDerived::Flags & RowMajorBit)) };
@@ -617,15 +637,15 @@ struct ei_cache_friendly_product_selector<ProductType,1,LhsOrder,LhsAccess,RhsCo
else
{
_res = ei_aligned_stack_new(Scalar, res.size());
Map<Matrix<Scalar,DestDerived::SizeAtCompileTime,1> >(_res, res.size()) = res;
Map<Matrix<Scalar,1,DestDerived::SizeAtCompileTime,ColMajor> >(_res, res.size()) = res;
}
ei_cache_friendly_product_colmajor_times_vector(res.size(),
&product.rhs().const_cast_derived().coeffRef(0,0), product.rhs().stride(),
product.lhs().transpose(), _res);
&rhs.const_cast_derived().coeffRef(0,0), rhs.stride(),
lhs.transpose(), _res);
if (!EvalToRes)
{
res = Map<Matrix<Scalar,DestDerived::SizeAtCompileTime,1> >(_res, res.size());
res = Map<Matrix<Scalar,1,DestDerived::SizeAtCompileTime,ColMajor> >(_res, res.size());
ei_aligned_stack_delete(Scalar, _res, res.size());
}
}
@@ -638,24 +658,28 @@ struct ei_cache_friendly_product_selector<ProductType,LhsRows,RowMajor,HasDirect
typedef typename ProductType::Scalar Scalar;
typedef typename ei_traits<ProductType>::_RhsNested Rhs;
enum {
UseRhsDirectly = ((ei_packet_traits<Scalar>::size==1) || (Rhs::Flags&ActualPacketAccessBit))
&& (!(Rhs::Flags & RowMajorBit)) };
UseRhsDirectly = ((ei_packet_traits<Scalar>::size==1) || (ProductType::RhsNestedFlags&ActualPacketAccessBit))
&& (ProductType::RhsNestedFlags&DirectAccessBit)
&& (!(ProductType::RhsNestedFlags & RowMajorBit)) };
template<typename DestDerived>
inline static void run(DestDerived& res, const ProductType& product)
{
typename ProductType::LhsNestedX lhs(product.lhs());
typename ProductType::RhsNestedX rhs(product.rhs());
Scalar* EIGEN_RESTRICT _rhs;
if (UseRhsDirectly)
_rhs = &product.rhs().const_cast_derived().coeffRef(0);
_rhs = &rhs.const_cast_derived().coeffRef(0);
else
{
_rhs = ei_aligned_stack_new(Scalar, product.rhs().size());
Map<Matrix<Scalar,Rhs::SizeAtCompileTime,1> >(_rhs, product.rhs().size()) = product.rhs();
_rhs = ei_aligned_stack_new(Scalar, rhs.size());
Map<Matrix<Scalar,Rhs::SizeAtCompileTime,1,ColMajor> >(_rhs, rhs.size()) = rhs;
}
ei_cache_friendly_product_rowmajor_times_vector(&product.lhs().const_cast_derived().coeffRef(0,0), product.lhs().stride(),
_rhs, product.rhs().size(), res);
ei_cache_friendly_product_rowmajor_times_vector(&lhs.const_cast_derived().coeffRef(0,0), lhs.stride(),
_rhs, rhs.size(), res);
if (!UseRhsDirectly) ei_aligned_stack_delete(Scalar, _rhs, product.rhs().size());
if (!UseRhsDirectly) ei_aligned_stack_delete(Scalar, _rhs, rhs.size());
}
};
@@ -666,24 +690,28 @@ struct ei_cache_friendly_product_selector<ProductType,1,LhsOrder,LhsAccess,RhsCo
typedef typename ProductType::Scalar Scalar;
typedef typename ei_traits<ProductType>::_LhsNested Lhs;
enum {
UseLhsDirectly = ((ei_packet_traits<Scalar>::size==1) || (Lhs::Flags&ActualPacketAccessBit))
&& (Lhs::Flags & RowMajorBit) };
UseLhsDirectly = ((ei_packet_traits<Scalar>::size==1) || (ProductType::LhsNestedFlags&ActualPacketAccessBit))
&& (ProductType::LhsNestedFlags&DirectAccessBit)
&& (ProductType::LhsNestedFlags & RowMajorBit) };
template<typename DestDerived>
inline static void run(DestDerived& res, const ProductType& product)
{
typename ProductType::LhsNestedX lhs(product.lhs());
typename ProductType::RhsNestedX rhs(product.rhs());
Scalar* EIGEN_RESTRICT _lhs;
if (UseLhsDirectly)
_lhs = &product.lhs().const_cast_derived().coeffRef(0);
_lhs = &lhs.const_cast_derived().coeffRef(0);
else
{
_lhs = ei_aligned_stack_new(Scalar, product.lhs().size());
Map<Matrix<Scalar,Lhs::SizeAtCompileTime,1> >(_lhs, product.lhs().size()) = product.lhs();
_lhs = ei_aligned_stack_new(Scalar, lhs.size());
Map<Matrix<Scalar,1,Lhs::SizeAtCompileTime,ColMajor> >(_lhs, lhs.size()) = lhs;
}
ei_cache_friendly_product_rowmajor_times_vector(&product.rhs().const_cast_derived().coeffRef(0,0), product.rhs().stride(),
_lhs, product.lhs().size(), res);
ei_cache_friendly_product_rowmajor_times_vector(&rhs.const_cast_derived().coeffRef(0,0), rhs.stride(),
_lhs, lhs.size(), res);
if(!UseLhsDirectly) ei_aligned_stack_delete(Scalar, _lhs, product.lhs().size());
if(!UseLhsDirectly) ei_aligned_stack_delete(Scalar, _lhs, lhs.size());
}
};
@@ -709,7 +737,17 @@ MatrixBase<Derived>::operator+=(const Flagged<Product<Lhs,Rhs,CacheFriendlyProdu
if (other._expression()._useCacheFriendlyProduct())
ei_cache_friendly_product_selector<Product<Lhs,Rhs,CacheFriendlyProduct> >::run(const_cast_derived(), other._expression());
else
lazyAssign(derived() + other._expression());
{
typedef typename ei_cleantype<Lhs>::type _Lhs;
typedef typename ei_cleantype<Rhs>::type _Rhs;
typedef typename ei_nested<_Lhs,_Rhs::ColsAtCompileTime>::type LhsNested;
typedef typename ei_nested<_Rhs,_Lhs::RowsAtCompileTime>::type RhsNested;
Product<LhsNested,RhsNested,NormalProduct> prod(other._expression().lhs(),other._expression().rhs());
lazyAssign(derived() + prod);
}
return derived();
}
@@ -724,12 +762,21 @@ inline Derived& MatrixBase<Derived>::lazyAssign(const Product<Lhs,Rhs,CacheFrien
}
else
{
lazyAssign<Product<Lhs,Rhs,CacheFriendlyProduct> >(product);
typedef typename ei_cleantype<Lhs>::type _Lhs;
typedef typename ei_cleantype<Rhs>::type _Rhs;
typedef typename ei_nested<_Lhs,_Rhs::ColsAtCompileTime>::type LhsNested;
typedef typename ei_nested<_Rhs,_Lhs::RowsAtCompileTime>::type RhsNested;
typedef Product<LhsNested,RhsNested,NormalProduct> NormalProduct;
NormalProduct normal_prod(product.lhs(),product.rhs());
lazyAssign<NormalProduct>(normal_prod);
}
return derived();
}
template<typename T> struct ei_product_copy_rhs
template<typename T,int StorageOrder> struct ei_product_copy_rhs
{
typedef typename ei_meta_if<
(ei_traits<T>::Flags & RowMajorBit)
@@ -739,11 +786,30 @@ template<typename T> struct ei_product_copy_rhs
>::ret type;
};
template<typename T> struct ei_product_copy_lhs
template<typename T> struct ei_product_copy_rhs<T,RowMajorBit>
{
typedef typename ei_meta_if<
(!(ei_traits<T>::Flags & DirectAccessBit)),
typename ei_plain_matrix_type<T>::type,
const T&
>::ret type;
};
template<typename T,int StorageOrder> struct ei_product_copy_lhs
{
typedef typename ei_meta_if<
(!(int(ei_traits<T>::Flags) & DirectAccessBit)),
typename ei_plain_matrix_type<T>::type,
typename ei_plain_matrix_type_row_major<T>::type,
const T&
>::ret type;
};
template<typename T> struct ei_product_copy_lhs<T,RowMajorBit>
{
typedef typename ei_meta_if<
((ei_traits<T>::Flags & RowMajorBit)==0)
|| (!(int(ei_traits<T>::Flags) & DirectAccessBit)),
typename ei_plain_matrix_type_row_major<T>::type,
const T&
>::ret type;
};
@@ -752,9 +818,9 @@ template<typename Lhs, typename Rhs, int ProductMode>
template<typename DestDerived>
inline void Product<Lhs,Rhs,ProductMode>::_cacheFriendlyEvalAndAdd(DestDerived& res) const
{
typedef typename ei_product_copy_lhs<_LhsNested>::type LhsCopy;
typedef typename ei_product_copy_lhs<_LhsNested,DestDerived::Flags&RowMajorBit>::type LhsCopy;
typedef typename ei_unref<LhsCopy>::type _LhsCopy;
typedef typename ei_product_copy_rhs<_RhsNested>::type RhsCopy;
typedef typename ei_product_copy_rhs<_RhsNested,DestDerived::Flags&RowMajorBit>::type RhsCopy;
typedef typename ei_unref<RhsCopy>::type _RhsCopy;
LhsCopy lhs(m_lhs);
RhsCopy rhs(m_rhs);
@@ -764,6 +830,7 @@ inline void Product<Lhs,Rhs,ProductMode>::_cacheFriendlyEvalAndAdd(DestDerived&
_RhsCopy::Flags&RowMajorBit, (const Scalar*)&(rhs.const_cast_derived().coeffRef(0,0)), rhs.stride(),
DestDerived::Flags&RowMajorBit, (Scalar*)&(res.coeffRef(0,0)), res.stride()
);
}
#endif // EIGEN_PRODUCT_H

View File

@@ -35,7 +35,7 @@ template<typename Lhs, typename Rhs,
? UpperTriangular
: -1,
int StorageOrder = ei_is_part<Lhs>::value ? -1 // this is to solve ambiguous specializations
: int(Lhs::Flags) & (RowMajorBit|SparseBit)
: int(Lhs::Flags) & int(RowMajorBit|SparseBit)
>
struct ei_solve_triangular_selector;

View File

@@ -117,6 +117,9 @@ template<typename ExpressionType> class SwapWrapper
protected:
ExpressionType& m_expression;
private:
SwapWrapper& operator=(const SwapWrapper&);
};
/** swaps *this with the expression \a other.

View File

@@ -69,7 +69,6 @@ template<typename MatrixType> class 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 Scalar& coeffRef(int row, int col)

View File

@@ -164,7 +164,7 @@ struct ei_functor_traits<ei_max_coeff_visitor<Scalar> > {
/** \returns the minimum of all coefficients of *this
* and puts in *row and *col its location.
*
* \sa MatrixBase::maxCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::minCoeff()
* \sa MatrixBase::minCoeff(int*), MatrixBase::maxCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::minCoeff()
*/
template<typename Derived>
typename ei_traits<Derived>::Scalar
@@ -177,6 +177,22 @@ MatrixBase<Derived>::minCoeff(int* row, int* col) const
return minVisitor.res;
}
/** \returns the minimum of all coefficients of *this
* and puts in *index its location.
*
* \sa MatrixBase::minCoeff(int*,int*), MatrixBase::maxCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::minCoeff()
*/
template<typename Derived>
typename ei_traits<Derived>::Scalar
MatrixBase<Derived>::minCoeff(int* index) const
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
ei_min_coeff_visitor<Scalar> minVisitor;
this->visit(minVisitor);
*index = (RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row;
return minVisitor.res;
}
/** \returns the maximum of all coefficients of *this
* and puts in *row and *col its location.
*
@@ -193,5 +209,20 @@ MatrixBase<Derived>::maxCoeff(int* row, int* col) const
return maxVisitor.res;
}
/** \returns the maximum of all coefficients of *this
* and puts in *index its location.
*
* \sa MatrixBase::maxCoeff(int*,int*), MatrixBase::minCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::maxCoeff()
*/
template<typename Derived>
typename ei_traits<Derived>::Scalar
MatrixBase<Derived>::maxCoeff(int* index) const
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
ei_max_coeff_visitor<Scalar> maxVisitor;
this->visit(maxVisitor);
*index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
return maxVisitor.res;
}
#endif // EIGEN_VISITOR_H

View File

@@ -114,9 +114,15 @@ template<> EIGEN_STRONG_INLINE void ei_pstoreu<float>(float* to, const __m128&
template<> EIGEN_STRONG_INLINE void ei_pstoreu<double>(double* to, const __m128d& from) { _mm_storeu_pd(to, from); }
template<> EIGEN_STRONG_INLINE void ei_pstoreu<int>(int* to, const __m128i& from) { _mm_storeu_si128(reinterpret_cast<__m128i*>(to), from); }
#ifdef _MSC_VER
// this fix internal compilation error
template<> EIGEN_STRONG_INLINE float ei_pfirst<__m128>(const __m128& a) { float x = _mm_cvtss_f32(a); return x; }
#if defined(_MSC_VER) && (_MSC_VER <= 1500) && defined(_WIN64) && !defined(__INTEL_COMPILER)
// The temporary variable fixes an internal compilation error.
// Direct of the struct members fixed bug #62.
template<> EIGEN_STRONG_INLINE float ei_pfirst<__m128>(const __m128& a) { return a.m128_f32[0]; }
template<> EIGEN_STRONG_INLINE double ei_pfirst<__m128d>(const __m128d& a) { return a.m128d_f64[0]; }
template<> EIGEN_STRONG_INLINE int ei_pfirst<__m128i>(const __m128i& a) { int x = _mm_cvtsi128_si32(a); return x; }
#elif defined(_MSC_VER) && (_MSC_VER <= 1500) && !defined(__INTEL_COMPILER)
// The temporary variable fixes an internal compilation error.
template<> EIGEN_STRONG_INLINE float ei_pfirst<__m128>(const __m128& a) { float x = _mm_cvtss_f32(a); return x; }
template<> EIGEN_STRONG_INLINE double ei_pfirst<__m128d>(const __m128d& a) { double x = _mm_cvtsd_f64(a); return x; }
template<> EIGEN_STRONG_INLINE int ei_pfirst<__m128i>(const __m128i& a) { int x = _mm_cvtsi128_si32(a); return x; }
#else
@@ -315,4 +321,7 @@ struct ei_palign_impl<Offset,__m128d>
};
#endif
#define ei_vec4f_swizzle1(v,p,q,r,s) \
(_mm_castsi128_ps(_mm_shuffle_epi32( _mm_castps_si128(v), ((s)<<6|(r)<<4|(q)<<2|(p)))))
#endif // EIGEN_PACKET_MATH_SSE_H

View File

@@ -239,4 +239,16 @@ enum {
HasDirectAccess = DirectAccessBit
};
const int EiArch_Generic = 0x0;
const int EiArch_SSE = 0x1;
const int EiArch_AltiVec = 0x2;
#if defined EIGEN_VECTORIZE_SSE
const int EiArch = EiArch_SSE;
#elif defined EIGEN_VECTORIZE_ALTIVEC
const int EiArch = EiArch_AltiVec;
#else
const int EiArch = EiArch_Generic;
#endif
#endif // EIGEN_CONSTANTS_H

View File

@@ -30,30 +30,48 @@
#define EIGEN_WORLD_VERSION 2
#define EIGEN_MAJOR_VERSION 0
#define EIGEN_MINOR_VERSION 5
#define EIGEN_MINOR_VERSION 17
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
EIGEN_MINOR_VERSION>=z))))
// if the compiler is GNUC, disable 16 byte alignment on exotic archs that probably don't need it, and on which
// it may be extra trouble to get aligned memory allocation to work (example: on ARM, overloading new[] is a PITA
// because extra memory must be allocated for bookkeeping).
// if the compiler is not GNUC, just cross fingers that the architecture isn't too exotic, because we don't want
// to keep track of all the different preprocessor symbols for all compilers.
#if !defined(__GNUC__) || defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__ia64__)
// 16 byte alignment is only useful for vectorization. Since it affects the ABI, we need to enable 16 byte alignment on all
// platforms where vectorization might be enabled. In theory we could always enable alignment, but it can be a cause of problems
// on some platforms, so we just disable it in certain common platform (compiler+architecture combinations) to avoid these problems.
#if defined(__GNUC__) && !(defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || defined(__ppc__) || defined(__ia64__))
#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_ALIGNMENT 1
#else
#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_ALIGNMENT 0
#endif
#if defined(__GNUC__) && (__GNUC__ <= 3)
#define EIGEN_GCC3_OR_OLDER 1
#else
#define EIGEN_GCC3_OR_OLDER 0
#endif
// FIXME vectorization + alignment is completely disabled with sun studio
#if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_ALIGNMENT && !EIGEN_GCC3_OR_OLDER && !defined(__SUNPRO_CC) && !defined(__QNXNTO__)
#define EIGEN_ARCH_WANTS_ALIGNMENT 1
#else
#ifdef EIGEN_VECTORIZE
#error Vectorization enabled, but the architecture is not listed among those for which we require 16 byte alignment. If you added vectorization for another architecture, you also need to edit this list.
#endif
#define EIGEN_ARCH_WANTS_ALIGNMENT 0
#endif
// EIGEN_ALIGN is the true test whether we want to align or not. It takes into account both the user choice to explicitly disable
// alignment (EIGEN_DONT_ALIGN) and the architecture config (EIGEN_ARCH_WANTS_ALIGNMENT). Henceforth, only EIGEN_ALIGN should be used.
#if EIGEN_ARCH_WANTS_ALIGNMENT && !defined(EIGEN_DONT_ALIGN)
#define EIGEN_ALIGN 1
#else
#define EIGEN_ALIGN 0
#ifdef EIGEN_VECTORIZE
#error "Vectorization enabled, but our platform checks say that we don't do 16 byte alignment on this platform. If you added vectorization for another architecture, you also need to edit this platform check."
#endif
#ifndef EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
#define EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
#endif
#endif
#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION RowMajor
#else
@@ -165,7 +183,7 @@ using Eigen::ei_cos;
* If we made alignment depend on whether or not EIGEN_VECTORIZE is defined, it would be impossible to link
* vectorized and non-vectorized code.
*/
#if !EIGEN_ARCH_WANTS_ALIGNMENT
#if !EIGEN_ALIGN
#define EIGEN_ALIGN_128
#elif (defined __GNUC__)
#define EIGEN_ALIGN_128 __attribute__((aligned(16)))
@@ -175,7 +193,12 @@ using Eigen::ei_cos;
#error Please tell me what is the equivalent of __attribute__((aligned(16))) for your compiler
#endif
#define EIGEN_RESTRICT __restrict
#ifdef EIGEN_DONT_USE_RESTRICT_KEYWORD
#define EIGEN_RESTRICT
#endif
#ifndef EIGEN_RESTRICT
#define EIGEN_RESTRICT __restrict
#endif
#ifndef EIGEN_STACK_ALLOCATION_LIMIT
#define EIGEN_STACK_ALLOCATION_LIMIT 1000000
@@ -234,6 +257,9 @@ enum { RowsAtCompileTime = Eigen::ei_traits<Derived>::RowsAtCompileTime, \
_EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, Eigen::MatrixBase<Derived>)
#define EIGEN_ENUM_MIN(a,b) (((int)a <= (int)b) ? (int)a : (int)b)
#define EIGEN_SIZE_MIN(a,b) (((int)a == 1 || (int)b == 1) ? 1 \
: ((int)a == Dynamic || (int)b == Dynamic) ? Dynamic \
: ((int)a <= (int)b) ? (int)a : (int)b)
#define EIGEN_ENUM_MAX(a,b) (((int)a >= (int)b) ? (int)a : (int)b)
// just an empty macro !

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 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
@@ -27,13 +27,23 @@
#ifndef EIGEN_MEMORY_H
#define EIGEN_MEMORY_H
#if defined(__APPLE__) || defined(_WIN64)
// FreeBSD 6 seems to have 16-byte aligned malloc
// See http://svn.freebsd.org/viewvc/base/stable/6/lib/libc/stdlib/malloc.c?view=markup
// FreeBSD 7 seems to have 16-byte aligned malloc except on ARM and MIPS architectures
// See http://svn.freebsd.org/viewvc/base/stable/7/lib/libc/stdlib/malloc.c?view=markup
#if defined(__FreeBSD__) && !defined(__arm__) && !defined(__mips__)
#define EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED 1
#else
#define EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED 0
#endif
#if defined(__APPLE__) || defined(_WIN64) || EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED
#define EIGEN_MALLOC_ALREADY_ALIGNED 1
#else
#define EIGEN_MALLOC_ALREADY_ALIGNED 0
#endif
#if ((defined _GNU_SOURCE) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0)
#if (defined __QNXNTO__) || (((defined _GNU_SOURCE) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0))
#define EIGEN_HAS_POSIX_MEMALIGN 1
#else
#define EIGEN_HAS_POSIX_MEMALIGN 0
@@ -49,10 +59,10 @@
* Fast, but wastes 16 additional bytes of memory.
* Does not throw any exception.
*/
inline void* ei_handmade_aligned_malloc(size_t size)
inline void* ei_handmade_aligned_malloc(std::size_t size)
{
void *original = malloc(size+16);
void *aligned = reinterpret_cast<void*>((reinterpret_cast<size_t>(original) & ~(size_t(15))) + 16);
void *original = std::malloc(size+16);
void *aligned = reinterpret_cast<void*>((reinterpret_cast<std::size_t>(original) & ~(std::size_t(15))) + 16);
*(reinterpret_cast<void**>(aligned) - 1) = original;
return aligned;
}
@@ -61,94 +71,96 @@ inline void* ei_handmade_aligned_malloc(size_t size)
inline void ei_handmade_aligned_free(void *ptr)
{
if(ptr)
free(*(reinterpret_cast<void**>(ptr) - 1));
std::free(*(reinterpret_cast<void**>(ptr) - 1));
}
/** \internal allocates \a size bytes. The returned pointer is guaranteed to have 16 bytes alignment.
* On allocation error, the returned pointer is undefined, but if exceptions are enabled then a std::bad_alloc is thrown.
* On allocation error, the returned pointer is null, and if exceptions are enabled then a std::bad_alloc is thrown.
*/
inline void* ei_aligned_malloc(size_t size)
inline void* ei_aligned_malloc(std::size_t size)
{
#ifdef EIGEN_NO_MALLOC
ei_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)");
#endif
void *result;
#if EIGEN_HAS_POSIX_MEMALIGN && EIGEN_ARCH_WANTS_ALIGNMENT && !EIGEN_MALLOC_ALREADY_ALIGNED
#ifdef EIGEN_EXCEPTIONS
const int failed =
#endif
posix_memalign(&result, 16, size);
void *result;
#if !EIGEN_ALIGN
result = std::malloc(size);
#elif EIGEN_MALLOC_ALREADY_ALIGNED
result = std::malloc(size);
#elif EIGEN_HAS_POSIX_MEMALIGN
if(posix_memalign(&result, 16, size)) result = 0;
#elif EIGEN_HAS_MM_MALLOC
result = _mm_malloc(size, 16);
#elif (defined _MSC_VER)
result = _aligned_malloc(size, 16);
#else
#if !EIGEN_ARCH_WANTS_ALIGNMENT
result = malloc(size);
#elif EIGEN_MALLOC_ALREADY_ALIGNED
result = malloc(size);
#elif EIGEN_HAS_MM_MALLOC
result = _mm_malloc(size, 16);
#elif (defined _MSC_VER)
result = _aligned_malloc(size, 16);
#else
result = ei_handmade_aligned_malloc(size);
#endif
#ifdef EIGEN_EXCEPTIONS
const int failed = (result == 0);
#endif
result = ei_handmade_aligned_malloc(size);
#endif
#ifdef EIGEN_EXCEPTIONS
if(failed)
if(result == 0)
throw std::bad_alloc();
#endif
return result;
}
/** allocates \a size bytes. If Align is true, then the returned ptr is 16-byte-aligned.
* On allocation error, the returned pointer is undefined, but if exceptions are enabled then a std::bad_alloc is thrown.
* On allocation error, the returned pointer is null, and if exceptions are enabled then a std::bad_alloc is thrown.
*/
template<bool Align> inline void* ei_conditional_aligned_malloc(size_t size)
template<bool Align> inline void* ei_conditional_aligned_malloc(std::size_t size)
{
return ei_aligned_malloc(size);
}
template<> inline void* ei_conditional_aligned_malloc<false>(size_t size)
template<> inline void* ei_conditional_aligned_malloc<false>(std::size_t size)
{
#ifdef EIGEN_NO_MALLOC
ei_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)");
#endif
void *result = malloc(size);
void *result = std::malloc(size);
#ifdef EIGEN_EXCEPTIONS
if(!result) throw std::bad_alloc();
#endif
return result;
}
/** \internal construct the elements of an array.
* The \a size parameter tells on how many objects to call the constructor of T.
*/
template<typename T> inline T* ei_construct_elements_of_array(T *ptr, std::size_t size)
{
for (std::size_t i=0; i < size; ++i) ::new (ptr + i) T;
return ptr;
}
/** allocates \a size objects of type T. The returned pointer is guaranteed to have 16 bytes alignment.
* On allocation error, the returned pointer is undefined, but if exceptions are enabled then a std::bad_alloc is thrown.
* The default constructor of T is called.
*/
template<typename T> inline T* ei_aligned_new(size_t size)
template<typename T> inline T* ei_aligned_new(std::size_t size)
{
void *void_result = ei_aligned_malloc(sizeof(T)*size);
return ::new(void_result) T[size];
T *result = reinterpret_cast<T*>(ei_aligned_malloc(sizeof(T)*size));
return ei_construct_elements_of_array(result, size);
}
template<typename T, bool Align> inline T* ei_conditional_aligned_new(size_t size)
template<typename T, bool Align> inline T* ei_conditional_aligned_new(std::size_t size)
{
void *void_result = ei_conditional_aligned_malloc<Align>(sizeof(T)*size);
return ::new(void_result) T[size];
T *result = reinterpret_cast<T*>(ei_conditional_aligned_malloc<Align>(sizeof(T)*size));
return ei_construct_elements_of_array(result, size);
}
/** \internal free memory allocated with ei_aligned_malloc
*/
inline void ei_aligned_free(void *ptr)
{
#if !EIGEN_ARCH_WANTS_ALIGNMENT
free(ptr);
#if !EIGEN_ALIGN
std::free(ptr);
#elif EIGEN_MALLOC_ALREADY_ALIGNED
free(ptr);
std::free(ptr);
#elif EIGEN_HAS_POSIX_MEMALIGN
free(ptr);
std::free(ptr);
#elif EIGEN_HAS_MM_MALLOC
_mm_free(ptr);
#elif defined(_MSC_VER)
@@ -167,48 +179,78 @@ template<bool Align> inline void ei_conditional_aligned_free(void *ptr)
template<> inline void ei_conditional_aligned_free<false>(void *ptr)
{
free(ptr);
std::free(ptr);
}
/** \internal delete the elements of an array.
/** \internal destruct the elements of an array.
* The \a size parameters tells on how many objects to call the destructor of T.
*/
template<typename T> inline void ei_delete_elements_of_array(T *ptr, size_t size)
template<typename T> inline void ei_destruct_elements_of_array(T *ptr, std::size_t size)
{
// always destruct an array starting from the end.
while(size) ptr[--size].~T();
if(ptr)
while(size) ptr[--size].~T();
}
/** \internal delete objects constructed with ei_aligned_new
* The \a size parameters tells on how many objects to call the destructor of T.
*/
template<typename T> inline void ei_aligned_delete(T *ptr, size_t size)
template<typename T> inline void ei_aligned_delete(T *ptr, std::size_t size)
{
ei_delete_elements_of_array<T>(ptr, size);
ei_destruct_elements_of_array<T>(ptr, size);
ei_aligned_free(ptr);
}
/** \internal delete objects constructed with ei_conditional_aligned_new
* The \a size parameters tells on how many objects to call the destructor of T.
*/
template<typename T, bool Align> inline void ei_conditional_aligned_delete(T *ptr, size_t size)
template<typename T, bool Align> inline void ei_conditional_aligned_delete(T *ptr, std::size_t size)
{
ei_delete_elements_of_array<T>(ptr, size);
ei_destruct_elements_of_array<T>(ptr, size);
ei_conditional_aligned_free<Align>(ptr);
}
/** \internal \returns the number of elements which have to be skipped such that data are 16 bytes aligned */
template<typename Scalar>
inline static int ei_alignmentOffset(const Scalar* ptr, int maxOffset)
/** \internal \returns the index of the first element of the array that is well aligned for vectorization.
*
* \param array the address of the start of the array
* \param size the size of the array
*
* \note If no element of the array is well aligned, the size of the array is returned. Typically,
* for example with SSE, "well aligned" means 16-byte-aligned. If vectorization is disabled or if the
* packet size for the given scalar type is 1, then everything is considered well-aligned.
*
* \note If the scalar type is vectorizable, we rely on the following assumptions: sizeof(Scalar) is a
* power of 2, the packet size in bytes is also a power of 2, and is a multiple of sizeof(Scalar). On the
* other hand, we do not assume that the array address is a multiple of sizeof(Scalar), as that fails for
* example with Scalar=double on certain 32-bit platforms, see bug #79.
*
* There is also the variant ei_first_aligned(const MatrixBase&, Integer) defined in Coeffs.h.
*/
template<typename Scalar, typename Integer>
inline static Integer ei_alignmentOffset(const Scalar* array, Integer size)
{
typedef typename ei_packet_traits<Scalar>::type Packet;
const int PacketSize = ei_packet_traits<Scalar>::size;
const int PacketAlignedMask = PacketSize-1;
const bool Vectorized = PacketSize>1;
return Vectorized
? std::min<int>( (PacketSize - (int((size_t(ptr)/sizeof(Scalar))) & PacketAlignedMask))
& PacketAlignedMask, maxOffset)
: 0;
enum { PacketSize = ei_packet_traits<Scalar>::size,
PacketAlignedMask = PacketSize-1
};
if(PacketSize==1)
{
// Either there is no vectorization, or a packet consists of exactly 1 scalar so that all elements
// of the array have the same aligment.
return 0;
}
else if(std::size_t(array) & (sizeof(Scalar)-1))
{
// There is vectorization for this scalar type, but the array is not aligned to the size of a single scalar.
// Consequently, no element of the array is well aligned.
return size;
}
else
{
return std::min<Integer>( (PacketSize - (Integer((std::size_t(array)/sizeof(Scalar))) & PacketAlignedMask))
& PacketAlignedMask, size);
}
}
/** \internal
@@ -232,31 +274,31 @@ inline static int ei_alignmentOffset(const Scalar* ptr, int maxOffset)
#define ei_aligned_stack_free(PTR,SIZE) ei_aligned_free(PTR)
#endif
#define ei_aligned_stack_new(TYPE,SIZE) ::new(ei_aligned_stack_alloc(sizeof(TYPE)*SIZE)) TYPE[SIZE]
#define ei_aligned_stack_delete(TYPE,PTR,SIZE) do {ei_delete_elements_of_array<TYPE>(PTR, SIZE); \
#define ei_aligned_stack_new(TYPE,SIZE) ei_construct_elements_of_array(reinterpret_cast<TYPE*>(ei_aligned_stack_alloc(sizeof(TYPE)*SIZE)), SIZE)
#define ei_aligned_stack_delete(TYPE,PTR,SIZE) do {ei_destruct_elements_of_array<TYPE>(PTR, SIZE); \
ei_aligned_stack_free(PTR,sizeof(TYPE)*SIZE);} while(0)
#if EIGEN_ARCH_WANTS_ALIGNMENT
#if EIGEN_ALIGN
#ifdef EIGEN_EXCEPTIONS
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
void* operator new(size_t size, const std::nothrow_t&) throw() { \
void* operator new(std::size_t size, const std::nothrow_t&) throw() { \
try { return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); } \
catch (...) { return 0; } \
return 0; \
}
#else
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
void* operator new(size_t size, const std::nothrow_t&) throw() { \
void* operator new(std::size_t size, const std::nothrow_t&) throw() { \
return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); \
}
#endif
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) \
void *operator new(size_t size) { \
void *operator new(std::size_t size) { \
return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); \
} \
void *operator new[](size_t size) { \
void *operator new[](std::size_t size) { \
return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); \
} \
void operator delete(void * ptr) throw() { Eigen::ei_conditional_aligned_free<NeedsToAlign>(ptr); } \
@@ -264,7 +306,7 @@ inline static int ei_alignmentOffset(const Scalar* ptr, int maxOffset)
/* in-place new and delete. since (at least afaik) there is no actual */ \
/* memory allocated we can safely let the default implementation handle */ \
/* this particular case. */ \
static void *operator new(size_t size, void *ptr) { return ::operator new(size,ptr); } \
static void *operator new(std::size_t size, void *ptr) { return ::operator new(size,ptr); } \
void operator delete(void * memory, void *ptr) throw() { return ::operator delete(memory,ptr); } \
/* nothrow-new (returns zero instead of std::bad_alloc) */ \
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
@@ -298,8 +340,8 @@ template<class T>
class aligned_allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
@@ -344,7 +386,7 @@ public:
return std::numeric_limits<size_type>::max();
}
pointer allocate( size_type num, const_pointer* hint = 0 )
pointer allocate( size_type num, const void* hint = 0 )
{
static_cast<void>( hint ); // suppress unused variable warning
return static_cast<pointer>( ei_aligned_malloc( num * sizeof(T) ) );

View File

@@ -74,6 +74,7 @@
THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES,
THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES,
INVALID_MATRIX_TEMPLATE_PARAMETERS,
INVALID_MATRIXBASE_TEMPLATE_PARAMETERS,
BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER,
THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX
};

View File

@@ -37,6 +37,10 @@
//classes inheriting ei_no_assignment_operator don't generate a default operator=.
class ei_no_assignment_operator
{
#if EIGEN_GCC3_OR_OLDER
protected:
void nevermind_this_is_just_to_work_around_a_stupid_gcc3_warning();
#endif
private:
ei_no_assignment_operator& operator=(const ei_no_assignment_operator&);
};
@@ -90,10 +94,16 @@ class ei_compute_matrix_flags
{
enum {
row_major_bit = Options&RowMajor ? RowMajorBit : 0,
inner_max_size = row_major_bit ? MaxCols : MaxRows,
inner_max_size = int(MaxRows==1) ? int(MaxCols)
: int(MaxCols==1) ? int(MaxRows)
: int(row_major_bit) ? int(MaxCols) : int(MaxRows),
is_big = inner_max_size == Dynamic,
is_packet_size_multiple = (Cols*Rows) % ei_packet_traits<Scalar>::size == 0,
aligned_bit = ((Options&AutoAlign) && (is_big || is_packet_size_multiple)) ? AlignedBit : 0,
storage_has_fixed_size = MaxRows != Dynamic && MaxCols != Dynamic,
storage_has_aligned_fixed_size = storage_has_fixed_size
&& ( (MaxCols*MaxRows) % ei_packet_traits<Scalar>::size == 0 ),
aligned_bit = ( (Options&AutoAlign)
&& (is_big || storage_has_aligned_fixed_size)
) ? AlignedBit : 0,
packet_access_bit = ei_packet_traits<Scalar>::size > 1 && aligned_bit ? PacketAccessBit : 0
};
@@ -110,7 +120,7 @@ template<int _Rows, int _Cols> struct ei_size_at_compile_time
* in order to avoid a useless copy
*/
template<typename T, int Sparseness = ei_traits<T>::Flags&SparseBit> class ei_eval;
template<typename T, int Sparseness = ei_traits<T>::Flags&SparseBit> struct ei_eval;
template<typename T> struct ei_eval<T,IsDense>
{
@@ -157,6 +167,19 @@ template<typename T> struct ei_plain_matrix_type_column_major
> type;
};
/* ei_plain_matrix_type_row_major : same as ei_plain_matrix_type but guaranteed to be row-major
*/
template<typename T> struct ei_plain_matrix_type_row_major
{
typedef Matrix<typename ei_traits<T>::Scalar,
ei_traits<T>::RowsAtCompileTime,
ei_traits<T>::ColsAtCompileTime,
AutoAlign | RowMajor,
ei_traits<T>::MaxRowsAtCompileTime,
ei_traits<T>::MaxColsAtCompileTime
> type;
};
template<typename T> struct ei_must_nest_by_value { enum { ret = false }; };
template<typename T> struct ei_must_nest_by_value<NestByValue<T> > { enum { ret = true }; };

View File

@@ -52,9 +52,9 @@ public:
typedef _Scalar Scalar;
typedef typename NumTraits<Scalar>::Real RealScalar;
typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType;
typedef Matrix<Scalar,AmbientDimAtCompileTime==Dynamic
typedef Matrix<Scalar,int(AmbientDimAtCompileTime)==Dynamic
? Dynamic
: AmbientDimAtCompileTime+1,1> Coefficients;
: int(AmbientDimAtCompileTime)+1,1> Coefficients;
typedef Block<Coefficients,AmbientDimAtCompileTime,1> NormalReturnType;
/** Default constructor without initialization */

View File

@@ -34,7 +34,7 @@
*
* A parametrized line is defined by an origin point \f$ \mathbf{o} \f$ and a unit
* direction vector \f$ \mathbf{d} \f$ such that the line corresponds to
* the set \f$ l(t) = \mathbf{o} + t \mathbf{d} \f$, \f$ l \in \mathbf{R} \f$.
* the set \f$ l(t) = \mathbf{o} + t \mathbf{d} \f$, \f$ t \in \mathbf{R} \f$.
*
* \param _Scalar the scalar type, i.e., the type of the coefficients
* \param _AmbientDim the dimension of the ambient space, can be a compile time value or Dynamic.

View File

@@ -224,17 +224,45 @@ typedef Quaternion<float> Quaternionf;
* double precision quaternion type */
typedef Quaternion<double> Quaterniond;
// Generic Quaternion * Quaternion product
template<int Arch,typename Scalar> inline Quaternion<Scalar>
ei_quaternion_product(const Quaternion<Scalar>& a, const Quaternion<Scalar>& b)
{
return Quaternion<Scalar>
(
a.w() * b.w() - a.x() * b.x() - a.y() * b.y() - a.z() * b.z(),
a.w() * b.x() + a.x() * b.w() + a.y() * b.z() - a.z() * b.y(),
a.w() * b.y() + a.y() * b.w() + a.z() * b.x() - a.x() * b.z(),
a.w() * b.z() + a.z() * b.w() + a.x() * b.y() - a.y() * b.x()
);
}
#ifdef EIGEN_VECTORIZE_SSE
template<> inline Quaternion<float>
ei_quaternion_product<EiArch_SSE,float>(const Quaternion<float>& _a, const Quaternion<float>& _b)
{
const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0,0,0,0x80000000));
Quaternion<float> res;
__m128 a = _a.coeffs().packet<Aligned>(0);
__m128 b = _b.coeffs().packet<Aligned>(0);
__m128 flip1 = _mm_xor_ps(_mm_mul_ps(ei_vec4f_swizzle1(a,1,2,0,2),
ei_vec4f_swizzle1(b,2,0,1,2)),mask);
__m128 flip2 = _mm_xor_ps(_mm_mul_ps(ei_vec4f_swizzle1(a,3,3,3,1),
ei_vec4f_swizzle1(b,0,1,2,1)),mask);
ei_pstore(&res.x(),
_mm_add_ps(_mm_sub_ps(_mm_mul_ps(a,ei_vec4f_swizzle1(b,3,3,3,3)),
_mm_mul_ps(ei_vec4f_swizzle1(a,2,0,1,0),
ei_vec4f_swizzle1(b,1,2,0,0))),
_mm_add_ps(flip1,flip2)));
return res;
}
#endif
/** \returns the concatenation of two rotations as a quaternion-quaternion product */
template <typename Scalar>
inline Quaternion<Scalar> Quaternion<Scalar>::operator* (const Quaternion& other) const
{
return Quaternion
(
this->w() * other.w() - this->x() * other.x() - this->y() * other.y() - this->z() * other.z(),
this->w() * other.x() + this->x() * other.w() + this->y() * other.z() - this->z() * other.y(),
this->w() * other.y() + this->y() * other.w() + this->z() * other.x() - this->x() * other.z(),
this->w() * other.z() + this->z() * other.w() + this->x() * other.y() - this->y() * other.x()
);
return ei_quaternion_product<EiArch>(*this,other);
}
/** \sa operator*(Quaternion) */
@@ -422,22 +450,31 @@ inline Scalar Quaternion<Scalar>::angularDistance(const Quaternion& other) const
template <typename Scalar>
Quaternion<Scalar> Quaternion<Scalar>::slerp(Scalar t, const Quaternion& other) const
{
static const Scalar one = Scalar(1) - precision<Scalar>();
static const Scalar one = Scalar(1) - machine_epsilon<Scalar>();
Scalar d = this->dot(other);
Scalar absD = ei_abs(d);
Scalar scale0;
Scalar scale1;
if (absD>=one)
return *this;
{
scale0 = Scalar(1) - t;
scale1 = t;
}
else
{
// theta is the angle between the 2 quaternions
Scalar theta = std::acos(absD);
Scalar sinTheta = ei_sin(theta);
// theta is the angle between the 2 quaternions
Scalar theta = std::acos(absD);
Scalar sinTheta = ei_sin(theta);
scale0 = ei_sin( ( Scalar(1) - t ) * theta) / sinTheta;
scale1 = ei_sin( ( t * theta) ) / sinTheta;
if (d<0)
scale1 = -scale1;
}
Scalar scale0 = ei_sin( ( Scalar(1) - t ) * theta) / sinTheta;
Scalar scale1 = ei_sin( ( t * theta) ) / sinTheta;
if (d<0)
scale1 = -scale1;
return Quaternion(scale0 * m_coeffs + scale1 * other.m_coeffs);
return Quaternion<Scalar>(scale0 * coeffs() + scale1 * other.coeffs());
}
// set from a rotation matrix

View File

@@ -198,6 +198,10 @@ public:
/** \sa MatrixBase::setIdentity() */
void setIdentity() { m_matrix.setIdentity(); }
static const typename MatrixType::IdentityReturnType Identity()
{
return MatrixType::Identity();
}
template<typename OtherDerived>
inline Transform& scale(const MatrixBase<OtherDerived> &other);

View File

@@ -29,8 +29,8 @@
*** Part 1 : optimized implementations for fixed-size 2,3,4 cases ***
********************************************************************/
template<typename MatrixType>
void ei_compute_inverse_in_size2_case(const MatrixType& matrix, MatrixType* result)
template<typename XprType, typename MatrixType>
void ei_compute_inverse_in_size2_case(const XprType& matrix, MatrixType* result)
{
typedef typename MatrixType::Scalar Scalar;
const Scalar invdet = Scalar(1) / matrix.determinant();
@@ -54,10 +54,10 @@ bool ei_compute_inverse_in_size2_case_with_check(const XprType& matrix, MatrixTy
return true;
}
template<typename MatrixType>
void ei_compute_inverse_in_size3_case(const MatrixType& matrix, MatrixType* result)
template<typename Derived, typename OtherDerived>
void ei_compute_inverse_in_size3_case(const Derived& matrix, OtherDerived* result)
{
typedef typename MatrixType::Scalar Scalar;
typedef typename Derived::Scalar Scalar;
const Scalar det_minor00 = matrix.minor(0,0).determinant();
const Scalar det_minor10 = matrix.minor(1,0).determinant();
const Scalar det_minor20 = matrix.minor(2,0).determinant();
@@ -75,140 +75,204 @@ void ei_compute_inverse_in_size3_case(const MatrixType& matrix, MatrixType* resu
result->coeffRef(2, 2) = matrix.minor(2,2).determinant() * invdet;
}
template<typename MatrixType>
bool ei_compute_inverse_in_size4_case_helper(const MatrixType& matrix, MatrixType* result)
template<typename Derived, typename OtherDerived, typename Scalar = typename Derived::Scalar>
struct ei_compute_inverse_in_size4_case
{
/* Let's split M into four 2x2 blocks:
* (P Q)
* (R S)
* If P is invertible, with inverse denoted by P_inverse, and if
* (S - R*P_inverse*Q) is also invertible, then the inverse of M is
* (P' Q')
* (R' S')
* where
* S' = (S - R*P_inverse*Q)^(-1)
* P' = P1 + (P1*Q) * S' *(R*P_inverse)
* Q' = -(P_inverse*Q) * S'
* R' = -S' * (R*P_inverse)
*/
typedef Block<MatrixType,2,2> XprBlock22;
typedef typename MatrixBase<XprBlock22>::PlainMatrixType Block22;
Block22 P_inverse;
if(ei_compute_inverse_in_size2_case_with_check(matrix.template block<2,2>(0,0), &P_inverse))
static void run(const Derived& matrix, OtherDerived& result)
{
const Block22 Q = matrix.template block<2,2>(0,2);
const Block22 P_inverse_times_Q = P_inverse * Q;
const XprBlock22 R = matrix.template block<2,2>(2,0);
const Block22 R_times_P_inverse = R * P_inverse;
const Block22 R_times_P_inverse_times_Q = R_times_P_inverse * Q;
const XprBlock22 S = matrix.template block<2,2>(2,2);
const Block22 X = S - R_times_P_inverse_times_Q;
Block22 Y;
ei_compute_inverse_in_size2_case(X, &Y);
result->template block<2,2>(2,2) = Y;
result->template block<2,2>(2,0) = - Y * R_times_P_inverse;
const Block22 Z = P_inverse_times_Q * Y;
result->template block<2,2>(0,2) = - Z;
result->template block<2,2>(0,0) = P_inverse + Z * R_times_P_inverse;
return true;
result.coeffRef(0,0) = matrix.minor(0,0).determinant();
result.coeffRef(1,0) = -matrix.minor(0,1).determinant();
result.coeffRef(2,0) = matrix.minor(0,2).determinant();
result.coeffRef(3,0) = -matrix.minor(0,3).determinant();
result.coeffRef(0,2) = matrix.minor(2,0).determinant();
result.coeffRef(1,2) = -matrix.minor(2,1).determinant();
result.coeffRef(2,2) = matrix.minor(2,2).determinant();
result.coeffRef(3,2) = -matrix.minor(2,3).determinant();
result.coeffRef(0,1) = -matrix.minor(1,0).determinant();
result.coeffRef(1,1) = matrix.minor(1,1).determinant();
result.coeffRef(2,1) = -matrix.minor(1,2).determinant();
result.coeffRef(3,1) = matrix.minor(1,3).determinant();
result.coeffRef(0,3) = -matrix.minor(3,0).determinant();
result.coeffRef(1,3) = matrix.minor(3,1).determinant();
result.coeffRef(2,3) = -matrix.minor(3,2).determinant();
result.coeffRef(3,3) = matrix.minor(3,3).determinant();
result /= (matrix.col(0).cwise()*result.row(0).transpose()).sum();
}
else
{
return false;
}
}
};
template<typename MatrixType>
void ei_compute_inverse_in_size4_case(const MatrixType& matrix, MatrixType* result)
#ifdef EIGEN_VECTORIZE_SSE
// The SSE code for the 4x4 float matrix inverse in this file comes from the file
// ftp://download.intel.com/design/PentiumIII/sml/24504301.pdf
// its copyright information is:
// Copyright (C) 1999 Intel Corporation
// See page ii of that document for legal stuff. Not being lawyers, we just assume
// here that if Intel makes this document publically available, with source code
// and detailed explanations, it's because they want their CPUs to be fed with
// good code, and therefore they presumably don't mind us using it in Eigen.
template<typename Derived, typename OtherDerived>
struct ei_compute_inverse_in_size4_case<Derived, OtherDerived, float>
{
if(ei_compute_inverse_in_size4_case_helper(matrix, result))
static void run(const Derived& matrix, OtherDerived& result)
{
// good ! The topleft 2x2 block was invertible, so the 2x2 blocks approach is successful.
return;
// Variables (Streaming SIMD Extensions registers) which will contain cofactors and, later, the
// lines of the inverted matrix.
__m128 minor0, minor1, minor2, minor3;
// Variables which will contain the lines of the reference matrix and, later (after the transposition),
// the columns of the original matrix.
__m128 row0, row1, row2, row3;
// Temporary variables and the variable that will contain the matrix determinant.
__m128 det, tmp1;
// Matrix transposition
const float *src = matrix.data();
tmp1 = _mm_loadh_pi(_mm_castpd_ps(_mm_load_sd((double*)src)), (__m64*)(src+ 4));
row1 = _mm_loadh_pi(_mm_castpd_ps(_mm_load_sd((double*)(src+8))), (__m64*)(src+12));
row0 = _mm_shuffle_ps(tmp1, row1, 0x88);
row1 = _mm_shuffle_ps(row1, tmp1, 0xDD);
tmp1 = _mm_loadh_pi(_mm_castpd_ps(_mm_load_sd((double*)(src+ 2))), (__m64*)(src+ 6));
row3 = _mm_loadh_pi(_mm_castpd_ps(_mm_load_sd((double*)(src+10))), (__m64*)(src+14));
row2 = _mm_shuffle_ps(tmp1, row3, 0x88);
row3 = _mm_shuffle_ps(row3, tmp1, 0xDD);
// Cofactors calculation. Because in the process of cofactor computation some pairs in three-
// element products are repeated, it is not reasonable to load these pairs anew every time. The
// values in the registers with these pairs are formed using shuffle instruction. Cofactors are
// calculated row by row (4 elements are placed in 1 SP FP SIMD floating point register).
tmp1 = _mm_mul_ps(row2, row3);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
minor0 = _mm_mul_ps(row1, tmp1);
minor1 = _mm_mul_ps(row0, tmp1);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
minor0 = _mm_sub_ps(_mm_mul_ps(row1, tmp1), minor0);
minor1 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor1);
minor1 = _mm_shuffle_ps(minor1, minor1, 0x4E);
// -----------------------------------------------
tmp1 = _mm_mul_ps(row1, row2);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
minor0 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor0);
minor3 = _mm_mul_ps(row0, tmp1);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row3, tmp1));
minor3 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor3);
minor3 = _mm_shuffle_ps(minor3, minor3, 0x4E);
// -----------------------------------------------
tmp1 = _mm_mul_ps(_mm_shuffle_ps(row1, row1, 0x4E), row3);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
row2 = _mm_shuffle_ps(row2, row2, 0x4E);
minor0 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor0);
minor2 = _mm_mul_ps(row0, tmp1);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row2, tmp1));
minor2 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor2);
minor2 = _mm_shuffle_ps(minor2, minor2, 0x4E);
// -----------------------------------------------
tmp1 = _mm_mul_ps(row0, row1);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
minor2 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor2);
minor3 = _mm_sub_ps(_mm_mul_ps(row2, tmp1), minor3);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
minor2 = _mm_sub_ps(_mm_mul_ps(row3, tmp1), minor2);
minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row2, tmp1));
// -----------------------------------------------
tmp1 = _mm_mul_ps(row0, row3);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row2, tmp1));
minor2 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor2);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
minor1 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor1);
minor2 = _mm_sub_ps(minor2, _mm_mul_ps(row1, tmp1));
// -----------------------------------------------
tmp1 = _mm_mul_ps(row0, row2);
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1);
minor1 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor1);
minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row1, tmp1));
tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E);
minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row3, tmp1));
minor3 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor3);
// Evaluation of determinant and its reciprocal value. In the original Intel document,
// 1/det was evaluated using a fast rcpps command with subsequent approximation using
// the Newton-Raphson algorithm. Here, we go for a IEEE-compliant division instead,
// so as to not compromise precision at all.
det = _mm_mul_ps(row0, minor0);
det = _mm_add_ps(_mm_shuffle_ps(det, det, 0x4E), det);
det = _mm_add_ss(_mm_shuffle_ps(det, det, 0xB1), det);
// tmp1= _mm_rcp_ss(det);
// det= _mm_sub_ss(_mm_add_ss(tmp1, tmp1), _mm_mul_ss(det, _mm_mul_ss(tmp1, tmp1)));
det = _mm_div_ss(_mm_set_ss(1.0f), det); // <--- yay, one original line not copied from Intel
det = _mm_shuffle_ps(det, det, 0x00);
// warning, Intel's variable naming is very confusing: now 'det' is 1/det !
// Multiplication of cofactors by 1/det. Storing the inverse matrix to the address in pointer src.
minor0 = _mm_mul_ps(det, minor0);
float *dst = result.data();
_mm_storel_pi((__m64*)(dst), minor0);
_mm_storeh_pi((__m64*)(dst+2), minor0);
minor1 = _mm_mul_ps(det, minor1);
_mm_storel_pi((__m64*)(dst+4), minor1);
_mm_storeh_pi((__m64*)(dst+6), minor1);
minor2 = _mm_mul_ps(det, minor2);
_mm_storel_pi((__m64*)(dst+ 8), minor2);
_mm_storeh_pi((__m64*)(dst+10), minor2);
minor3 = _mm_mul_ps(det, minor3);
_mm_storel_pi((__m64*)(dst+12), minor3);
_mm_storeh_pi((__m64*)(dst+14), minor3);
}
else
{
// rare case: the topleft 2x2 block is not invertible (but the matrix itself is assumed to be).
// since this is a rare case, we don't need to optimize it. We just want to handle it with little
// additional code.
MatrixType m(matrix);
m.row(0).swap(m.row(2));
m.row(1).swap(m.row(3));
if(ei_compute_inverse_in_size4_case_helper(m, result))
{
// good, the topleft 2x2 block of m is invertible. Since m is different from matrix in that some
// rows were permuted, the actual inverse of matrix is derived from the inverse of m by permuting
// the corresponding columns.
result->col(0).swap(result->col(2));
result->col(1).swap(result->col(3));
}
else
{
// last possible case. Since matrix is assumed to be invertible, this last case has to work.
// first, undo the swaps previously made
m.row(0).swap(m.row(2));
m.row(1).swap(m.row(3));
// swap row 0 with the the row among 0 and 1 that has the biggest 2 first coeffs
int swap0with = ei_abs(m.coeff(0,0))+ei_abs(m.coeff(0,1))>ei_abs(m.coeff(1,0))+ei_abs(m.coeff(1,1)) ? 0 : 1;
m.row(0).swap(m.row(swap0with));
// swap row 1 with the the row among 2 and 3 that has the biggest 2 first coeffs
int swap1with = ei_abs(m.coeff(2,0))+ei_abs(m.coeff(2,1))>ei_abs(m.coeff(3,0))+ei_abs(m.coeff(3,1)) ? 2 : 3;
m.row(1).swap(m.row(swap1with));
ei_compute_inverse_in_size4_case_helper(m, result);
result->col(1).swap(result->col(swap1with));
result->col(0).swap(result->col(swap0with));
}
}
}
};
#endif
/***********************************************
*** Part 2 : selector and MatrixBase methods ***
***********************************************/
template<typename MatrixType, int Size = MatrixType::RowsAtCompileTime>
template<typename Derived, typename OtherDerived, int Size = Derived::RowsAtCompileTime>
struct ei_compute_inverse
{
static inline void run(const MatrixType& matrix, MatrixType* result)
static inline void run(const Derived& matrix, OtherDerived* result)
{
LU<MatrixType> lu(matrix);
LU<Derived> lu(matrix);
lu.computeInverse(result);
}
};
template<typename MatrixType>
struct ei_compute_inverse<MatrixType, 1>
template<typename Derived, typename OtherDerived>
struct ei_compute_inverse<Derived, OtherDerived, 1>
{
static inline void run(const MatrixType& matrix, MatrixType* result)
static inline void run(const Derived& matrix, OtherDerived* result)
{
typedef typename MatrixType::Scalar Scalar;
typedef typename Derived::Scalar Scalar;
result->coeffRef(0,0) = Scalar(1) / matrix.coeff(0,0);
}
};
template<typename MatrixType>
struct ei_compute_inverse<MatrixType, 2>
template<typename Derived, typename OtherDerived>
struct ei_compute_inverse<Derived, OtherDerived, 2>
{
static inline void run(const MatrixType& matrix, MatrixType* result)
static inline void run(const Derived& matrix, OtherDerived* result)
{
ei_compute_inverse_in_size2_case(matrix, result);
}
};
template<typename MatrixType>
struct ei_compute_inverse<MatrixType, 3>
template<typename Derived, typename OtherDerived>
struct ei_compute_inverse<Derived, OtherDerived, 3>
{
static inline void run(const MatrixType& matrix, MatrixType* result)
static inline void run(const Derived& matrix, OtherDerived* result)
{
ei_compute_inverse_in_size3_case(matrix, result);
}
};
template<typename MatrixType>
struct ei_compute_inverse<MatrixType, 4>
template<typename Derived, typename OtherDerived>
struct ei_compute_inverse<Derived, OtherDerived, 4>
{
static inline void run(const MatrixType& matrix, MatrixType* result)
static inline void run(const Derived& matrix, OtherDerived* result)
{
ei_compute_inverse_in_size4_case(matrix, result);
ei_compute_inverse_in_size4_case<Derived, OtherDerived>::run(matrix, *result);
}
};
@@ -226,11 +290,12 @@ struct ei_compute_inverse<MatrixType, 4>
* \sa inverse()
*/
template<typename Derived>
inline void MatrixBase<Derived>::computeInverse(PlainMatrixType *result) const
template<typename OtherDerived>
inline void MatrixBase<Derived>::computeInverse(MatrixBase<OtherDerived> *result) const
{
ei_assert(rows() == cols());
EIGEN_STATIC_ASSERT(NumTraits<Scalar>::HasFloatingPoint,NUMERIC_TYPE_MUST_BE_FLOATING_POINT)
ei_compute_inverse<PlainMatrixType>::run(eval(), result);
ei_compute_inverse<PlainMatrixType, OtherDerived>::run(eval(), static_cast<OtherDerived*>(result));
}
/** \lu_module

View File

@@ -63,12 +63,12 @@ template<typename MatrixType> class LU
typedef typename MatrixType::Scalar Scalar;
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType;
typedef Matrix<int, 1, MatrixType::ColsAtCompileTime, MatrixType::Options, 1, MatrixType::MaxColsAtCompileTime> IntRowVectorType;
typedef Matrix<int, MatrixType::RowsAtCompileTime, 1, MatrixType::Options, MatrixType::MaxRowsAtCompileTime, 1> IntColVectorType;
typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime, MatrixType::Options, 1, MatrixType::MaxColsAtCompileTime> RowVectorType;
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1, MatrixType::Options, MatrixType::MaxRowsAtCompileTime, 1> ColVectorType;
enum { MaxSmallDimAtCompileTime = EIGEN_ENUM_MIN(
enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN(
MatrixType::MaxColsAtCompileTime,
MatrixType::MaxRowsAtCompileTime)
};
@@ -297,7 +297,8 @@ template<typename MatrixType> class LU
*
* \sa MatrixBase::computeInverse(), inverse()
*/
inline void computeInverse(MatrixType *result) const
template<typename ResultType>
inline void computeInverse(ResultType *result) const
{
solve(MatrixType::Identity(m_lu.rows(), m_lu.cols()), result);
}
@@ -508,15 +509,16 @@ bool LU<MatrixType>::solve(
if(!isSurjective())
{
// is c is in the image of U ?
RealScalar biggest_in_c = m_rank>0 ? c.corner(TopLeft, m_rank, c.cols()).cwise().abs().maxCoeff() : 0;
RealScalar biggest_in_c = m_rank>0 ? c.corner(TopLeft, m_rank, c.cols()).cwise().abs().maxCoeff() : RealScalar(0);
for(int col = 0; col < c.cols(); ++col)
for(int row = m_rank; row < c.rows(); ++row)
if(!ei_isMuchSmallerThan(c.coeff(row,col), biggest_in_c, m_precision))
return false;
}
m_lu.corner(TopLeft, m_rank, m_rank)
.template marked<UpperTriangular>()
.solveTriangularInPlace(c.corner(TopLeft, m_rank, c.cols()));
if(m_rank>0)
m_lu.corner(TopLeft, m_rank, m_rank)
.template marked<UpperTriangular>()
.solveTriangularInPlace(c.corner(TopLeft, m_rank, c.cols()));
// Step 4
result->resize(m_lu.cols(), b.cols());

View File

@@ -54,10 +54,13 @@
* constants \f$a,b,c\f$ so that the plane of equation \f$y=ax+bz+c\f$ fits
* best the five above points. To do that, call this function as follows:
* @code
// create a vector of pointers to the points
std::vector<Vector3d> points_ptrs(5);
for(int k=0; k<5; ++k) points_ptrs[k] = &points[k];
Vector3d coeffs; // will store the coefficients a, b, c
linearRegression(
5,
&points,
&(points_ptrs[0]),
&coeffs,
1 // the coord to express as a function of
// the other ones. 0 means x, 1 means y, 2 means z.

View File

@@ -270,12 +270,18 @@ bool QR<MatrixType>::solve(
ei_assert(m_isInitialized && "QR is not initialized.");
const int rows = m_qr.rows();
ei_assert(b.rows() == rows);
result->resize(rows, b.cols());
// enforce the computation of the rank
rank();
result->resize(m_qr.cols(), b.cols());
// TODO(keir): There is almost certainly a faster way to multiply by
// Q^T without explicitly forming matrixQ(). Investigate.
*result = matrixQ().transpose()*b;
if(m_rank==0)
return result->isZero();
if(!isSurjective())
{
// is result is in the image of R ?

View File

@@ -293,7 +293,7 @@ void Tridiagonalization<MatrixType>::_compute(MatrixType& matA, CoeffVectorType&
{
int starti = i+1;
int alignedEnd = starti;
if (PacketSize>1)
if (PacketSize>1 && (int(MatrixType::Flags)&RowMajor) == 0)
{
int alignedStart = (starti) + ei_alignmentOffset(&matA.coeffRef(starti,j1), n-starti);
alignedEnd = alignedStart + ((n-alignedStart)/PacketSize)*PacketSize;
@@ -391,7 +391,7 @@ void Tridiagonalization<MatrixType>::_decomposeInPlace3x3(MatrixType& mat, Diago
{
diag[0] = ei_real(mat(0,0));
RealScalar v1norm2 = ei_abs2(mat(0,2));
if (ei_isMuchSmallerThan(v1norm2, RealScalar(1)))
if (v1norm2==RealScalar(0))
{
diag[1] = ei_real(mat(1,1));
diag[2] = ei_real(mat(2,2));

View File

@@ -49,7 +49,7 @@ template<typename MatrixType> class SVD
enum {
PacketSize = ei_packet_traits<Scalar>::size,
AlignmentMask = int(PacketSize)-1,
MinSize = EIGEN_ENUM_MIN(MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime)
MinSize = EIGEN_SIZE_MIN(MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime)
};
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVector;
@@ -61,6 +61,8 @@ template<typename MatrixType> class SVD
public:
SVD() {} // a user who relied on compiler-generated default compiler reported problems with MSVC in 2.0.7
SVD(const MatrixType& matrix)
: m_matU(matrix.rows(), std::min(matrix.rows(), matrix.cols())),
m_matV(matrix.cols(),matrix.cols()),
@@ -107,6 +109,8 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
const int m = matrix.rows();
const int n = matrix.cols();
const int nu = std::min(m,n);
ei_assert(m>=n && "In Eigen 2.0, SVD only works for MxN matrices with M>=N. Sorry!");
ei_assert(m>1 && "In Eigen 2.0, SVD doesn't work on 1x1 matrices");
m_matU.resize(m, nu);
m_matU.setZero();

View File

@@ -98,7 +98,9 @@ template<typename _Scalar> class AmbiVector
int allocSize = m_allocatedElements * sizeof(ListEl);
allocSize = allocSize/sizeof(Scalar) + (allocSize%sizeof(Scalar)>0?1:0);
Scalar* newBuffer = new Scalar[allocSize];
memcpy(newBuffer, m_buffer, copyElements * sizeof(ListEl));
std::memcpy(newBuffer, m_buffer, copyElements * sizeof(ListEl));
delete[] m_buffer;
m_buffer = newBuffer;
}
protected:
@@ -238,8 +240,11 @@ Scalar& AmbiVector<Scalar>::coeffRef(int i)
else
{
if (m_llSize>=m_allocatedElements)
{
reallocateSparse();
ei_internal_assert(m_llSize<m_size && "internal error: overflow in sparse mode");
llElements = reinterpret_cast<ListEl*>(m_buffer);
}
ei_internal_assert(m_llSize<m_allocatedElements && "internal error: overflow in sparse mode");
// let's insert a new coefficient
ListEl& el = llElements[m_llSize];
el.value = Scalar(0);
@@ -365,6 +370,9 @@ class AmbiVector<_Scalar>::Iterator
int m_cachedIndex; // current coordinate
Scalar m_cachedValue; // current value
bool m_isDense; // mode of the vector
private:
Iterator& operator=(const Iterator&);
};

View File

@@ -37,7 +37,7 @@ class CompressedStorage
: m_values(0), m_indices(0), m_size(0), m_allocatedSize(0)
{}
CompressedStorage(size_t size)
CompressedStorage(std::size_t size)
: m_values(0), m_indices(0), m_size(0), m_allocatedSize(0)
{
resize(size);
@@ -52,8 +52,8 @@ class CompressedStorage
CompressedStorage& operator=(const CompressedStorage& other)
{
resize(other.size());
memcpy(m_values, other.m_values, m_size * sizeof(Scalar));
memcpy(m_indices, other.m_indices, m_size * sizeof(int));
std::memcpy(m_values, other.m_values, m_size * sizeof(Scalar));
std::memcpy(m_indices, other.m_indices, m_size * sizeof(int));
return *this;
}
@@ -71,9 +71,9 @@ class CompressedStorage
delete[] m_indices;
}
void reserve(size_t size)
void reserve(std::size_t size)
{
size_t newAllocatedSize = m_size + size;
std::size_t newAllocatedSize = m_size + size;
if (newAllocatedSize > m_allocatedSize)
reallocate(newAllocatedSize);
}
@@ -84,10 +84,10 @@ class CompressedStorage
reallocate(m_size);
}
void resize(size_t size, float reserveSizeFactor = 0)
void resize(std::size_t size, float reserveSizeFactor = 0)
{
if (m_allocatedSize<size)
reallocate(size + size_t(reserveSizeFactor*size));
reallocate(size + std::size_t(reserveSizeFactor*size));
m_size = size;
}
@@ -99,17 +99,17 @@ class CompressedStorage
m_indices[id] = i;
}
inline size_t size() const { return m_size; }
inline size_t allocatedSize() const { return m_allocatedSize; }
inline std::size_t size() const { return m_size; }
inline std::size_t allocatedSize() const { return m_allocatedSize; }
inline void clear() { m_size = 0; }
inline Scalar& value(size_t i) { return m_values[i]; }
inline const Scalar& value(size_t i) const { return m_values[i]; }
inline Scalar& value(std::size_t i) { return m_values[i]; }
inline const Scalar& value(std::size_t i) const { return m_values[i]; }
inline int& index(size_t i) { return m_indices[i]; }
inline const int& index(size_t i) const { return m_indices[i]; }
inline int& index(std::size_t i) { return m_indices[i]; }
inline const int& index(std::size_t i) const { return m_indices[i]; }
static CompressedStorage Map(int* indices, Scalar* values, size_t size)
static CompressedStorage Map(int* indices, Scalar* values, std::size_t size)
{
CompressedStorage res;
res.m_indices = indices;
@@ -125,11 +125,11 @@ class CompressedStorage
}
/** \returns the largest \c k in [start,end) such that for all \c j in [start,k) index[\c j]\<\a key */
inline int searchLowerIndex(size_t start, size_t end, int key) const
inline int searchLowerIndex(std::size_t start, std::size_t end, int key) const
{
while(end>start)
{
size_t mid = (end+start)>>1;
std::size_t mid = (end+start)>>1;
if (m_indices[mid]<key)
start = mid+1;
else
@@ -148,12 +148,12 @@ class CompressedStorage
return m_values[m_size-1];
// ^^ optimization: let's first check if it is the last coefficient
// (very common in high level algorithms)
const size_t id = searchLowerIndex(0,m_size-1,key);
const std::size_t id = searchLowerIndex(0,m_size-1,key);
return ((id<m_size) && (m_indices[id]==key)) ? m_values[id] : defaultValue;
}
/** Like at(), but the search is performed in the range [start,end) */
inline Scalar atInRange(size_t start, size_t end, int key, Scalar defaultValue = Scalar(0)) const
inline Scalar atInRange(std::size_t start, std::size_t end, int key, Scalar defaultValue = Scalar(0)) const
{
if (start==end)
return Scalar(0);
@@ -161,7 +161,7 @@ class CompressedStorage
return m_values[end-1];
// ^^ optimization: let's first check if it is the last coefficient
// (very common in high level algorithms)
const size_t id = searchLowerIndex(start,end-1,key);
const std::size_t id = searchLowerIndex(start,end-1,key);
return ((id<end) && (m_indices[id]==key)) ? m_values[id] : defaultValue;
}
@@ -170,11 +170,11 @@ class CompressedStorage
* such that the keys are sorted. */
inline Scalar& atWithInsertion(int key, Scalar defaultValue = Scalar(0))
{
size_t id = searchLowerIndex(0,m_size,key);
std::size_t id = searchLowerIndex(0,m_size,key);
if (id>=m_size || m_indices[id]!=key)
{
resize(m_size+1,1);
for (size_t j=m_size-1; j>id; --j)
for (std::size_t j=m_size-1; j>id; --j)
{
m_indices[j] = m_indices[j-1];
m_values[j] = m_values[j-1];
@@ -187,9 +187,9 @@ class CompressedStorage
void prune(Scalar reference, RealScalar epsilon = precision<RealScalar>())
{
size_t k = 0;
size_t n = size();
for (size_t i=0; i<n; ++i)
std::size_t k = 0;
std::size_t n = size();
for (std::size_t i=0; i<n; ++i)
{
if (!ei_isMuchSmallerThan(value(i), reference, epsilon))
{
@@ -203,14 +203,14 @@ class CompressedStorage
protected:
inline void reallocate(size_t size)
inline void reallocate(std::size_t size)
{
Scalar* newValues = new Scalar[size];
int* newIndices = new int[size];
size_t copySize = std::min(size, m_size);
std::size_t copySize = std::min(size, m_size);
// copy
memcpy(newValues, m_values, copySize * sizeof(Scalar));
memcpy(newIndices, m_indices, copySize * sizeof(int));
std::memcpy(newValues, m_values, copySize * sizeof(Scalar));
std::memcpy(newIndices, m_indices, copySize * sizeof(int));
// delete old stuff
delete[] m_values;
delete[] m_indices;
@@ -222,8 +222,8 @@ class CompressedStorage
protected:
Scalar* m_values;
int* m_indices;
size_t m_size;
size_t m_allocatedSize;
std::size_t m_size;
std::size_t m_allocatedSize;
};

View File

@@ -212,7 +212,7 @@ class DynamicSparseMatrix
// remove all coefficients with innerCoord>=innerSize
// TODO
std::cerr << "not implemented yet\n";
exit(2);
std::exit(2);
}
if (m_data.size() != outerSize)
{
@@ -289,9 +289,11 @@ class DynamicSparseMatrix<Scalar,_Flags>::InnerIterator : public SparseVector<Sc
inline int row() const { return IsRowMajor ? m_outer : Base::index(); }
inline int col() const { return IsRowMajor ? Base::index() : m_outer; }
protected:
const int m_outer;
private:
InnerIterator& operator=(const InnerIterator&);
};
#endif // EIGEN_DYNAMIC_SPARSEMATRIX_H

View File

@@ -53,6 +53,9 @@ class SparseInnerVectorSet : ei_no_assignment_operator,
inline InnerIterator(const SparseInnerVectorSet& xpr, int outer)
: MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer)
{}
private:
InnerIterator& operator=(const InnerIterator&);
};
inline SparseInnerVectorSet(const MatrixType& matrix, int outerStart, int outerSize)
@@ -110,6 +113,8 @@ class SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options>, Size>
inline InnerIterator(const SparseInnerVectorSet& xpr, int outer)
: MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer)
{}
private:
InnerIterator& operator=(const InnerIterator&);
};
inline SparseInnerVectorSet(const MatrixType& matrix, int outerStart, int outerSize)

View File

@@ -156,6 +156,9 @@ template<typename ExpressionType> class SparseCwise
protected:
ExpressionTypeNested m_matrix;
private:
SparseCwise& operator=(const SparseCwise&);
};
template<typename Derived>

View File

@@ -126,6 +126,8 @@ class SparseCwiseBinaryOp<BinaryOp,Lhs,Rhs>::InnerIterator
EIGEN_STRONG_INLINE InnerIterator(const SparseCwiseBinaryOp& binOp, int outer)
: Base(binOp,outer)
{}
private:
InnerIterator& operator=(const InnerIterator&);
};
/***************************************************************************
@@ -197,6 +199,9 @@ class ei_sparse_cwise_binary_op_inner_iterator_selector<BinaryOp, Lhs, Rhs, Deri
const BinaryOp& m_functor;
Scalar m_value;
int m_id;
private:
ei_sparse_cwise_binary_op_inner_iterator_selector& operator=(const ei_sparse_cwise_binary_op_inner_iterator_selector&);
};
// sparse - sparse (product)
@@ -250,6 +255,9 @@ class ei_sparse_cwise_binary_op_inner_iterator_selector<ei_scalar_product_op<T>,
LhsIterator m_lhsIter;
RhsIterator m_rhsIter;
const BinaryFunc& m_functor;
private:
ei_sparse_cwise_binary_op_inner_iterator_selector& operator=(const ei_sparse_cwise_binary_op_inner_iterator_selector&);
};
// sparse - dense (product)
@@ -290,6 +298,9 @@ class ei_sparse_cwise_binary_op_inner_iterator_selector<ei_scalar_product_op<T>,
LhsIterator m_lhsIter;
const BinaryFunc m_functor;
const int m_outer;
private:
ei_sparse_cwise_binary_op_inner_iterator_selector& operator=(const ei_sparse_cwise_binary_op_inner_iterator_selector&);
};
// sparse - dense (product)

View File

@@ -90,6 +90,9 @@ class SparseCwiseUnaryOp<UnaryOp,MatrixType>::InnerIterator
protected:
MatrixTypeIterator m_iter;
const UnaryOp m_functor;
private:
InnerIterator& operator=(const InnerIterator&);
};
template<typename Derived>

View File

@@ -120,6 +120,8 @@ class ei_sparse_diagonal_product_inner_iterator_selector
const SparseDiagonalProductType& expr, int outer)
: Base(expr.rhs().innerVector(outer) .cwise()* expr.lhs().diagonal(), 0)
{}
private:
ei_sparse_diagonal_product_inner_iterator_selector& operator=(const ei_sparse_diagonal_product_inner_iterator_selector&);
};
template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>

View File

@@ -64,16 +64,21 @@ template<typename ExpressionType, unsigned int Added, unsigned int Removed> clas
protected:
ExpressionTypeNested m_matrix;
private:
SparseFlagged& operator=(const SparseFlagged&);
};
template<typename ExpressionType, unsigned int Added, unsigned int Removed>
class SparseFlagged<ExpressionType,Added,Removed>::InnerIterator : public ExpressionType::InnerIterator
{
public:
EIGEN_STRONG_INLINE InnerIterator(const SparseFlagged& xpr, int outer)
: ExpressionType::InnerIterator(xpr.m_matrix, outer)
{}
private:
InnerIterator& operator=(const InnerIterator&);
};
template<typename ExpressionType, unsigned int Added, unsigned int Removed>

View File

@@ -96,8 +96,8 @@ class SparseLU
void setOrderingMethod(int m)
{
ei_assert(m&~OrderingMask == 0 && m!=0 && "invalid ordering method");
m_flags = m_flags&~OrderingMask | m&OrderingMask;
ei_assert((m&~OrderingMask) == 0 && m!=0 && "invalid ordering method");
m_flags = (m_flags&~OrderingMask) | (m&OrderingMask);
}
int orderingMethod() const

View File

@@ -122,7 +122,7 @@ class SparseMatrix
{
m_data.clear();
//if (m_outerSize)
memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(int));
std::memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(int));
// for (int i=0; i<m_outerSize; ++i)
// m_outerIndex[i] = 0;
// if (m_outerSize)
@@ -164,7 +164,7 @@ class SparseMatrix
{
ei_assert(m_data.index(m_data.size()-1)<inner && "wrong sorted insertion");
}
assert(size_t(m_outerIndex[outer+1]) == m_data.size());
assert(std::size_t(m_outerIndex[outer+1]) == m_data.size());
int id = m_outerIndex[outer+1];
++m_outerIndex[outer+1];
@@ -190,10 +190,10 @@ class SparseMatrix
}
m_outerIndex[outer+1] = m_outerIndex[outer];
}
assert(size_t(m_outerIndex[outer+1]) == m_data.size() && "invalid outer index");
size_t startId = m_outerIndex[outer];
// FIXME let's make sure sizeof(long int) == sizeof(size_t)
size_t id = m_outerIndex[outer+1];
assert(std::size_t(m_outerIndex[outer+1]) == m_data.size() && "invalid outer index");
std::size_t startId = m_outerIndex[outer];
// FIXME let's make sure sizeof(long int) == sizeof(std::size_t)
std::size_t id = m_outerIndex[outer+1];
++m_outerIndex[outer+1];
float reallocRatio = 1;
@@ -259,19 +259,21 @@ class SparseMatrix
m_data.resize(k,0);
}
/** Resizes the matrix to a \a rows x \a cols matrix and initializes it to zero
* \sa resizeNonZeros(int), reserve(), setZero()
*/
void resize(int rows, int cols)
{
// std::cerr << this << " resize " << rows << "x" << cols << "\n";
const int outerSize = IsRowMajor ? rows : cols;
m_innerSize = IsRowMajor ? cols : rows;
m_data.clear();
if (m_outerSize != outerSize)
if (m_outerSize != outerSize || m_outerSize==0)
{
delete[] m_outerIndex;
m_outerIndex = new int [outerSize+1];
m_outerSize = outerSize;
memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(int));
}
std::memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(int));
}
void resizeNonZeros(int size)
{
@@ -322,7 +324,7 @@ class SparseMatrix
else
{
resize(other.rows(), other.cols());
memcpy(m_outerIndex, other.m_outerIndex, (m_outerSize+1)*sizeof(int));
std::memcpy(m_outerIndex, other.m_outerIndex, (m_outerSize+1)*sizeof(int));
m_data = other.m_data;
}
return *this;
@@ -442,6 +444,9 @@ class SparseMatrix<Scalar,_Flags>::InnerIterator
int m_id;
const int m_start;
const int m_end;
private:
InnerIterator& operator=(const InnerIterator&);
};
#endif // EIGEN_SPARSEMATRIX_H

View File

@@ -97,7 +97,7 @@ struct ei_traits<SparseProduct<LhsNested, RhsNested, ProductMode> >
RowsAtCompileTime = _LhsNested::RowsAtCompileTime,
ColsAtCompileTime = _RhsNested::ColsAtCompileTime,
InnerSize = EIGEN_ENUM_MIN(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime),
InnerSize = EIGEN_SIZE_MIN(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime),
MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime,
MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime,

View File

@@ -62,15 +62,20 @@ template<typename MatrixType> class SparseTranspose
protected:
const typename MatrixType::Nested m_matrix;
private:
SparseTranspose& operator=(const SparseTranspose&);
};
template<typename MatrixType> class SparseTranspose<MatrixType>::InnerIterator : public MatrixType::InnerIterator
{
public:
EIGEN_STRONG_INLINE InnerIterator(const SparseTranspose& trans, int outer)
: MatrixType::InnerIterator(trans.m_matrix, outer)
{}
private:
InnerIterator& operator=(const InnerIterator&);
};
template<typename MatrixType> class SparseTranspose<MatrixType>::ReverseInnerIterator : public MatrixType::ReverseInnerIterator

View File

@@ -360,6 +360,9 @@ class SparseVector<Scalar,_Flags>::InnerIterator
const CompressedStorage<Scalar>& m_data;
int m_id;
const int m_end;
private:
InnerIterator& operator=(const InnerIterator&);
};
#endif // EIGEN_SPARSEVECTOR_H

View File

@@ -43,8 +43,11 @@ struct ei_solve_triangular_selector<Lhs,Rhs,LowerTriangular,RowMajor|IsSparse>
{
lastVal = it.value();
lastIndex = it.index();
if(lastIndex == i)
break;
tmp -= lastVal * other.coeff(lastIndex,col);
}
if (Lhs::Flags & UnitDiagBit)
other.coeffRef(i,col) = tmp;
else

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) 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,8 +26,15 @@
#ifndef EIGEN_BENCH_TIMER_H
#define EIGEN_BENCH_TIMER_H
#include <sys/time.h>
#if defined(_WIN32) || defined(__CYGWIN__)
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <time.h>
#include <unistd.h>
#endif
#include <cstdlib>
#include <numeric>
@@ -35,12 +42,25 @@ namespace Eigen
{
/** Elapsed time timer keeping the best try.
*
* On POSIX platforms we use clock_gettime with CLOCK_PROCESS_CPUTIME_ID.
* On Windows we use QueryPerformanceCounter
*
* Important: on linux, you must link with -lrt
*/
class BenchTimer
{
public:
BenchTimer() { reset(); }
BenchTimer()
{
#if defined(_WIN32) || defined(__CYGWIN__)
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
m_frequency = (double)freq.QuadPart;
#endif
reset();
}
~BenchTimer() {}
@@ -51,23 +71,34 @@ public:
m_best = std::min(m_best, getTime() - m_start);
}
/** Return the best elapsed time.
/** Return the best elapsed time in seconds.
*/
inline double value(void)
{
return m_best;
return m_best;
}
#if defined(_WIN32) || defined(__CYGWIN__)
inline double getTime(void)
#else
static inline double getTime(void)
#endif
{
struct timeval tv;
struct timezone tz;
gettimeofday(&tv, &tz);
return (double)tv.tv_sec + 1.e-6 * (double)tv.tv_usec;
#ifdef WIN32
LARGE_INTEGER query_ticks;
QueryPerformanceCounter(&query_ticks);
return query_ticks.QuadPart/m_frequency;
#else
timespec ts;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
return double(ts.tv_sec) + 1e-9 * double(ts.tv_nsec);
#endif
}
protected:
#if defined(_WIN32) || defined(__CYGWIN__)
double m_frequency;
#endif
double m_best, m_start;
};

View File

@@ -142,7 +142,7 @@ public :
}
static inline void cholesky(const gene_matrix & X, gene_matrix & C, int N){
C = X.cholesky().matrixL();
C = X.llt().matrixL();
// C = X;
// Cholesky<gene_matrix>::computeInPlace(C);
// Cholesky<gene_matrix>::computeInPlaceBlock(C);

View File

@@ -0,0 +1,31 @@
# Base configuration for linux cross-compilation.
.build:linux:cross:
extends: .common:linux:cross
stage: build
variables:
EIGEN_CI_BUILD_TARGET: buildtests
script:
- . ci/scripts/build.linux.script.sh
tags:
- saas-linux-2xlarge-amd64
rules:
- if: $CI_PIPELINE_SOURCE == "schedule" && $CI_PROJECT_NAMESPACE == "libeigen"
- if: $CI_PIPELINE_SOURCE == "web" && $CI_PROJECT_NAMESPACE == "libeigen"
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_PROJECT_NAMESPACE == "libeigen" && $CI_MERGE_REQUEST_LABELS =~ "/all-tests/"
cache:
key: "$CI_JOB_NAME_SLUG-$CI_COMMIT_REF_SLUG-BUILD"
paths:
- ${EIGEN_CI_BUILDDIR}/
build:linux:docs:
extends: .build:linux:cross
variables:
EIGEN_CI_TARGET_ARCH: any
EIGEN_CI_BUILD_TARGET: doc
EIGEN_CI_INSTALL: ca-certificates clang flex python3 bison graphviz
EIGEN_CI_C_COMPILER: clang
EIGEN_CI_CXX_COMPILER: clang++
EIGEN_CI_BEFORE_SCRIPT: ". ci/scripts/build_and_install_doxygen.sh Release_1_13_2"
EIGEN_CI_ADDITIONAL_ARGS: '-DCMAKE_CXX_FLAGS="-Wno-deprecated-declarations -Wno-ignored-reference-qualifiers"'
rules:
- if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_NAMESPACE == "libeigen"

24
ci/common.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,24 @@
# Base configuration for linux builds and tests.
.common:linux:cross:
image: ubuntu:20.04
variables:
EIGEN_CI_TARGET_ARCH: ""
EIGEN_CI_ADDITIONAL_ARGS: ""
# If host matches target, use the following:
EIGEN_CI_C_COMPILER: ""
EIGEN_CI_CXX_COMPILER: ""
EIGEN_CI_INSTALL: "${EIGEN_CI_C_COMPILER} ${EIGEN_CI_CXX_COMPILER}"
# If host does not match the target, use the following:
EIGEN_CI_CROSS_TARGET_TRIPLE: ""
EIGEN_CI_CROSS_C_COMPILER: ${EIGEN_CI_C_COMPILER}
EIGEN_CI_CROSS_CXX_COMPILER: ${EIGEN_CI_CXX_COMPILER}
EIGEN_CI_CROSS_INSTALL: "${EIGEN_CI_CROSS_C_COMPILER} ${EIGEN_CI_CROSS_CXX_COMPILER}"
before_script:
# Call script in current shell - it sets up some environment variables.
- . ci/scripts/common.linux.before_script.sh
artifacts:
when: always
name: "$CI_JOB_NAME_SLUG-$CI_COMMIT_REF_SLUG"
paths:
- ${EIGEN_CI_BUILDDIR}/
expire_in: 5 days

25
ci/deploy.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,25 @@
# Upload docs if pipeline succeeded.
deploy:docs:
stage: deploy
image: busybox
dependencies: [ build:linux:docs ]
variables:
PAGES_PREFIX: docs-nightly
script:
- echo "Deploying site to $CI_PAGES_URL"
- mv ${EIGEN_CI_BUILDDIR}/doc/html public
pages:
path_prefix: $PAGES_PREFIX
expire_in: never
artifacts:
name: "$CI_JOB_NAME_SLUG-$CI_COMMIT_REF_SLUG"
paths:
- public
tags:
- saas-linux-small-amd64
rules:
- if: $CI_PIPELINE_SOURCE == "schedule" && $CI_PROJECT_NAMESPACE == "libeigen"
- if: $CI_PIPELINE_SOURCE == "web" && $CI_PROJECT_NAMESPACE == "libeigen"
- if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_NAMESPACE == "libeigen"
variables:
PAGES_PREFIX: docs-$CI_COMMIT_REF_NAME

View File

@@ -0,0 +1,31 @@
#!/bin/bash
set -x
# Create and enter build directory.
rootdir=`pwd`
mkdir -p ${EIGEN_CI_BUILDDIR}
cd ${EIGEN_CI_BUILDDIR}
# Configure build.
cmake -G Ninja \
-DCMAKE_CXX_COMPILER=${EIGEN_CI_CXX_COMPILER} \
-DCMAKE_C_COMPILER=${EIGEN_CI_C_COMPILER} \
-DCMAKE_CXX_COMPILER_TARGET=${EIGEN_CI_CXX_COMPILER_TARGET} \
"${EIGEN_CI_ADDITIONAL_ARGS}" ${rootdir}
target=""
if [[ ${EIGEN_CI_BUILD_TARGET} ]]; then
target="--target ${EIGEN_CI_BUILD_TARGET}"
fi
# Builds (particularly gcc) sometimes get killed, potentially when running
# out of resources. In that case, keep trying to build the remaining
# targets (k0), then try to build again with a single thread (j1) to minimize
# resource use.
cmake --build . ${target} -- -k0 || cmake --build . ${target} -- -k0 -j1
# Return to root directory.
cd ${rootdir}
set +x

View File

@@ -0,0 +1,6 @@
git clone --depth 1 --branch $1 https://github.com/doxygen/doxygen.git
cmake -B doxygen/.build -G Ninja \
-DCMAKE_CXX_COMPILER=${EIGEN_CI_CXX_COMPILER} \
-DCMAKE_C_COMPILER=${EIGEN_CI_C_COMPILER} \
doxygen
cmake --build doxygen/.build -t install

View File

@@ -0,0 +1,46 @@
#!/bin/bash
set -x
echo "Running ${CI_JOB_NAME}"
# Get architecture and display CI configuration.
export ARCH=`uname -m`
export NPROC=`nproc`
echo "arch=$ARCH, target=${EIGEN_CI_TARGET_ARCH}"
echo "Processors: ${NPROC}"
echo "CI Variables:"
export | grep EIGEN
# Set noninteractive, otherwise tzdata may be installed and prompt for a
# geographical region.
export DEBIAN_FRONTEND=noninteractive
apt-get update -y > /dev/null
apt-get install -y --no-install-recommends ninja-build cmake git > /dev/null
# Install required dependencies and set up compilers.
# These are required even for testing to ensure that dynamic runtime libraries
# are available.
if [[ "$ARCH" == "${EIGEN_CI_TARGET_ARCH}" || "${EIGEN_CI_TARGET_ARCH}" == "any" ]]; then
apt-get install -y --no-install-recommends ${EIGEN_CI_INSTALL} > /dev/null;
export EIGEN_CI_CXX_IMPLICIT_INCLUDE_DIRECTORIES="";
export EIGEN_CI_CXX_COMPILER_TARGET="";
else
apt-get install -y --no-install-recommends ${EIGEN_CI_CROSS_INSTALL} > /dev/null;
export EIGEN_CI_C_COMPILER=${EIGEN_CI_CROSS_C_COMPILER};
export EIGEN_CI_CXX_COMPILER=${EIGEN_CI_CROSS_CXX_COMPILER};
export EIGEN_CI_CXX_COMPILER_TARGET=${EIGEN_CI_CROSS_TARGET_TRIPLE};
# Tell the compiler where to find headers and libraries if using clang.
# NOTE: this breaks GCC since it messes with include path order
# (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70129)
if [[ "${EIGEN_CI_CROSS_CXX_COMPILER}" == *"clang"* ]]; then
export CPLUS_INCLUDE_PATH="/usr/${EIGEN_CI_CROSS_TARGET_TRIPLE}/include";
export LIBRARY_PATH="/usr/${EIGEN_CI_CROSS_TARGET_TRIPLE}/lib64";
fi
fi
echo "Compilers: ${EIGEN_CI_C_COMPILER} ${EIGEN_CI_CXX_COMPILER}"
if [ -n "$EIGEN_CI_BEFORE_SCRIPT" ]; then eval "$EIGEN_CI_BEFORE_SCRIPT"; fi
set +x

View File

@@ -0,0 +1,64 @@
# - Try to find how to link to the standard math library, if anything at all is needed to do.
# On most platforms this is automatic, but for example it's not automatic on QNX.
#
# Once done this will define
#
# STANDARD_MATH_LIBRARY_FOUND - we found how to successfully link to the standard math library
# STANDARD_MATH_LIBRARY - the name of the standard library that one has to link to.
# -- this will be left empty if it's automatic (most platforms).
# -- this will be set to "m" on platforms where one must explicitly
# pass the "-lm" linker flag.
#
# Copyright (c) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
# Redistribution and use is allowed according to the terms of the 2-clause BSD license.
include(CheckCXXSourceCompiles)
# a little test program for c++ math functions.
# notice the std:: is required on some platforms such as QNX
set(find_standard_math_library_test_program
"#include<cmath>
int main() { std::sin(0.0); std::log(0.0f); }")
# first try compiling/linking the test program without any linker flags
set(CMAKE_REQUIRED_FLAGS "")
set(CMAKE_REQUIRED_LIBRARIES "")
CHECK_CXX_SOURCE_COMPILES(
"${find_standard_math_library_test_program}"
standard_math_library_linked_to_automatically
)
if(standard_math_library_linked_to_automatically)
# the test program linked successfully without any linker flag.
set(STANDARD_MATH_LIBRARY "")
set(STANDARD_MATH_LIBRARY_FOUND TRUE)
else()
# the test program did not link successfully without any linker flag.
# This is a very uncommon case that so far we only saw on QNX. The next try is the
# standard name 'm' for the standard math library.
set(CMAKE_REQUIRED_LIBRARIES "m")
CHECK_CXX_SOURCE_COMPILES(
"${find_standard_math_library_test_program}"
standard_math_library_linked_to_as_m)
if(standard_math_library_linked_to_as_m)
# the test program linked successfully when linking to the 'm' library
set(STANDARD_MATH_LIBRARY "m")
set(STANDARD_MATH_LIBRARY_FOUND TRUE)
else()
# the test program still doesn't link successfully
set(STANDARD_MATH_LIBRARY_FOUND FALSE)
endif()
endif()

View File

@@ -39,7 +39,7 @@ add_custom_target(
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/Eigen_Silly_Professor_64x64.png
${CMAKE_CURRENT_BINARY_DIR}/html/
COMMAND doxygen
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/cleanhierarchy.sh ${CMAKE_CURRENT_BINARY_DIR}/html/hierarchy.html
# COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/cleanhierarchy.sh ${CMAKE_CURRENT_BINARY_DIR}/html/hierarchy.html
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)

View File

@@ -57,10 +57,10 @@ void makeFloor(const MatrixBase<OtherDerived>& other) { derived() = derived().cw
template<typename OtherDerived>
void makeCeil(const MatrixBase<OtherDerived>& other) { derived() = derived().cwise().max(other.derived()); }
const typename Cwise<Derived>::ScalarAddReturnType
operator+(const Scalar& scalar) const { return cwise() + scalar }
const const CwiseUnaryOp<ei_scalar_add_op<Scalar>, Derived>
operator+(const Scalar& scalar) const { return cwise() + scalar; }
friend const typename Cwise<Derived>::ScalarAddReturnType
friend const CwiseUnaryOp<ei_scalar_add_op<Scalar>, Derived>
operator+(const Scalar& scalar, const MatrixBase<Derived>& mat) { return mat + scalar; }
\endcode
@@ -81,7 +81,7 @@ In order to add support for a custom type \c T you need:
3 - define a couple of math functions for your type such as: ei_sqrt, ei_abs, etc...
(see the file Eigen/src/Core/MathFunctions.h)
Here is a concrete example adding support for the Adolc's \c adouble type. <a href="http://www.math.tu-dresden.de/~adol-c/">Adolc</a> is an automatic differentiation library. The type \c adouble is basically a real value tracking the values of any number of partial derivatives.
Here is a concrete example adding support for the Adolc's \c adouble type. <a href="https://projects.coin-or.org/ADOL-C">Adolc</a> is an automatic differentiation library. The type \c adouble is basically a real value tracking the values of any number of partial derivatives.
\code
#ifndef ADLOCSUPPORT_H

View File

@@ -4,6 +4,10 @@ namespace Eigen {
This is an issue that, so far, we met only with GCC on Windows: for instance, MinGW and TDM-GCC.
\htmlonly
<b><big><big>It seems that this GCC bug has been <a href="http://gcc.gnu.org/gcc-4.5/changes.html">fixed in GCC 4.5</a>. We encourage all GCC/Windows users to upgrade to GCC 4.5.</big></big></b>
\endhtmlonly
By default, in a function like this,
\code

View File

@@ -783,9 +783,7 @@ HTML_HEADER = "${Eigen_BINARY_DIR}/doc/eigendoxy_header.html"
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
# the footer has not been customized yet, so let's use the default one
# ${Eigen_BINARY_DIR}/doc/eigendoxy_footer.html
HTML_FOOTER =
HTML_FOOTER = "${Eigen_BINARY_DIR}/doc/eigendoxy_footer.html"
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
# style sheet that is used by each HTML page. It can be used to

View File

@@ -229,17 +229,24 @@ Of course, fixed-size matrices can't be resized.
\subsection TutorialMap Map
Any memory buffer can be mapped as an Eigen expression:
<table class="tutorial_code"><tr><td>
Any memory buffer can be mapped as an Eigen expression using the Map() static method:
\code
std::vector<float> stlarray(10);
Map<VectorXf>(&stlarray[0], stlarray.size()).setOnes();
int data[4] = 1, 2, 3, 4;
Matrix2i mat2x2(data);
MatrixXi mat2x2 = Map<Matrix2i>(data);
MatrixXi mat2x2 = Map<MatrixXi>(data,2,2);
VectorXf::Map(&stlarray[0], stlarray.size()).squaredNorm();
\endcode
Here VectorXf::Map returns an object of class Map<VectorXf>, which behaves like a VectorXf except that it uses the existing array. You can write to this object, that will write to the existing array. You can also construct a named obtect to reuse it:
\code
float array[rows*cols];
Map<MatrixXf> m(array,rows,cols);
m = othermatrix1 * othermatrix2;
m.eigenvalues();
\endcode
In the fixed-size case, no need to pass sizes:
\code
float array[9];
Map<Matrix3d> m(array);
Matrix3d::Map(array).setIdentity();
\endcode
</td></tr></table>

View File

@@ -6,10 +6,12 @@ namespace Eigen {
- \ref summary
- \ref allocator
- \ref vector
- \ref newvector
\section summary Executive summary
Using STL containers on \ref FixedSizeVectorizable "fixed-size vectorizable Eigen types" requires taking the following two steps:
Using STL containers on \ref FixedSizeVectorizable "fixed-size vectorizable Eigen types", or classes having members of such types, requires taking the following two steps:
\li A 16-byte-aligned allocator must be used. Eigen does provide one ready for use: aligned_allocator.
\li If you want to use the std::vector container, you need to \#include <Eigen/StdVector>.
@@ -44,6 +46,18 @@ std::vector<Eigen::Vector4f>
\endcode
without having to worry about anything.
\section newvector The new and improved workaround for std::vector
Well, except that in Eigen 2.0 the <Eigen/StdVector> header causes some compatibility issues as it reimplements the std::vector<T> container in a not-fully-compatible way. If you want to avoid these issues, starting in Eigen 2.0.6 a new implementation is available, which will become default in the next major version of Eigen. You can enable it by defining EIGEN_USE_NEW_STDVECTOR:
\code
#define EIGEN_USE_NEW_STDVECTOR
#include<Eigen/StdVector>
\endcode
This new implementation <a href="http://eigen.tuxfamily.org/dox-devel/StlContainers.html#vector">is documented here</a>. In particular, note that if you use it, you must specify Eigen::aligned_allocator<T> as the allocator type, otherwise it doesn't make any difference from the standard std::vector. This new std::vector implementation \b only overrides the standard one if used with this allocator, which guarantees that it doesn't break existing non-Eigen code.
<span class="note">\b Explanation: The resize() method of std::vector takes a value_type argument (defaulting to value_type()). So with std::vector<Eigen::Vector4f>, some Eigen::Vector4f objects will be passed by value, which discards any alignment modifiers, so a Eigen::Vector4f can be created at an unaligned location. In order to avoid that, the only solution we saw was to specialize std::vector to make it work on a slight modification of, here, Eigen::Vector4f, that is able to deal properly with this situation.
</span>

View File

@@ -152,7 +152,7 @@ OpenGL compatibility \b 3D </td><td>\code
glLoadMatrixf(t.data());\endcode</td></tr>
<tr><td>
OpenGL compatibility \b 2D </td><td>\code
Transform3f aux(Transform3f::Identity);
Transform3f aux(Transform3f::Identity());
aux.linear().corner<2,2>(TopLeft) = t.linear();
aux.translation().start<2>() = t.translation();
glLoadMatrixf(aux.data());\endcode</td></tr>

View File

@@ -12,7 +12,7 @@ is explained here: http://eigen.tuxfamily.org/dox/UnalignedArrayAssert.html
**** READ THIS WEB PAGE !!! ****"' failed.
</pre>
There are 3 known causes for this issue. Please read on to understand them and learn how to fix them.
There are 4 known causes for this issue. Please read on to understand them and learn how to fix them.
\b Table \b of \b contents
- \ref where
@@ -21,6 +21,7 @@ There are 3 known causes for this issue. Please read on to understand them and l
- \ref c3
- \ref c4
- \ref explanation
- \ref getrid
\section where Where in my own code is the cause of the problem?
@@ -54,16 +55,17 @@ Note that here, Eigen::Vector2d is only used as an example, more generally the i
\section c2 Cause 2: STL Containers
If you use STL Containers such as std::vector, std::map, ..., with Eigen objects, like this,
If you use STL Containers such as std::vector, std::map, ..., with Eigen objects, or with classes containing Eigen objects, like this,
\code
std::vector<Eigen::Matrix2f> my_vector;
std::map<int, Eigen::Matrix2f> my_map;
struct my_class { ... Eigen::Matrix2f m; ... };
std::map<int, my_class> my_map;
\endcode
then you need to read this separate page: \ref StlContainers "Using STL Containers with Eigen".
Note that here, Eigen::Matrix2f is only used as an example, more generally the issue arises for all \ref FixedSizeVectorizable "fixed-size vectorizable Eigen types".
Note that here, Eigen::Matrix2f is only used as an example, more generally the issue arises for all \ref FixedSizeVectorizable "fixed-size vectorizable Eigen types" and \ref StructHavingEigenMembers "structures having such Eigen objects as member".
\section c3 Cause 3: Passing Eigen objects by value
@@ -101,6 +103,16 @@ Eigen normally takes care of these alignment issues for you, by setting an align
However there are a few corner cases where these alignment settings get overridden: they are the possible causes for this assertion.
\section getrid I don't care about vectorization, how do I get rid of that stuff?
Two possibilities:
<ul>
<li>Define EIGEN_DONT_ALIGN. That disables all 128-bit alignment code, and in particular everything vectorization-related. But do note that this in particular breaks ABI compatibility with vectorized code. This requires Eigen 2.0.6 or later, and with Eigen 2.0.12 or later it automatically implies EIGEN_DONT_VECTORIZE (before 2.0.12 you had to define both).</li>
<li>Or define both EIGEN_DONT_VECTORIZE and EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT. This keeps the 128-bit alignment code and thus preserves ABI compatibility.</li>
</ul>
For more information, see <a href="http://eigen.tuxfamily.org/index.php?title=FAQ#I_disabled_vectorization.2C_but_I.27m_still_getting_annoyed_about_alignment_issues.21">this FAQ</a>.
*/
}

View File

@@ -1,5 +1,17 @@
<hr size="1"><address style="text-align: right;"><small>Generated on Sun Aug 24 23:40:21 2008 for Eigen by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.5 </small></address>
<hr class="footer"/>
<!-- Piwik -->
<script type="text/javascript">
var pkBaseURL = (("https:" == document.location.protocol) ? "https://stats.sylphide-consulting.com/piwik/" : "http://stats.sylphide-consulting.com/piwik/");
document.write(unescape("%3Cscript src='" + pkBaseURL + "piwik.js' type='text/javascript'%3E%3C/script%3E"));
</script><script type="text/javascript">
try {
var piwikTracker = Piwik.getTracker(pkBaseURL + "piwik.php", 20);
piwikTracker.trackPageView();
piwikTracker.enableLinkTracking();
} catch( err ) {}
</script><noscript><p><img src="http://stats.sylphide-consulting.com/piwik/piwik.php?idsite=20" style="border:0" alt="" /></p></noscript>
<!-- End Piwik Tracking Code -->
</body>
</html>
</html>

View File

@@ -5,6 +5,9 @@ ADD_CUSTOM_TARGET(all_examples)
FOREACH(example_src ${examples_SRCS})
GET_FILENAME_COMPONENT(example ${example_src} NAME_WE)
ADD_EXECUTABLE(${example} ${example_src})
if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)
target_link_libraries(${example} ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO})
endif()
GET_TARGET_PROPERTY(example_executable
${example} LOCATION)
ADD_CUSTOM_COMMAND(

View File

@@ -11,6 +11,9 @@ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/compile_snippet.cpp.in
${CMAKE_CURRENT_BINARY_DIR}/${compile_snippet_src})
ADD_EXECUTABLE(${compile_snippet_target}
${CMAKE_CURRENT_BINARY_DIR}/${compile_snippet_src})
if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)
target_link_libraries(${compile_snippet_target} ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO})
endif()
GET_TARGET_PROPERTY(compile_snippet_executable
${compile_snippet_target} LOCATION)
ADD_CUSTOM_COMMAND(

7
eigen2.pc.in Normal file
View File

@@ -0,0 +1,7 @@
Name: Eigen2
Description: A C++ template library for linear algebra: vectors, matrices, and related algorithms
Requires:
Version: ${EIGEN_VERSION_NUMBER}
Libs:
Cflags: -I${INCLUDE_INSTALL_DIR}

View File

@@ -1,27 +1,24 @@
#!/bin/sh
# TODO : actually exit on exit, currently it only exit from the ()
# TODO : display error msg on stderr instead of stdout
# configuration
USER='orzel'
# You should call this script with USER set as you want, else some default
# will be used
USER=${USER:-'orzel'}
UPLOAD_DIR=dox-2.0
# step 1 : update
hg pull -u || (echo "update failed"; exit 1)
#ulimit -v 1024000
# step 2 : build
# todo if 'build is not there, create one:
#mkdir build
(cd build && cmake .. && make -j3 doc) || (echo "make failed"; exit 1)
#todo: n+1 where n = number of cpus
# step 1 : build
rm build/doc/html -Rf
mkdir build -p
(cd build && cmake .. && make doc) || { echo "make failed"; exit 1; }
#step 3 : upload
BRANCH=`hg branch`
if [ $BRANCH == "default" ]
then
BRANCH='devel'
fi
# (the '/' at the end of path are very important, see rsync documentation)
rsync -az build/doc/html/ $USER@ssh.tuxfamily.org:eigen/eigen.tuxfamily.org-web/htdocs/dox-$BRANCH/ || (echo "upload failed"; exit 1)
#step 2 : upload
# (the '/' at the end of path is very important, see rsync documentation)
rsync -az --no-p --delete build/doc/html/ $USER@ssh.tuxfamily.org:eigen/eigen.tuxfamily.org-web/htdocs/$UPLOAD_DIR/ || { echo "upload failed"; exit 1; }
#step 3 : fix the perm
ssh $USER@ssh.tuxfamily.org "chmod -R g+w /home/eigen/eigen.tuxfamily.org-web/htdocs/$UPLOAD_DIR" || { echo "perm failed"; exit 1; }
echo "Uploaded successfully"

View File

@@ -1,3 +1,7 @@
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()
find_package(GSL)
if(GSL_FOUND AND GSL_VERSION_MINOR LESS 9)
@@ -93,12 +97,20 @@ else(CMAKE_COMPILER_IS_GNUCXX)
endif(CMAKE_COMPILER_IS_GNUCXX)
option(EIGEN_NO_ASSERTION_CHECKING "Disable checking of assertions" OFF)
if(EIGEN_NO_ASSERTION_CHECKING)
add_definitions("-DEIGEN_NO_ASSERTION_CHECKING=1")
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})
set_target_properties(${target} PROPERTIES ${prop} "${previous} ${value}")
if(previous MATCHES "NOTFOUND")
set_target_properties(${target} PROPERTIES ${prop} "${value}")
else()
set_target_properties(${target} PROPERTIES ${prop} "${previous} ${value}")
endif()
endmacro(ei_add_target_property)
@@ -134,13 +146,9 @@ macro(ei_add_test testname)
option(EIGEN_DEBUG_ASSERTS "Enable debuging of assertions" OFF)
if(EIGEN_DEBUG_ASSERTS)
set_target_properties(${targetname} PROPERTIES COMPILE_DEFINITIONS "-DEIGEN_DEBUG_ASSERTS=1")
set_target_properties(${targetname} PROPERTIES COMPILE_DEFINITIONS "EIGEN_DEBUG_ASSERTS=1")
endif(EIGEN_DEBUG_ASSERTS)
else(NOT EIGEN_NO_ASSERTION_CHECKING)
set_target_properties(${targetname} PROPERTIES COMPILE_DEFINITIONS "-DEIGEN_NO_ASSERTION_CHECKING=1")
endif(NOT EIGEN_NO_ASSERTION_CHECKING)
if(${ARGC} GREATER 1)
@@ -153,6 +161,10 @@ macro(ei_add_test testname)
target_link_libraries(${targetname} Eigen2)
endif(TEST_LIB)
if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)
target_link_libraries(${targetname} ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO})
endif()
target_link_libraries(${targetname} ${EXTERNAL_LIBS})
if(${ARGC} GREATER 2)
string(STRIP "${ARGV2}" ARGV2_stripped)
@@ -180,6 +192,7 @@ ei_add_test(meta)
ei_add_test(sizeof)
ei_add_test(dynalloc)
ei_add_test(nomalloc)
ei_add_test(first_aligned)
ei_add_test(mixingtypes)
ei_add_test(packetmath)
ei_add_test(unalignedassert)
@@ -200,7 +213,7 @@ ei_add_test(array)
ei_add_test(triangular)
ei_add_test(cholesky " " "${GSL_LIBRARIES}")
ei_add_test(lu ${EI_OFLAG})
ei_add_test(determinant)
ei_add_test(determinant ${EI_OFLAG})
ei_add_test(inverse)
ei_add_test(qr)
ei_add_test(eigensolver " " "${GSL_LIBRARIES}")
@@ -211,13 +224,21 @@ ei_add_test(parametrizedline)
ei_add_test(alignedbox)
ei_add_test(regression)
ei_add_test(stdvector)
ei_add_test(newstdvector)
if(QT4_FOUND)
ei_add_test(qtvector " " "${QT_QTCORE_LIBRARY}")
endif(QT4_FOUND)
ei_add_test(sparse_vector)
ei_add_test(sparse_basic)
ei_add_test(sparse_solvers " " "${SPARSE_LIBS}")
ei_add_test(sparse_product)
if(NOT EIGEN_DEFAULT_TO_ROW_MAJOR)
ei_add_test(sparse_vector)
ei_add_test(sparse_basic)
ei_add_test(sparse_solvers " " "${SPARSE_LIBS}")
ei_add_test(sparse_product)
endif()
ei_add_test(swap)
ei_add_test(visitor)
ei_add_test(bug_132)
ei_add_test(prec_inverse_4x4 ${EI_OFLAG})
# print a summary of the different options
message("************************************************************")
@@ -262,11 +283,22 @@ else(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)
message("Explicit vec: AUTO")
endif(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)
if(EIGEN_DEFAULT_TO_ROW_MAJOR)
message("Default order: Row-major")
else()
message("Default order: Column-major")
endif()
string(TOLOWER "${CMAKE_CXX_COMPILER}" cmake_cxx_compiler_tolower)
if(cmake_cxx_compiler_tolower MATCHES "qcc")
set(CXX_IS_QCC "ON")
endif()
message("CXX: ${CMAKE_CXX_COMPILER}")
if(CMAKE_COMPILER_IS_GNUCXX)
if(CMAKE_COMPILER_IS_GNUCXX AND NOT CXX_IS_QCC)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version COMMAND head -n 1 OUTPUT_VARIABLE EIGEN_CXX_VERSION_STRING OUTPUT_STRIP_TRAILING_WHITESPACE)
message("CXX_VERSION: ${EIGEN_CXX_VERSION_STRING}")
endif(CMAKE_COMPILER_IS_GNUCXX)
endif()
message("CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
message("Sparse lib flags: ${SPARSE_LIBS}")

41
test/bug_132.cpp Normal file
View File

@@ -0,0 +1,41 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// 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/>.
#include "main.h"
void test_bug_132() {
enum { size = 100 };
MatrixXd A(size, size);
VectorXd b(size), c(size);
{
VectorXd y = A.transpose() * (b-c); // bug 132: infinite recursion in coeffRef
VectorXd z = (b-c).transpose() * A; // bug 132: infinite recursion in coeffRef
}
// the following ones weren't failing, but let's include them for completeness:
{
VectorXd y = A * (b-c);
VectorXd z = (b-c).transpose() * A.transpose();
}
}

View File

@@ -100,6 +100,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
VERIFY_IS_APPROX(symm * matX, matB);
}
#if 0 // cholesky is not rank-revealing anyway
// test isPositiveDefinite on non definite matrix
if (rows>4)
{
@@ -109,6 +110,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
LDLT<SquareMatrixType> cholnosqrt(symm);
VERIFY(!cholnosqrt.isPositiveDefinite());
}
#endif
}
void test_cholesky()
@@ -122,4 +124,8 @@ void test_cholesky()
CALL_SUBTEST( cholesky(MatrixXf(17,17)) );
CALL_SUBTEST( cholesky(MatrixXd(33,33)) );
}
MatrixXf m = MatrixXf::Zero(10,10);
VectorXf b = VectorXf::Zero(10);
VERIFY(!m.llt().isPositiveDefinite());
}

View File

@@ -35,7 +35,7 @@ void check_handmade_aligned_malloc()
for(int i = 1; i < 1000; i++)
{
char *p = (char*)ei_handmade_aligned_malloc(i);
VERIFY(size_t(p)%ALIGNMENT==0);
VERIFY(std::size_t(p)%ALIGNMENT==0);
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
for(int j = 0; j < i; j++) p[j]=0;
ei_handmade_aligned_free(p);
@@ -47,7 +47,7 @@ void check_aligned_malloc()
for(int i = 1; i < 1000; i++)
{
char *p = (char*)ei_aligned_malloc(i);
VERIFY(size_t(p)%ALIGNMENT==0);
VERIFY(std::size_t(p)%ALIGNMENT==0);
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
for(int j = 0; j < i; j++) p[j]=0;
ei_aligned_free(p);
@@ -59,7 +59,7 @@ void check_aligned_new()
for(int i = 1; i < 1000; i++)
{
float *p = ei_aligned_new<float>(i);
VERIFY(size_t(p)%ALIGNMENT==0);
VERIFY(std::size_t(p)%ALIGNMENT==0);
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
for(int j = 0; j < i; j++) p[j]=0;
ei_aligned_delete(p,i);
@@ -71,7 +71,7 @@ void check_aligned_stack_alloc()
for(int i = 1; i < 1000; i++)
{
float *p = ei_aligned_stack_new(float,i);
VERIFY(size_t(p)%ALIGNMENT==0);
VERIFY(std::size_t(p)%ALIGNMENT==0);
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
for(int j = 0; j < i; j++) p[j]=0;
ei_aligned_stack_delete(float,p,i);
@@ -98,7 +98,7 @@ class MyClassA
template<typename T> void check_dynaligned()
{
T* obj = new T;
VERIFY(size_t(obj)%ALIGNMENT==0);
VERIFY(std::size_t(obj)%ALIGNMENT==0);
delete obj;
}
@@ -121,15 +121,15 @@ void test_dynalloc()
// check static allocation, who knows ?
{
MyStruct foo0; VERIFY(size_t(foo0.avec.data())%ALIGNMENT==0);
MyClassA fooA; VERIFY(size_t(fooA.avec.data())%ALIGNMENT==0);
MyStruct foo0; VERIFY(std::size_t(foo0.avec.data())%ALIGNMENT==0);
MyClassA fooA; VERIFY(std::size_t(fooA.avec.data())%ALIGNMENT==0);
}
// dynamic allocation, single object
for (int i=0; i<g_repeat*100; ++i)
{
MyStruct *foo0 = new MyStruct(); VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0);
MyClassA *fooA = new MyClassA(); VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0);
MyStruct *foo0 = new MyStruct(); VERIFY(std::size_t(foo0->avec.data())%ALIGNMENT==0);
MyClassA *fooA = new MyClassA(); VERIFY(std::size_t(fooA->avec.data())%ALIGNMENT==0);
delete foo0;
delete fooA;
}
@@ -138,8 +138,8 @@ void test_dynalloc()
const int N = 10;
for (int i=0; i<g_repeat*100; ++i)
{
MyStruct *foo0 = new MyStruct[N]; VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0);
MyClassA *fooA = new MyClassA[N]; VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0);
MyStruct *foo0 = new MyStruct[N]; VERIFY(std::size_t(foo0->avec.data())%ALIGNMENT==0);
MyClassA *fooA = new MyClassA[N]; VERIFY(std::size_t(fooA->avec.data())%ALIGNMENT==0);
delete[] foo0;
delete[] fooA;
}

64
test/first_aligned.cpp Normal file
View File

@@ -0,0 +1,64 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#include "main.h"
template<typename Scalar>
void test_first_aligned_helper(Scalar *array, int size)
{
const int packet_size = sizeof(Scalar) * ei_packet_traits<Scalar>::size;
VERIFY(((std::size_t(array) + sizeof(Scalar) * ei_alignmentOffset(array, size)) % packet_size) == 0);
}
template<typename Scalar>
void test_none_aligned_helper(Scalar *array, int size)
{
VERIFY(ei_packet_traits<Scalar>::size == 1 || ei_alignmentOffset(array, size) == size);
}
struct some_non_vectorizable_type { float x; };
void test_first_aligned()
{
EIGEN_ALIGN_128 float array_float[100];
test_first_aligned_helper(array_float, 50);
test_first_aligned_helper(array_float+1, 50);
test_first_aligned_helper(array_float+2, 50);
test_first_aligned_helper(array_float+3, 50);
test_first_aligned_helper(array_float+4, 50);
test_first_aligned_helper(array_float+5, 50);
EIGEN_ALIGN_128 double array_double[100];
test_first_aligned_helper(array_double, 50);
test_first_aligned_helper(array_double+1, 50);
test_first_aligned_helper(array_double+2, 50);
double *array_double_plus_4_bytes = (double*)(std::size_t(array_double)+4);
test_none_aligned_helper(array_double_plus_4_bytes, 50);
test_none_aligned_helper(array_double_plus_4_bytes+1, 50);
some_non_vectorizable_type array_nonvec[100];
test_first_aligned_helper(array_nonvec, 100);
test_none_aligned_helper(array_nonvec, 100);
}

View File

@@ -151,7 +151,13 @@ template<typename Scalar> void geometry(void)
a = ei_random<Scalar>(-Scalar(0.4)*Scalar(M_PI), Scalar(0.4)*Scalar(M_PI));
q1 = AngleAxisx(a, v0.normalized());
Transform3 t0, t1, t2;
// first test setIdentity() and Identity()
t0.setIdentity();
VERIFY_IS_APPROX(t0.matrix(), Transform3::MatrixType::Identity());
t0.matrix().setZero();
t0 = Transform3::Identity();
VERIFY_IS_APPROX(t0.matrix(), Transform3::MatrixType::Identity());
t0.linear() = q1.toRotationMatrix();
t1.setIdentity();
t1.linear() = q1.toRotationMatrix();

View File

@@ -121,7 +121,8 @@ template<typename Scalar> void lines()
VERIFY_IS_APPROX(result, center);
// check conversions between two types of lines
CoeffsType converted_coeffs(HLine(PLine(line_u)).coeffs());
PLine pl(line_u); // gcc 3.3 will commit suicide if we don't name this variable
CoeffsType converted_coeffs(HLine(pl).coeffs());
converted_coeffs *= line_u.coeffs()(0)/converted_coeffs(0);
VERIFY(line_u.coeffs().isApprox(converted_coeffs));
}

View File

@@ -43,11 +43,9 @@ template<typename MatrixType> void inverse(const MatrixType& m)
mzero = MatrixType::Zero(rows, cols),
identity = MatrixType::Identity(rows, rows);
if (ei_is_same_type<RealScalar,float>::ret)
while(ei_abs(m1.determinant()) < RealScalar(0.1) && rows <= 8)
{
// let's build a more stable to inverse matrix
MatrixType a = MatrixType::Random(rows,cols);
m1 += m1 * m1.adjoint() + a * a.adjoint();
m1 = MatrixType::Random(rows, cols);
}
m2 = m1.inverse();

View File

@@ -132,4 +132,10 @@ void test_lu()
CALL_SUBTEST( lu_invertible<MatrixXcf>() );
CALL_SUBTEST( lu_invertible<MatrixXcd>() );
}
MatrixXf m = MatrixXf::Zero(10,10);
VectorXf b = VectorXf::Zero(10);
VectorXf x = VectorXf::Random(10);
VERIFY(m.lu().solve(b,&x));
VERIFY(x.isZero());
}

View File

@@ -142,7 +142,7 @@ namespace Eigen
#define VERIFY(a) do { if (!(a)) { \
std::cerr << "Test " << g_test_stack.back() << " failed in "EI_PP_MAKE_STRING(__FILE__) << " (" << EI_PP_MAKE_STRING(__LINE__) << ")" \
<< std::endl << " " << EI_PP_MAKE_STRING(a) << std::endl << std::endl; \
exit(2); \
std::exit(2); \
} } while (0)
#define VERIFY_IS_APPROX(a, b) VERIFY(test_ei_isApprox(a, b))
@@ -257,7 +257,7 @@ int main(int argc, char *argv[])
std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
return 1;
}
repeat = atoi(argv[i]+1);
repeat = std::atoi(argv[i]+1);
has_set_repeat = true;
if(repeat <= 0)
{
@@ -272,7 +272,7 @@ int main(int argc, char *argv[])
std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
return 1;
}
seed = int(strtoul(argv[i]+1, 0, 10));
seed = int(std::strtoul(argv[i]+1, 0, 10));
has_set_seed = true;
bool ok = seed!=0;
if(!ok)
@@ -295,11 +295,11 @@ int main(int argc, char *argv[])
return 1;
}
if(!has_set_seed) seed = (unsigned int) time(NULL);
if(!has_set_seed) seed = (unsigned int) std::time(NULL);
if(!has_set_repeat) repeat = DEFAULT_REPEAT;
std::cout << "Initializing random number generator with seed " << seed << std::endl;
srand(seed);
std::srand(seed);
std::cout << "Repeating each test " << repeat << " times" << std::endl;
Eigen::g_repeat = repeat;

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.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2007-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
@@ -24,7 +24,7 @@
#include "main.h"
template<typename VectorType> void map_class(const VectorType& m)
template<typename VectorType> void map_class_vector(const VectorType& m)
{
typedef typename VectorType::Scalar Scalar;
@@ -34,7 +34,7 @@ template<typename VectorType> void map_class(const VectorType& m)
Scalar* array1 = ei_aligned_new<Scalar>(size);
Scalar* array2 = ei_aligned_new<Scalar>(size);
Scalar* array3 = new Scalar[size+1];
Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;
Scalar* array3unaligned = std::size_t(array3)%16 == 0 ? array3+1 : array3;
Map<VectorType, Aligned>(array1, size) = VectorType::Random(size);
Map<VectorType>(array2, size) = Map<VectorType>(array1, size);
@@ -50,6 +50,34 @@ template<typename VectorType> void map_class(const VectorType& m)
delete[] array3;
}
template<typename MatrixType> void map_class_matrix(const MatrixType& m)
{
typedef typename MatrixType::Scalar Scalar;
int rows = m.rows(), cols = m.cols(), size = rows*cols;
// test Map.h
Scalar* array1 = ei_aligned_new<Scalar>(size);
for(int i = 0; i < size; i++) array1[i] = Scalar(1);
Scalar* array2 = ei_aligned_new<Scalar>(size);
for(int i = 0; i < size; i++) array2[i] = Scalar(1);
Scalar* array3 = new Scalar[size+1];
for(int i = 0; i < size+1; i++) array3[i] = Scalar(1);
Scalar* array3unaligned = std::size_t(array3)%16 == 0 ? array3+1 : array3;
Map<MatrixType, Aligned>(array1, rows, cols) = MatrixType::Ones(rows,cols);
Map<MatrixType>(array2, rows, cols) = Map<MatrixType>(array1, rows, cols);
Map<MatrixType>(array3unaligned, rows, cols) = Map<MatrixType>(array1, rows, cols);
MatrixType ma1 = Map<MatrixType>(array1, rows, cols);
MatrixType ma2 = Map<MatrixType, Aligned>(array2, rows, cols);
VERIFY_IS_APPROX(ma1, ma2);
MatrixType ma3 = Map<MatrixType>(array3unaligned, rows, cols);
VERIFY_IS_APPROX(ma1, ma3);
ei_aligned_delete(array1, size);
ei_aligned_delete(array2, size);
delete[] array3;
}
template<typename VectorType> void map_static_methods(const VectorType& m)
{
typedef typename VectorType::Scalar Scalar;
@@ -60,7 +88,7 @@ template<typename VectorType> void map_static_methods(const VectorType& m)
Scalar* array1 = ei_aligned_new<Scalar>(size);
Scalar* array2 = ei_aligned_new<Scalar>(size);
Scalar* array3 = new Scalar[size+1];
Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;
Scalar* array3unaligned = std::size_t(array3)%16 == 0 ? array3+1 : array3;
VectorType::MapAligned(array1, size) = VectorType::Random(size);
VectorType::Map(array2, size) = VectorType::Map(array1, size);
@@ -80,11 +108,17 @@ template<typename VectorType> void map_static_methods(const VectorType& m)
void test_map()
{
for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST( map_class(Matrix<float, 1, 1>()) );
CALL_SUBTEST( map_class(Vector4d()) );
CALL_SUBTEST( map_class(RowVector4f()) );
CALL_SUBTEST( map_class(VectorXcf(8)) );
CALL_SUBTEST( map_class(VectorXi(12)) );
CALL_SUBTEST( map_class_vector(Matrix<float, 1, 1>()) );
CALL_SUBTEST( map_class_vector(Vector4d()) );
CALL_SUBTEST( map_class_vector(RowVector4f()) );
CALL_SUBTEST( map_class_vector(VectorXcf(8)) );
CALL_SUBTEST( map_class_vector(VectorXi(12)) );
CALL_SUBTEST( map_class_matrix(Matrix<float, 1, 1>()) );
CALL_SUBTEST( map_class_matrix(Matrix4d()) );
CALL_SUBTEST( map_class_matrix(Matrix<float,3,5>()) );
CALL_SUBTEST( map_class_matrix(MatrixXcf(ei_random<int>(1,10),ei_random<int>(1,10))) );
CALL_SUBTEST( map_class_matrix(MatrixXi(ei_random<int>(1,10),ei_random<int>(1,10))) );
CALL_SUBTEST( map_static_methods(Matrix<double, 1, 1>()) );
CALL_SUBTEST( map_static_methods(Vector3f()) );

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