mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Compare commits
1822 Commits
3.2.1
...
3.3-alpha1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9303cc7c5 | ||
|
|
b20a55a608 | ||
|
|
ed265258e4 | ||
|
|
a835dfca73 | ||
|
|
941a99ac1a | ||
|
|
d91db41a31 | ||
|
|
3942db9d7c | ||
|
|
5c9ee73eb9 | ||
|
|
5a1cc5d24c | ||
|
|
2795ffd6a0 | ||
|
|
ef2b54f422 | ||
|
|
5ad7981f73 | ||
|
|
aa768add0b | ||
|
|
51455824ea | ||
|
|
f8976fdbe0 | ||
|
|
92b9f0e102 | ||
|
|
cda55ab245 | ||
|
|
14458ec0a0 | ||
|
|
6b99afa5ae | ||
|
|
b5ad3d2cf7 | ||
|
|
6522c3a6f0 | ||
|
|
be5e2ecc21 | ||
|
|
aba8c9ee17 | ||
|
|
a75616887e | ||
|
|
280f93ff65 | ||
|
|
6059188f9d | ||
|
|
0b2412df50 | ||
|
|
9001f4a46b | ||
|
|
f41831e445 | ||
|
|
2ab603316a | ||
|
|
2ed1495eec | ||
|
|
d4c24eb016 | ||
|
|
78358a7241 | ||
|
|
a09cfe650f | ||
|
|
e5c78d85c8 | ||
|
|
1bdd06a199 | ||
|
|
0721690dbb | ||
|
|
8097d8d028 | ||
|
|
d2e0927127 | ||
|
|
dc2c103b3b | ||
|
|
d6a4805fdf | ||
|
|
a40f6ab276 | ||
|
|
61e0977e10 | ||
|
|
712e2fed17 | ||
|
|
a5d1bb2be8 | ||
|
|
93635cafee | ||
|
|
23aab82c0c | ||
|
|
0d5e673baa | ||
|
|
cac6b23033 | ||
|
|
febcce34f1 | ||
|
|
6245591349 | ||
|
|
60e4260d0d | ||
|
|
e68c7b8368 | ||
|
|
65bfa5fce7 | ||
|
|
3602926ed5 | ||
|
|
ce57dbd937 | ||
|
|
2afdef6a54 | ||
|
|
1f5024332e | ||
|
|
65186ef18d | ||
|
|
becd89df29 | ||
|
|
d4f5efc51a | ||
|
|
7e0d7a76b8 | ||
|
|
e31fc50280 | ||
|
|
9a4713e505 | ||
|
|
506964fc29 | ||
|
|
db0f5c9d90 | ||
|
|
b986c147cd | ||
|
|
cbce0e3b12 | ||
|
|
a5dc49e7e8 | ||
|
|
e1d28b7ea7 | ||
|
|
0570594f2c | ||
|
|
099597406f | ||
|
|
6db3a557f4 | ||
|
|
aec4814370 | ||
|
|
f7d5b9323d | ||
|
|
175ed636ea | ||
|
|
76874b128e | ||
|
|
41e1f3498c | ||
|
|
b9db19aec4 | ||
|
|
f84417d97b | ||
|
|
1a30a8e7a2 | ||
|
|
a44d022caf | ||
|
|
2195822df6 | ||
|
|
f6282e451a | ||
|
|
4b3052c54d | ||
|
|
a446020b78 | ||
|
|
3d951df223 | ||
|
|
6d6e6d0b88 | ||
|
|
ce65c2922a | ||
|
|
4200bdec24 | ||
|
|
3b0ad02c10 | ||
|
|
815fa0dbf6 | ||
|
|
d259b719d1 | ||
|
|
0dda72316f | ||
|
|
586d10f7e0 | ||
|
|
d3e5db9a80 | ||
|
|
5e635f9ca1 | ||
|
|
45ee14a13a | ||
|
|
87f3e533f5 | ||
|
|
ab8b497a7e | ||
|
|
6544b49e59 | ||
|
|
2d93060291 | ||
|
|
c11971de37 | ||
|
|
88e352adac | ||
|
|
6799c26cd6 | ||
|
|
7a39439904 | ||
|
|
e94f9eb637 | ||
|
|
513e357b48 | ||
|
|
943035e5bd | ||
|
|
06a22ca5bd | ||
|
|
3275eddc24 | ||
|
|
979b73cebf | ||
|
|
a5ec25f11c | ||
|
|
7a243959b4 | ||
|
|
b756f6af5e | ||
|
|
05787f8367 | ||
|
|
b900fe47d5 | ||
|
|
4b3d697e12 | ||
|
|
8315e025e1 | ||
|
|
e892524efe | ||
|
|
f5aa640862 | ||
|
|
7cecd39a84 | ||
|
|
592ee2a4b4 | ||
|
|
6527dbb9f8 | ||
|
|
b80036abec | ||
|
|
3912ca0d53 | ||
|
|
ea87561564 | ||
|
|
b8df8815f4 | ||
|
|
002c2923c2 | ||
|
|
dbb3e2cf8a | ||
|
|
0d09845562 | ||
|
|
20b96025fd | ||
|
|
1dd6a329e8 | ||
|
|
bc40eb745d | ||
|
|
e6297741c9 | ||
|
|
6de6fa9483 | ||
|
|
7b7df7b6b8 | ||
|
|
6e55284e51 | ||
|
|
a93af65938 | ||
|
|
7fa6fe8d8c | ||
|
|
fa17358c4b | ||
|
|
3f2101b03b | ||
|
|
0485a2468d | ||
|
|
ebdacfc5ea | ||
|
|
81f9e968fd | ||
|
|
66b30728f8 | ||
|
|
5359e5cdb2 | ||
|
|
864318e508 | ||
|
|
c2019dfeb3 | ||
|
|
ea7113dd0c | ||
|
|
9115896590 | ||
|
|
95ef94f1ee | ||
|
|
8f1d547c92 | ||
|
|
1e911b276c | ||
|
|
4ed213f97b | ||
|
|
56e155dd60 | ||
|
|
925d0d375a | ||
|
|
44eedd8915 | ||
|
|
6021b68d8b | ||
|
|
f1f480b116 | ||
|
|
dc31fcb9ba | ||
|
|
f587075987 | ||
|
|
28b36632ec | ||
|
|
109005c6c9 | ||
|
|
a4aa7c6217 | ||
|
|
7d41e97fa9 | ||
|
|
fffe63045c | ||
|
|
db9dbbda32 | ||
|
|
f0ce85b757 | ||
|
|
670c71d906 | ||
|
|
d8098ee7d5 | ||
|
|
3625734bc8 | ||
|
|
392a30db82 | ||
|
|
c911fc8dee | ||
|
|
98ff17eb9e | ||
|
|
e102ddbf1f | ||
|
|
555b9c6843 | ||
|
|
53b930887d | ||
|
|
3f49cf4c90 | ||
|
|
7f824dd613 | ||
|
|
c5f9eafcbc | ||
|
|
33e699c9fe | ||
|
|
6b4d255cab | ||
|
|
973b0a90db | ||
|
|
84264ceebc | ||
|
|
b4ab72678c | ||
|
|
788941d3b1 | ||
|
|
4c8cd13b35 | ||
|
|
c38c195321 | ||
|
|
23535ed31c | ||
|
|
62f21e2d11 | ||
|
|
763c833637 | ||
|
|
36643eec0c | ||
|
|
02db7c9bc6 | ||
|
|
53a61a067b | ||
|
|
95e19be381 | ||
|
|
2a33075aeb | ||
|
|
23da99492f | ||
|
|
6441befbb3 | ||
|
|
c3e398d138 | ||
|
|
b0d08869a9 | ||
|
|
18c9d155f3 | ||
|
|
71523a2e25 | ||
|
|
d9778f3391 | ||
|
|
5f9630d7f9 | ||
|
|
793e4c6d77 | ||
|
|
307c4fc292 | ||
|
|
bb3a9b4941 | ||
|
|
476beed7f8 | ||
|
|
9fc1c92137 | ||
|
|
9c7cfa7dab | ||
|
|
3ccd23efc0 | ||
|
|
0848ba0a6e | ||
|
|
b3b3dcad05 | ||
|
|
ad5fdc7ddd | ||
|
|
40821876ea | ||
|
|
7043083be4 | ||
|
|
84aaef93ba | ||
|
|
6b33b29f00 | ||
|
|
846b227bb7 | ||
|
|
368ea23406 | ||
|
|
4cc0c961f3 | ||
|
|
386d9e5ebd | ||
|
|
a5a7b68b76 | ||
|
|
6fc5438205 | ||
|
|
e9edb085c0 | ||
|
|
6318d53b41 | ||
|
|
5c84dd5665 | ||
|
|
0c8b0e007b | ||
|
|
3f6aa4cd5d | ||
|
|
4a8888dfbc | ||
|
|
3af4c6c1c9 | ||
|
|
82b6ac0864 | ||
|
|
fad36cc814 | ||
|
|
06036d8bb1 | ||
|
|
d2db15016b | ||
|
|
6a9a29e96f | ||
|
|
bb6acc561e | ||
|
|
40f326ef2e | ||
|
|
ab5db86fe9 | ||
|
|
ea160a898c | ||
|
|
367794e668 | ||
|
|
736a805883 | ||
|
|
9ab8ac5c8b | ||
|
|
38874b1651 | ||
|
|
e2e66930c6 | ||
|
|
7baa1ba03e | ||
|
|
97cbe28829 | ||
|
|
972a535288 | ||
|
|
e5b490b654 | ||
|
|
a546be56e0 | ||
|
|
3946c981b1 | ||
|
|
2212e40e95 | ||
|
|
321a2cbe3d | ||
|
|
2f2a441a4d | ||
|
|
91b64a9c65 | ||
|
|
84d103bee8 | ||
|
|
916ef52fff | ||
|
|
d93ba137f2 | ||
|
|
9756c7fb4d | ||
|
|
93a62265dc | ||
|
|
b0d5aaafcc | ||
|
|
25a98be948 | ||
|
|
192bce2795 | ||
|
|
e6832ce93d | ||
|
|
0b2cbb2bdc | ||
|
|
feaf76c001 | ||
|
|
f899aeb301 | ||
|
|
785b9c0127 | ||
|
|
0eb06f1391 | ||
|
|
64753af3b7 | ||
|
|
cacbc5679d | ||
|
|
04665ef9e1 | ||
|
|
d4c574707e | ||
|
|
f9350e70eb | ||
|
|
4aba24a1b2 | ||
|
|
302cf8ffe2 | ||
|
|
3a4299b245 | ||
|
|
9aef0db992 | ||
|
|
9a2447b0c9 | ||
|
|
cd8b996f99 | ||
|
|
913a61870d | ||
|
|
8f031a3cee | ||
|
|
e6c5723dcd | ||
|
|
274b1f5d7e | ||
|
|
cbe3a1a83e | ||
|
|
a7ae628c9f | ||
|
|
0a9b5d1396 | ||
|
|
d0b7b5cb55 | ||
|
|
56d4ef7ad6 | ||
|
|
98a8d43457 | ||
|
|
b685660b22 | ||
|
|
8bc26562f4 | ||
|
|
3e7bc8d686 | ||
|
|
acc761cf0c | ||
|
|
ea1190486f | ||
|
|
0e5fed74e7 | ||
|
|
f13b3d4433 | ||
|
|
abec18bae0 | ||
|
|
9df186c140 | ||
|
|
466bcc589e | ||
|
|
d457734a19 | ||
|
|
6b800744ce | ||
|
|
48f6b274e2 | ||
|
|
2451679951 | ||
|
|
a81d17b73a | ||
|
|
051d5325cc | ||
|
|
ebea530782 | ||
|
|
c88e1abaf3 | ||
|
|
807793ec3b | ||
|
|
140f85bb99 | ||
|
|
a852001196 | ||
|
|
e66caf48e8 | ||
|
|
ef81730625 | ||
|
|
a605a1d7df | ||
|
|
447e060b81 | ||
|
|
494fa991c3 | ||
|
|
4a936974a5 | ||
|
|
c2107d30ce | ||
|
|
ebf8ca4fa8 | ||
|
|
dd698e6680 | ||
|
|
1dded10cb7 | ||
|
|
6273aca9b1 | ||
|
|
4dd7d0b5dc | ||
|
|
4b9eddaef8 | ||
|
|
28a4c92cbf | ||
|
|
173b34e9ab | ||
|
|
da2baf685d | ||
|
|
8c6a3b5ace | ||
|
|
de18cd413d | ||
|
|
1681a665d9 | ||
|
|
834f66e9fc | ||
|
|
40258078c6 | ||
|
|
c460af414e | ||
|
|
fd1d4bd86c | ||
|
|
91359e1d0a | ||
|
|
8838ed39f4 | ||
|
|
e7457e419d | ||
|
|
dfa991cbae | ||
|
|
dbd12b4cda | ||
|
|
d6a8b43b39 | ||
|
|
e709488361 | ||
|
|
10a1f81822 | ||
|
|
e5048b5501 | ||
|
|
249c48ba00 | ||
|
|
0250f4a9f2 | ||
|
|
0339502a4f | ||
|
|
43eb2ca6e1 | ||
|
|
016c29f207 | ||
|
|
70bc3b0668 | ||
|
|
3220eb2b93 | ||
|
|
fc2d5b86ce | ||
|
|
5a3c48e3c6 | ||
|
|
3b429b71e6 | ||
|
|
9c6b82bcd5 | ||
|
|
4f126b862d | ||
|
|
da5b98a94d | ||
|
|
d19d09ae6a | ||
|
|
9d7843d0d0 | ||
|
|
3be9f5c4d7 | ||
|
|
e0cff9ae0d | ||
|
|
5dbe758dc3 | ||
|
|
04c8c5d9ef | ||
|
|
0f82399fe9 | ||
|
|
761691f18d | ||
|
|
5401fbcc50 | ||
|
|
085aa8e601 | ||
|
|
0eb220c00d | ||
|
|
d7f51feb07 | ||
|
|
0e9753c8df | ||
|
|
1de49ef4c2 | ||
|
|
a1f1e1e51d | ||
|
|
7c18ab921c | ||
|
|
15b5adb327 | ||
|
|
74e558cfa8 | ||
|
|
03a0df2010 | ||
|
|
b8b7807269 | ||
|
|
383b6dfafe | ||
|
|
5861cfb55e | ||
|
|
3105986e71 | ||
|
|
39dcd01b0a | ||
|
|
8481dc21ea | ||
|
|
79b4e6acaf | ||
|
|
3c38589984 | ||
|
|
8313fb7df7 | ||
|
|
dfb674a25e | ||
|
|
20d030f207 | ||
|
|
678207e02a | ||
|
|
68d4afe985 | ||
|
|
f873686602 | ||
|
|
73cdeae1d3 | ||
|
|
0cbd5ae3cb | ||
|
|
ae01c05e18 | ||
|
|
bd76d837e6 | ||
|
|
35d3053d55 | ||
|
|
731d7b84b4 | ||
|
|
7bd578d11d | ||
|
|
3b169d792d | ||
|
|
3238ca6abc | ||
|
|
1efae98fee | ||
|
|
35722fa022 | ||
|
|
71950f02e5 | ||
|
|
58af8bf90c | ||
|
|
2adbf6b8ca | ||
|
|
41e20248f8 | ||
|
|
09a5361d1b | ||
|
|
266a84558f | ||
|
|
1b4bb20cf1 | ||
|
|
eb7e4c2b9c | ||
|
|
ad044008da | ||
|
|
79cb875249 | ||
|
|
7e225b6fa4 | ||
|
|
1b8cc9af43 | ||
|
|
3d59ae0203 | ||
|
|
4df8b5a75e | ||
|
|
b3343bfdae | ||
|
|
ccf290a65c | ||
|
|
d3f7915aeb | ||
|
|
abdbe8562e | ||
|
|
29eaa2b0f1 | ||
|
|
f42b105f73 | ||
|
|
d27968eb7e | ||
|
|
4472f3e578 | ||
|
|
83e5b7656b | ||
|
|
4bab4790c0 | ||
|
|
4e2b18d909 | ||
|
|
8d9bfb3a7b | ||
|
|
a6a628ca6b | ||
|
|
e134226a03 | ||
|
|
9ee62fdcd5 | ||
|
|
d6b2f300db | ||
|
|
61c45d7cfd | ||
|
|
d7698c18b7 | ||
|
|
f329d0908a | ||
|
|
2ab4922431 | ||
|
|
41b717de25 | ||
|
|
cc0f89eb3b | ||
|
|
dc04f12967 | ||
|
|
8878e1c1de | ||
|
|
596be3cd86 | ||
|
|
e26134ed62 | ||
|
|
e21e29a088 | ||
|
|
447a5a6b01 | ||
|
|
f52b78491c | ||
|
|
1c78d6f2a6 | ||
|
|
85da0c2281 | ||
|
|
364cfd529d | ||
|
|
25664afacd | ||
|
|
e1d6e6c972 | ||
|
|
577056aa94 | ||
|
|
5144f66728 | ||
|
|
0fd6d52724 | ||
|
|
eb6929cb19 | ||
|
|
f218c0181d | ||
|
|
fef4e071d7 | ||
|
|
46cf9cda32 | ||
|
|
7b829940d1 | ||
|
|
1d76ceab55 | ||
|
|
717b7954ce | ||
|
|
fb68b149cb | ||
|
|
35c3a8bb84 | ||
|
|
e274607d7f | ||
|
|
151b8b95c6 | ||
|
|
02babb9c0f | ||
|
|
3589a9c115 | ||
|
|
1dd3d89818 | ||
|
|
ca5c12587b | ||
|
|
e56aabf205 | ||
|
|
b6b88c0808 | ||
|
|
488c15615a | ||
|
|
9f58524cbd | ||
|
|
1330f8bbd1 | ||
|
|
d99ab35f9e | ||
|
|
8580eb6808 | ||
|
|
a9df28c95b | ||
|
|
5ffe29cb9f | ||
|
|
d73ccd717e | ||
|
|
2f6f8bf31c | ||
|
|
f2c3e2b10f | ||
|
|
657407227e | ||
|
|
f89fcefa79 | ||
|
|
a5e49976f5 | ||
|
|
19a71056ae | ||
|
|
31fdd67756 | ||
|
|
fd78874888 | ||
|
|
d4317a85e8 | ||
|
|
9e885fb766 | ||
|
|
224a1fe4c6 | ||
|
|
cf9940e17b | ||
|
|
39228cb224 | ||
|
|
a4f956b1da | ||
|
|
19bf13aa62 | ||
|
|
0ee391863e | ||
|
|
14a5f135a3 | ||
|
|
d23fcc0672 | ||
|
|
87681e508f | ||
|
|
4c8eeeaed6 | ||
|
|
cd3bbffa73 | ||
|
|
eedd5063fd | ||
|
|
58740ce4c6 | ||
|
|
4ab01f7c21 | ||
|
|
5db2baa573 | ||
|
|
4c8b95d5c5 | ||
|
|
7550107028 | ||
|
|
2dc968e453 | ||
|
|
2231b3dece | ||
|
|
00ea121881 | ||
|
|
0196141938 | ||
|
|
b0f2b6f297 | ||
|
|
d9cb604a5d | ||
|
|
4fd7f47692 | ||
|
|
ae73859a0a | ||
|
|
131449298f | ||
|
|
56ea45ff0f | ||
|
|
bb483313f6 | ||
|
|
fb53384b0f | ||
|
|
61409d9449 | ||
|
|
1a7b84dc75 | ||
|
|
37357a310f | ||
|
|
cf1eea11de | ||
|
|
78732186ee | ||
|
|
4250a0cab0 | ||
|
|
a4e37b0617 | ||
|
|
306fceccbe | ||
|
|
75e7f381c8 | ||
|
|
2386fc8528 | ||
|
|
e1f6a45b14 | ||
|
|
90893bbe18 | ||
|
|
473e6d4c3d | ||
|
|
4369538227 | ||
|
|
99cfbd6e84 | ||
|
|
6466fa63be | ||
|
|
05089aba75 | ||
|
|
bf9877a92a | ||
|
|
90f4e90f1d | ||
|
|
573b377110 | ||
|
|
2fc3b484d7 | ||
|
|
33669348c4 | ||
|
|
f5ff4d826f | ||
|
|
b7fc8746e0 | ||
|
|
f074bb4b5f | ||
|
|
57154fdb32 | ||
|
|
f41b1f1666 | ||
|
|
2fffe69b1b | ||
|
|
bcf9bb5c1f | ||
|
|
4ec3f04b3a | ||
|
|
2e9cb06a87 | ||
|
|
a46061ab7b | ||
|
|
a8ad8887bf | ||
|
|
400becc591 | ||
|
|
bffb6bdf45 | ||
|
|
27f3fb2bcc | ||
|
|
f8fbb3f9a6 | ||
|
|
8e817b65d0 | ||
|
|
410070e5ab | ||
|
|
1cfd51908c | ||
|
|
eb21a8173e | ||
|
|
8afce86e64 | ||
|
|
692136350b | ||
|
|
531fa9de77 | ||
|
|
26275b250a | ||
|
|
488874781b | ||
|
|
052b6b40f1 | ||
|
|
ecbf2a6656 | ||
|
|
6af6cf0c2e | ||
|
|
3cf642baa3 | ||
|
|
458cf91cd9 | ||
|
|
03ec601ff7 | ||
|
|
333b497383 | ||
|
|
2da1594750 | ||
|
|
01b8440579 | ||
|
|
3594451ee0 | ||
|
|
b192e29eae | ||
|
|
ab41652d81 | ||
|
|
7765039f1c | ||
|
|
a66f5fc2fd | ||
|
|
ece6b440f9 | ||
|
|
1b7e12847d | ||
|
|
0f4dd15dfc | ||
|
|
92ceb02c6d | ||
|
|
110fb90250 | ||
|
|
829dddd0fd | ||
|
|
db05f2d01e | ||
|
|
0ed00d5438 | ||
|
|
9bd8a4bab5 | ||
|
|
ee27d50633 | ||
|
|
73a24de424 | ||
|
|
63eb0f6fe6 | ||
|
|
fc5c3e85e2 | ||
|
|
4a3e6c8be1 | ||
|
|
c7bb1e8ea8 | ||
|
|
168ceb271e | ||
|
|
8fdcaded5e | ||
|
|
c43154bbc5 | ||
|
|
1ce0178363 | ||
|
|
3dca4a1efc | ||
|
|
05274219a7 | ||
|
|
2aa09e6b4e | ||
|
|
5d2fd64a1a | ||
|
|
f64b4480af | ||
|
|
eae8e27b7d | ||
|
|
37a93c4263 | ||
|
|
ccc1277a42 | ||
|
|
f839099512 | ||
|
|
9930e9583b | ||
|
|
1ec0f4fadf | ||
|
|
3109f0e74e | ||
|
|
ef09ce4552 | ||
|
|
3a4b6827b4 | ||
|
|
31e2ffe82c | ||
|
|
73dd95e7b0 | ||
|
|
682196e9fc | ||
|
|
33f40b2883 | ||
|
|
0f82a1d7b7 | ||
|
|
9aee1e300a | ||
|
|
b10cd3afd2 | ||
|
|
4084dce038 | ||
|
|
548b781380 | ||
|
|
6f4adc9e94 | ||
|
|
371d3bef36 | ||
|
|
63464754ef | ||
|
|
eb563049f7 | ||
|
|
dc7e6acc05 | ||
|
|
d4eda01488 | ||
|
|
24d65ac0b0 | ||
|
|
20cac72b82 | ||
|
|
36c9d08274 | ||
|
|
f77054f43c | ||
|
|
1d3b64d32b | ||
|
|
00f048d44f | ||
|
|
97a36ecba4 | ||
|
|
159fb181c2 | ||
|
|
91ab2489dd | ||
|
|
9daf8eba6f | ||
|
|
3373c903b3 | ||
|
|
9f49f00feb | ||
|
|
f0b1b1df9b | ||
|
|
8768ff3c31 | ||
|
|
64b29e06b9 | ||
|
|
1c0e8bcf09 | ||
|
|
69fa405096 | ||
|
|
0f464d9d87 | ||
|
|
470d26d580 | ||
|
|
4dded73227 | ||
|
|
953d5ccfd5 | ||
|
|
98604576d1 | ||
|
|
45cbb0bbb1 | ||
|
|
cc641aabb7 | ||
|
|
aa6c516ec1 | ||
|
|
bd511dde9d | ||
|
|
e2cfddf75f | ||
|
|
0927801a84 | ||
|
|
e972b55ec4 | ||
|
|
fc202bab39 | ||
|
|
fe51319980 | ||
|
|
0918c51e60 | ||
|
|
409547a0c8 | ||
|
|
4470c99975 | ||
|
|
6620aaa4b3 | ||
|
|
f669f5656a | ||
|
|
029d236ceb | ||
|
|
fe25f3b8e3 | ||
|
|
ceb4c9c10b | ||
|
|
cc5d7ff523 | ||
|
|
d771295554 | ||
|
|
fefec723aa | ||
|
|
780b2422e2 | ||
|
|
c21e45fbc5 | ||
|
|
057cfd2f02 | ||
|
|
114e863f08 | ||
|
|
410895a7e4 | ||
|
|
4716c2c666 | ||
|
|
91fe3a3004 | ||
|
|
c3f3580b8f | ||
|
|
deecff97ed | ||
|
|
c6e8caf090 | ||
|
|
d10d6a40dd | ||
|
|
87629cd639 | ||
|
|
bde98df03f | ||
|
|
d4ec48575e | ||
|
|
554aa9b31d | ||
|
|
3af29caae8 | ||
|
|
f2ff8c091e | ||
|
|
f3be317614 | ||
|
|
08081f8293 | ||
|
|
7838fda82c | ||
|
|
3ba6647398 | ||
|
|
01f7918788 | ||
|
|
b50ffaddf2 | ||
|
|
74e460b995 | ||
|
|
c03c73c9b7 | ||
|
|
668518aed6 | ||
|
|
c739102ef9 | ||
|
|
2559fa9b0f | ||
|
|
dcb2a8b184 | ||
|
|
a8f2c6eec7 | ||
|
|
b1eca55328 | ||
|
|
ebdf6a2dbb | ||
|
|
f64045a060 | ||
|
|
590f4b0aa3 | ||
|
|
5ef95fabee | ||
|
|
0f21613698 | ||
|
|
340b8afb14 | ||
|
|
9f99f61e69 | ||
|
|
759bd92a85 | ||
|
|
f1092d2f73 | ||
|
|
9d82f7e30d | ||
|
|
e896c0ade7 | ||
|
|
5a6ea4edf6 | ||
|
|
a727a2c4ed | ||
|
|
9dfdbd7e56 | ||
|
|
46fc881e4a | ||
|
|
c6eb84aabc | ||
|
|
e1f1091fde | ||
|
|
b9d314ae19 | ||
|
|
14f537c296 | ||
|
|
641e824c56 | ||
|
|
b5124e7cfd | ||
|
|
54e3633b43 | ||
|
|
f697df7237 | ||
|
|
6559d09c60 | ||
|
|
8a382aa119 | ||
|
|
703c526355 | ||
|
|
4cdf3fe427 | ||
|
|
0feff6e987 | ||
|
|
cd679f2c47 | ||
|
|
1ac8600126 | ||
|
|
378bdfb7f0 | ||
|
|
0526dc1bb4 | ||
|
|
1a36590e84 | ||
|
|
7e0b6c56b4 | ||
|
|
b12dd1ae3c | ||
|
|
71676eaddd | ||
|
|
0a0ab6dd15 | ||
|
|
5692723c58 | ||
|
|
8f4b8d204b | ||
|
|
3bd2b41b2e | ||
|
|
4928ea1212 | ||
|
|
b00fe1590d | ||
|
|
c94174b4fe | ||
|
|
91dd53e54d | ||
|
|
279786e987 | ||
|
|
ae4644cc68 | ||
|
|
36f7c1337f | ||
|
|
63974bcb88 | ||
|
|
79f4a59ed9 | ||
|
|
9f98650d0a | ||
|
|
db5b0741b5 | ||
|
|
f5f6e2c6f4 | ||
|
|
25c7d9164f | ||
|
|
b8d9eaa19b | ||
|
|
f806c23012 | ||
|
|
99501a2c4c | ||
|
|
7dad5f797e | ||
|
|
dcad508986 | ||
|
|
608733415a | ||
|
|
57ec399ec9 | ||
|
|
56ca44ad1a | ||
|
|
e8cdbedefb | ||
|
|
6ccf97f3e6 | ||
|
|
433bce5c3a | ||
|
|
775f7e5fbb | ||
|
|
a819fa148d | ||
|
|
1a8dc85142 | ||
|
|
4974d1d2b4 | ||
|
|
e2f3e4e4aa | ||
|
|
b26e697182 | ||
|
|
b1f9f603a0 | ||
|
|
5384e89147 | ||
|
|
8518ba0bbc | ||
|
|
80cae358b0 | ||
|
|
0efaff9b3b | ||
|
|
41a20994cc | ||
|
|
a910a7466e | ||
|
|
4371911861 | ||
|
|
5fc4ce6449 | ||
|
|
77294047d6 | ||
|
|
bea36925db | ||
|
|
7f7a712062 | ||
|
|
30c849669d | ||
|
|
e0a8615b94 | ||
|
|
8efd9142b3 | ||
|
|
80ed5bd90c | ||
|
|
eb3695d2fc | ||
|
|
48db34a7b9 | ||
|
|
da584912b6 | ||
|
|
509e4ddc02 | ||
|
|
b33cf92878 | ||
|
|
1d3c8306f8 | ||
|
|
ec785b0180 | ||
|
|
eeabf7975e | ||
|
|
c2d1074932 | ||
|
|
722916e19d | ||
|
|
cb37f818ca | ||
|
|
9a06a71627 | ||
|
|
c6fefe5d8e | ||
|
|
ee06f78679 | ||
|
|
9ea09179b5 | ||
|
|
b1789c112b | ||
|
|
2dde63499c | ||
|
|
7f2c6ed2fa | ||
|
|
c5a3777666 | ||
|
|
0833b82efd | ||
|
|
85c3389b28 | ||
|
|
67fcf47ecb | ||
|
|
fcecafde3a | ||
|
|
d62bfe73a9 | ||
|
|
bc99c5f7db | ||
|
|
1946cc4478 | ||
|
|
5e62427e22 | ||
|
|
4ec2f07a5b | ||
|
|
883168ed94 | ||
|
|
e5f134006b | ||
|
|
d2fc597d5b | ||
|
|
3d25b1f5b8 | ||
|
|
acecb7b09f | ||
|
|
21c0a2ce0c | ||
|
|
debc97821c | ||
|
|
e2e7ba9f85 | ||
|
|
bd2d330b25 | ||
|
|
79225db0b6 | ||
|
|
c426054767 | ||
|
|
1fa793cb97 | ||
|
|
04ffb9956e | ||
|
|
94ed7c81e6 | ||
|
|
fcb3573d17 | ||
|
|
fae4fd7a26 | ||
|
|
cf09c5f687 | ||
|
|
b508619392 | ||
|
|
0f65f2762d | ||
|
|
87524922dc | ||
|
|
a303b6a733 | ||
|
|
fe57b2f963 | ||
|
|
c12b7896d0 | ||
|
|
973e6a035f | ||
|
|
84aaa03182 | ||
|
|
aa5f79206f | ||
|
|
b4a9b3f496 | ||
|
|
d04f23260d | ||
|
|
8838b0a1ff | ||
|
|
f786897e4b | ||
|
|
7acd38d19e | ||
|
|
b50e5bc816 | ||
|
|
a370b1f2e2 | ||
|
|
a13bc22204 | ||
|
|
4b7c3abbea | ||
|
|
feacfa5f83 | ||
|
|
8472e697ca | ||
|
|
65af852b54 | ||
|
|
ae697b471c | ||
|
|
94e47798f4 | ||
|
|
d853adffdb | ||
|
|
880e72c130 | ||
|
|
bfdd9f3ac9 | ||
|
|
c566cfe2ba | ||
|
|
dba55041ab | ||
|
|
fd1aaf4772 | ||
|
|
c806009453 | ||
|
|
2cc41dbe83 | ||
|
|
c26e8a1af3 | ||
|
|
0ec1fc9e11 | ||
|
|
99d75235a9 | ||
|
|
4c70b0a762 | ||
|
|
d3f52debc6 | ||
|
|
0219f8aed4 | ||
|
|
2ed1838aeb | ||
|
|
4b36c3591f | ||
|
|
a991f94c0e | ||
|
|
498b7eed25 | ||
|
|
767424af18 | ||
|
|
a80e17cfe8 | ||
|
|
349c2c9235 | ||
|
|
48d537f59f | ||
|
|
538c059aa4 | ||
|
|
a48b82eece | ||
|
|
ccd70ba123 | ||
|
|
44beee9d68 | ||
|
|
0a07ac574e | ||
|
|
6c047d398d | ||
|
|
4b886e6b39 | ||
|
|
5741349294 | ||
|
|
118b1113d9 | ||
|
|
503c176d8e | ||
|
|
dbdd8b0883 | ||
|
|
d44d432baa | ||
|
|
893bfcf95f | ||
|
|
fb53ff1eda | ||
|
|
7a17639953 | ||
|
|
bbce6fa65d | ||
|
|
95a430a2ca | ||
|
|
152f3218ac | ||
|
|
af2e5995e2 | ||
|
|
1269392822 | ||
|
|
b7271dffb5 | ||
|
|
8b2afe33a1 | ||
|
|
5cc23199be | ||
|
|
7caaf6453b | ||
|
|
1c236f4c9a | ||
|
|
1fa6fe2abd | ||
|
|
9d3c69952b | ||
|
|
5180bb5e47 | ||
|
|
0187504912 | ||
|
|
6d26deb894 | ||
|
|
81517eebc1 | ||
|
|
12d59465cb | ||
|
|
e404841235 | ||
|
|
15c946338f | ||
|
|
56a0bbbbee | ||
|
|
842e31cf5c | ||
|
|
abd3502e9e | ||
|
|
76c3cf6949 | ||
|
|
bc34ee3365 | ||
|
|
9a04cd307c | ||
|
|
f0a62c90bc | ||
|
|
2946992ad4 | ||
|
|
821ff0ecfb | ||
|
|
2c4cace56c | ||
|
|
8a502233d8 | ||
|
|
b2755edcdd | ||
|
|
d1ef3c3546 | ||
|
|
edaefeb978 | ||
|
|
3bd31e21b5 | ||
|
|
75e269c77b | ||
|
|
74cde0c925 | ||
|
|
ce2035af86 | ||
|
|
6d0f0b8cec | ||
|
|
4ba8aa1482 | ||
|
|
27d6b4daf9 | ||
|
|
446001ef51 | ||
|
|
13cbc751c9 | ||
|
|
421feea3b2 | ||
|
|
7817bc19a4 | ||
|
|
eb13ada3aa | ||
|
|
36448c9e28 | ||
|
|
de0d8a010e | ||
|
|
72569f17ec | ||
|
|
3878e6f170 | ||
|
|
ff46ec0f24 | ||
|
|
ae514ddfe5 | ||
|
|
f9d6d3780f | ||
|
|
abba11bdcf | ||
|
|
d9e0336a78 | ||
|
|
333905b0c2 | ||
|
|
5fa69422a2 | ||
|
|
de38ff2499 | ||
|
|
60e093a9dc | ||
|
|
56408504e4 | ||
|
|
974fe38ca3 | ||
|
|
c0205ca4af | ||
|
|
10f8aabb61 | ||
|
|
80de35b6c5 | ||
|
|
60663a510a | ||
|
|
03dd4dd91a | ||
|
|
0a18eecab3 | ||
|
|
7b044c0ead | ||
|
|
755e77266f | ||
|
|
07c5500d70 | ||
|
|
e70506dd8f | ||
|
|
2ae20d558b | ||
|
|
62bce6e5e6 | ||
|
|
060e835ee9 | ||
|
|
0ca43f7e9a | ||
|
|
8b3be4907d | ||
|
|
0bf5894861 | ||
|
|
e44d78dab3 | ||
|
|
c2f66c65aa | ||
|
|
125619146b | ||
|
|
341ae8665d | ||
|
|
fc23e93707 | ||
|
|
0f0580b97c | ||
|
|
486ca277a0 | ||
|
|
10a79ca3a3 | ||
|
|
466d6d41c6 | ||
|
|
8514179aa3 | ||
|
|
0403d49006 | ||
|
|
c83e01f2d6 | ||
|
|
26db954776 | ||
|
|
fda680f9cf | ||
|
|
dfc54e1bbf | ||
|
|
749b56f6af | ||
|
|
af9c9f7706 | ||
|
|
9452eb38f8 | ||
|
|
470aa15c35 | ||
|
|
188a13f9fe | ||
|
|
efdff15749 | ||
|
|
dacd39ea76 | ||
|
|
74db22455a | ||
|
|
b23556bbbd | ||
|
|
1abe4ed14c | ||
|
|
d43f737b4a | ||
|
|
f50548e86a | ||
|
|
15bad3670b | ||
|
|
8846aa6d1b | ||
|
|
80993b95d3 | ||
|
|
b24fe22b1a | ||
|
|
c82dc227f1 | ||
|
|
a96f3d629c | ||
|
|
47829e2d16 | ||
|
|
1f398dfc82 | ||
|
|
b3a0365429 | ||
|
|
eb39296028 | ||
|
|
72c4f8ca8f | ||
|
|
b121eecf60 | ||
|
|
8754341848 | ||
|
|
daad9585a3 | ||
|
|
b051bbd64f | ||
|
|
b3d63b4db2 | ||
|
|
1c4b69c5fb | ||
|
|
8a74ce922c | ||
|
|
863b7362bc | ||
|
|
1bf3b34849 | ||
|
|
f9580a3473 | ||
|
|
fbb53b6cbb | ||
|
|
85c7659574 | ||
|
|
bc065c75d2 | ||
|
|
e6cc24cbd6 | ||
|
|
0369db12af | ||
|
|
7ff266e3ce | ||
|
|
b4a709520d | ||
|
|
c1d0f15bde | ||
|
|
124d12a915 | ||
|
|
f29dbec321 | ||
|
|
01f3ca3e8d | ||
|
|
aec3d90ca6 | ||
|
|
460662cbcc | ||
|
|
1ed9e2d004 | ||
|
|
e49e84d979 | ||
|
|
c3e4080474 | ||
|
|
2959045f2f | ||
|
|
36fffe48f7 | ||
|
|
fb5c1e9097 | ||
|
|
0ba490cf80 | ||
|
|
25a3e65a68 | ||
|
|
be3477e206 | ||
|
|
2e50289ba3 | ||
|
|
b49ef99617 | ||
|
|
9c0aa81fbf | ||
|
|
3d298da269 | ||
|
|
eeadc06e83 | ||
|
|
4403800e11 | ||
|
|
9062f74d13 | ||
|
|
6a3423da80 | ||
|
|
9ac3c821ea | ||
|
|
33c702c79f | ||
|
|
756292f8aa | ||
|
|
8c8db49331 | ||
|
|
eeb43f9e2b | ||
|
|
16047c8d4a | ||
|
|
916ef48846 | ||
|
|
f1d8c13dbc | ||
|
|
9faad2932f | ||
|
|
f8fad09301 | ||
|
|
72e7529708 | ||
|
|
1aa2bf8274 | ||
|
|
b1892ab14d | ||
|
|
439feca139 | ||
|
|
e6d55c081b | ||
|
|
57f71a5552 | ||
|
|
5e890d3ad7 | ||
|
|
2d90484450 | ||
|
|
84a7ead059 | ||
|
|
d6236d3b26 | ||
|
|
921a645481 | ||
|
|
4b678b96eb | ||
|
|
51b3f558bb | ||
|
|
6162672dc5 | ||
|
|
e54898f53e | ||
|
|
fafc829424 | ||
|
|
abb33258ce | ||
|
|
25bceefb4e | ||
|
|
60314beb38 | ||
|
|
280661e67d | ||
|
|
ff9bfc45f7 | ||
|
|
42e27d41a2 | ||
|
|
a44a343f03 | ||
|
|
18fbe7e7d4 | ||
|
|
3eb5253ca1 | ||
|
|
305aa1f9c5 | ||
|
|
50085d2c28 | ||
|
|
e51da9c3a8 | ||
|
|
953ec08089 | ||
|
|
3e59163a24 | ||
|
|
4dd55a2958 | ||
|
|
f25338f4d7 | ||
|
|
51357a6622 | ||
|
|
107bb308c3 | ||
|
|
c2ff44cbf3 | ||
|
|
c53f88297c | ||
|
|
6f58a41097 | ||
|
|
2a3c3c49a1 | ||
|
|
fc13b37c55 | ||
|
|
db76193bc7 | ||
|
|
647622281e | ||
|
|
d79516660c | ||
|
|
26d2cdefd4 | ||
|
|
db183ca7b3 | ||
|
|
702a3c17db | ||
|
|
5f5a8d97c0 | ||
|
|
bae2e3327b | ||
|
|
cd0ff253ec | ||
|
|
929e77192c | ||
|
|
ba694ce8cf | ||
|
|
2116e261fb | ||
|
|
5f3d542b8a | ||
|
|
a0a87410d0 | ||
|
|
2c625ec9ba | ||
|
|
1f371e78e6 | ||
|
|
f7bb7ee3f3 | ||
|
|
d1e9f39a9a | ||
|
|
7f15f27a9e | ||
|
|
922694a2d1 | ||
|
|
baa77ffe38 | ||
|
|
a8283e0ed2 | ||
|
|
4aac87251f | ||
|
|
6daa6a0d16 | ||
|
|
2a251ffab0 | ||
|
|
9b729f93a1 | ||
|
|
946b99dd5c | ||
|
|
50eef6dfc3 | ||
|
|
62f332fc04 | ||
|
|
3eba5e1101 | ||
|
|
529e6cb552 | ||
|
|
36e6c9064f | ||
|
|
a325d1cb1e | ||
|
|
da62eb22e4 | ||
|
|
77af4cc3c9 | ||
|
|
5e72151ca5 | ||
|
|
2cd38a6634 | ||
|
|
84ad8ce7e3 | ||
|
|
40b74411e4 | ||
|
|
14c8793a70 | ||
|
|
424c3ad266 | ||
|
|
a53f2b0e43 | ||
|
|
cd0b433540 | ||
|
|
338d2ec42b | ||
|
|
0a945687b7 | ||
|
|
a0d1aac6c5 | ||
|
|
2bdb3b1afd | ||
|
|
3c7686630d | ||
|
|
4f440b8123 | ||
|
|
a20e2462bf | ||
|
|
c0f76ce2cf | ||
|
|
df604e4f49 | ||
|
|
5f1eedd655 | ||
|
|
296cb40161 | ||
|
|
40bb98e76a | ||
|
|
9b7a6f0122 | ||
|
|
ffd3654f67 | ||
|
|
b1169ce40c | ||
|
|
d1460d9278 | ||
|
|
cf7cf7b490 | ||
|
|
f27f55bee3 | ||
|
|
e955725ff1 | ||
|
|
25b2f6624d | ||
|
|
23bb592a2d | ||
|
|
75d19bb087 | ||
|
|
62f948c56a | ||
|
|
da1e356306 | ||
|
|
54fbbe7b4e | ||
|
|
ea0906dfd8 | ||
|
|
cc1bacea5b | ||
|
|
c285fda7f4 | ||
|
|
1967e7f2f3 | ||
|
|
77d57cd681 | ||
|
|
e3557e8dd2 | ||
|
|
5214466b7a | ||
|
|
5c4733f6e4 | ||
|
|
b47ef1431f | ||
|
|
e25e674852 | ||
|
|
4b6b76463a | ||
|
|
904509fbb6 | ||
|
|
0dfb73d46a | ||
|
|
7fa83e7374 | ||
|
|
7d53633e05 | ||
|
|
bc072c5cba | ||
|
|
47981c5925 | ||
|
|
1eefa5a841 | ||
|
|
e4b6979334 | ||
|
|
b9ee880f07 | ||
|
|
2bf58316ee | ||
|
|
85777fc131 | ||
|
|
58687aa5e6 | ||
|
|
339f14b8d1 | ||
|
|
d4cc1bdc7f | ||
|
|
8e19027130 | ||
|
|
ef4a86d6b8 | ||
|
|
68eafc10b1 | ||
|
|
1cb71a8782 | ||
|
|
ac1bb3e5b3 | ||
|
|
4860da2de1 | ||
|
|
7a915f6846 | ||
|
|
1a817d3b70 | ||
|
|
8ee38d2db6 | ||
|
|
f365380496 | ||
|
|
3a9f9faada | ||
|
|
998455a570 | ||
|
|
0a8e4712d1 | ||
|
|
61b88d2feb | ||
|
|
bf334b8ae5 | ||
|
|
8f4cdbbc8f | ||
|
|
7390af91b6 | ||
|
|
1e6f53e070 | ||
|
|
6f846ef9c6 | ||
|
|
324e7e8fc9 | ||
|
|
3c63446507 | ||
|
|
746d2db6ed | ||
|
|
441f97b2df | ||
|
|
0ad7a644df | ||
|
|
7ffd55c980 | ||
|
|
75e574275c | ||
|
|
c401167712 | ||
|
|
73e686c6a4 | ||
|
|
ae039dde13 | ||
|
|
f0648f8860 | ||
|
|
08c615f1e4 | ||
|
|
54607665ab | ||
|
|
d73ee84d37 | ||
|
|
a7bd4c455a | ||
|
|
b868bfb84a | ||
|
|
3b19b466a7 | ||
|
|
199ac3f2e7 | ||
|
|
e3ba5329ff | ||
|
|
17f119689e | ||
|
|
f9496d341f | ||
|
|
e745a450de | ||
|
|
e86adc87e9 | ||
|
|
b59f045c07 | ||
|
|
755be9016a | ||
|
|
957c2c291b | ||
|
|
15c2c083e8 | ||
|
|
3117036b80 | ||
|
|
1c3843bf86 | ||
|
|
0ddde223e9 | ||
|
|
3849cc65ee | ||
|
|
5dbbe6b400 | ||
|
|
ec0a8b2e6d | ||
|
|
7fa87a8b12 | ||
|
|
b29b81a1f4 | ||
|
|
47585c8ab2 | ||
|
|
c415b627a7 | ||
|
|
78bb808337 | ||
|
|
963d338922 | ||
|
|
98ef44fe55 | ||
|
|
1fdef63d1f | ||
|
|
de150b1e14 | ||
|
|
55453c51e8 | ||
|
|
eb49100de9 | ||
|
|
afb1a8c124 | ||
|
|
c06ec0f464 | ||
|
|
95ecd582a3 | ||
|
|
b0979b8598 | ||
|
|
774c3c1e0a | ||
|
|
f80c8e17eb | ||
|
|
38ab7e6ed0 | ||
|
|
1ee4e2db15 | ||
|
|
aa664eabb9 | ||
|
|
4304c73542 | ||
|
|
925fb6b937 | ||
|
|
a77458a8ff | ||
|
|
a669052f12 | ||
|
|
36a2b2e9dc | ||
|
|
2859a31ac8 | ||
|
|
d13711a363 | ||
|
|
fe102248ac | ||
|
|
8c8ae2d819 | ||
|
|
29aebf96e6 | ||
|
|
79085e08e9 | ||
|
|
a961d72e65 | ||
|
|
abc1ca0af1 | ||
|
|
c331ce6b8e | ||
|
|
ed37c44765 | ||
|
|
8998f4099e | ||
|
|
96cb58fa3b | ||
|
|
ea99433523 | ||
|
|
cee62018fc | ||
|
|
58cfac9a12 | ||
|
|
45515779d3 | ||
|
|
6fa6cdd2b9 | ||
|
|
0f1e321dd4 | ||
|
|
789674809f | ||
|
|
eb56461ac2 | ||
|
|
736267cf6b | ||
|
|
7402fea0a8 | ||
|
|
e3ab46b8c9 | ||
|
|
c794099e69 | ||
|
|
aa524604b7 | ||
|
|
c55c5763fe | ||
|
|
eda79321be | ||
|
|
df92649379 | ||
|
|
0f94607947 | ||
|
|
edebb15275 | ||
|
|
9aa3dc4e21 | ||
|
|
881aab14b4 | ||
|
|
0320f7e3a7 | ||
|
|
5811e68dd1 | ||
|
|
9217de8bf2 | ||
|
|
84cb1d72b8 | ||
|
|
56de8d3816 | ||
|
|
b4beba72a2 | ||
|
|
b5e3d76aa5 | ||
|
|
f56d452c7e | ||
|
|
af79b158a1 | ||
|
|
0b7f95a03f | ||
|
|
d67aa1549b | ||
|
|
07986189b7 | ||
|
|
c0f2cb016e | ||
|
|
2fb64578aa | ||
|
|
ecf1f1d589 | ||
|
|
e7ef26fa44 | ||
|
|
450d0c3de0 | ||
|
|
f9d2f3903e | ||
|
|
6f64b0b487 | ||
|
|
c20e3641de | ||
|
|
2dbfd83424 | ||
|
|
7388fdf560 | ||
|
|
c9788d55b9 | ||
|
|
ae4d9434e2 | ||
|
|
4def7b1fa5 | ||
|
|
c79bd4b64b | ||
|
|
cf7eaed38d | ||
|
|
3d8d0f6269 | ||
|
|
b0e19db1cf | ||
|
|
8d85ce88e1 | ||
|
|
4eb92e5647 | ||
|
|
ccb4dec719 | ||
|
|
82b09fcb91 | ||
|
|
ecbd67a15a | ||
|
|
934ce93886 | ||
|
|
5c5231ab71 | ||
|
|
2606abed53 | ||
|
|
a7d20038df | ||
|
|
3454b4e5f1 | ||
|
|
94684721bd | ||
|
|
1388f4f9fd | ||
|
|
6d665d446b | ||
|
|
2c3c95990d | ||
|
|
6d6df90c9a | ||
|
|
c354bd47f7 | ||
|
|
9777a5ca60 | ||
|
|
9746396d1b | ||
|
|
e5d0cb54a5 | ||
|
|
1dd015fea6 | ||
|
|
45a4aad572 | ||
|
|
e1d461352e | ||
|
|
11fbdcbc38 | ||
|
|
0fa8290366 | ||
|
|
d936ddc3d1 | ||
|
|
de8336a9bc | ||
|
|
ffc995c9e4 | ||
|
|
d5a795f673 | ||
|
|
b30706bd5c | ||
|
|
e0dbb68c2f | ||
|
|
59f5f155c2 | ||
|
|
20c840be15 | ||
|
|
1afd50e0f3 | ||
|
|
3c66bb136b | ||
|
|
7098e6d976 | ||
|
|
feaf7c7e6d | ||
|
|
d567e3b893 | ||
|
|
148acf8e4f | ||
|
|
0587db8bf5 | ||
|
|
7903d3f27b | ||
|
|
a803ff18a9 | ||
|
|
91288e9bf9 | ||
|
|
fbd5eac7cf | ||
|
|
1b333c89c9 | ||
|
|
a1fcf599fa | ||
|
|
a91a7a1964 | ||
|
|
3b2321e3ab | ||
|
|
b446ff037e | ||
|
|
5afcb4965c | ||
|
|
096af59799 | ||
|
|
8044b00a7f | ||
|
|
aecc78325a | ||
|
|
1cb8de1250 | ||
|
|
56c4851323 | ||
|
|
ceae5b4145 | ||
|
|
ec65e6648c | ||
|
|
d992634fbc | ||
|
|
5e8622477b | ||
|
|
1221dd90aa | ||
|
|
93870d95b7 | ||
|
|
f603823ef3 | ||
|
|
8d0441052e | ||
|
|
82c8163067 | ||
|
|
1c0728043a | ||
|
|
e497a27ddc | ||
|
|
ad59ade116 | ||
|
|
39bfbd43f0 | ||
|
|
10aa14592a | ||
|
|
8d2bb2c20d | ||
|
|
c94fde118a | ||
|
|
51e85c936d | ||
|
|
8a94cb3edd | ||
|
|
7f3162f707 | ||
|
|
ee86679096 | ||
|
|
58fe2fc2b2 | ||
|
|
729363114f | ||
|
|
1697d7a179 | ||
|
|
3e1fe8e416 | ||
|
|
b776458ccb | ||
|
|
c4902a3d01 | ||
|
|
7d73c7f18b | ||
|
|
6f123d209e | ||
|
|
052aedd394 | ||
|
|
fb03b56647 | ||
|
|
6a81594771 | ||
|
|
9ce0d78513 | ||
|
|
a419cea4a0 | ||
|
|
ba3457cab2 | ||
|
|
14bc4b9704 | ||
|
|
e45a6bed45 | ||
|
|
cc73164aa8 | ||
|
|
f0a4c9d5ab | ||
|
|
8be011e776 | ||
|
|
a078f442a3 | ||
|
|
cf1a7bfbe1 | ||
|
|
bc401eb6fa | ||
|
|
b286a1e75c | ||
|
|
6bf3cc2732 | ||
|
|
7ae9b0805d | ||
|
|
08f7b3221d | ||
|
|
72707a8664 | ||
|
|
8a0845ebd7 | ||
|
|
3e42b775ea | ||
|
|
dead9085c0 | ||
|
|
4fe56a0e02 | ||
|
|
35a2c9cde7 | ||
|
|
bb4b67cf39 | ||
|
|
0a6c472335 | ||
|
|
2db792852f | ||
|
|
847d801a4c | ||
|
|
aceae8314b | ||
|
|
16d4c7a5e8 | ||
|
|
a395024d44 | ||
|
|
f74ed34539 | ||
|
|
5e26b7cf9d | ||
|
|
74b1d79d77 | ||
|
|
0b362e0c9a | ||
|
|
a6be1952f4 | ||
|
|
2379ccffcb | ||
|
|
88aa18df64 | ||
|
|
0bd5671b9e | ||
|
|
8dd3b716e3 | ||
|
|
7eefdb948c | ||
|
|
082f7ddc37 | ||
|
|
bbc0ada12a | ||
|
|
9be72cda2a | ||
|
|
ae40583965 | ||
|
|
5806e73800 | ||
|
|
2bf63c6b4a | ||
|
|
1b3d7fc04c | ||
|
|
da6ec81282 | ||
|
|
354bd8a428 | ||
|
|
5c0f294098 | ||
|
|
804ef2350d | ||
|
|
a6b130c63c | ||
|
|
8eac97138a | ||
|
|
1dd176b0b0 | ||
|
|
131027ee0a | ||
|
|
db7d49efbb | ||
|
|
9fdc6258cf | ||
|
|
21fecd5252 | ||
|
|
6fecb6f1b6 | ||
|
|
3e439889e0 | ||
|
|
cbc572caf7 | ||
|
|
1e0c2f6ddb | ||
|
|
c98881e130 | ||
|
|
d67548f345 | ||
|
|
6c7ab50811 | ||
|
|
728c3d2cb9 | ||
|
|
af31b6c37a | ||
|
|
93125e372d | ||
|
|
b2e1453e1e | ||
|
|
9621333545 | ||
|
|
5f6ec95291 | ||
|
|
ecd2c8f37b | ||
|
|
5960befc20 | ||
|
|
2eee6eaf3c | ||
|
|
8af02d19b2 | ||
|
|
95b0a6707b | ||
|
|
b1ab6a8e0b | ||
|
|
61cff28618 | ||
|
|
68e8ddaf94 | ||
|
|
3a735a6cf1 | ||
|
|
ccc41128fb | ||
|
|
b3a07eecc5 | ||
|
|
c16b80746a | ||
|
|
cbd7e98174 | ||
|
|
7ed9441ea4 | ||
|
|
5b78780def | ||
|
|
8169c6ac59 | ||
|
|
463554c254 | ||
|
|
82c066b3c4 | ||
|
|
0543cb51b5 | ||
|
|
99e27916cf | ||
|
|
37a1d736bf | ||
|
|
06545058bb | ||
|
|
7002aa858f | ||
|
|
8cfb138e73 | ||
|
|
1b5de5a37b | ||
|
|
a08cba6b5f | ||
|
|
573c587e3d | ||
|
|
551bf5c66a | ||
|
|
2d136d3d7f | ||
|
|
873401032b | ||
|
|
d595fd31f5 | ||
|
|
bffa15142c | ||
|
|
b14a4628af | ||
|
|
3573a10712 | ||
|
|
bd6eca059d | ||
|
|
ed461ba9bc | ||
|
|
3bb57e21a8 | ||
|
|
4b6b3f310f | ||
|
|
cd606bbc94 | ||
|
|
0508af4287 | ||
|
|
3283d98d13 | ||
|
|
0d3f496233 | ||
|
|
6df3bee687 | ||
|
|
97965dde9b | ||
|
|
0b1430ae10 | ||
|
|
c0e08e9e4b | ||
|
|
0715d49908 | ||
|
|
3291580630 | ||
|
|
14422decc2 | ||
|
|
7ea6ef8969 | ||
|
|
31c63ef0b4 | ||
|
|
e170e7070b | ||
|
|
c1921ad3e2 | ||
|
|
c4f08cfc05 | ||
|
|
9e71ecbeec | ||
|
|
ff8d81762d | ||
|
|
6c527bd811 | ||
|
|
e722f36ffa | ||
|
|
febfc7b9b4 | ||
|
|
64a85800bd | ||
|
|
94acccc126 | ||
|
|
34694d8828 | ||
|
|
ee1c55f923 | ||
|
|
f54e62e4a9 | ||
|
|
5fa7262e4c | ||
|
|
fef534f52e | ||
|
|
a7621809fe | ||
|
|
6cf938df53 | ||
|
|
afcfb560a2 | ||
|
|
40c42d9788 | ||
|
|
deab937d45 | ||
|
|
66f1c56aab | ||
|
|
aa0db35185 | ||
|
|
4c08385b74 | ||
|
|
4ccff2d028 | ||
|
|
3a4616d6e3 | ||
|
|
92190a1caf | ||
|
|
ac409f51f1 | ||
|
|
a6a57748dd | ||
|
|
c8c81c1e74 | ||
|
|
60cd361ebe | ||
|
|
c8bfbf4a7e | ||
|
|
01fd880424 | ||
|
|
e3fb190edf | ||
|
|
cfd3d6ce9c | ||
|
|
c39a3fa7a1 | ||
|
|
2a564695f0 | ||
|
|
a58325ac2f | ||
|
|
4cd4be97a7 | ||
|
|
548216b7ca | ||
|
|
e15cb9f4f8 | ||
|
|
bbf373bbe9 | ||
|
|
1200bd2ef0 | ||
|
|
8a49dd5626 | ||
|
|
ce99b502ce | ||
|
|
033ee7f6d9 | ||
|
|
ba2f79e680 | ||
|
|
72461be962 | ||
|
|
33ca9b4ee6 | ||
|
|
ce41b72eb8 | ||
|
|
d5cc083782 | ||
|
|
7313f32efa | ||
|
|
04e1e38eed | ||
|
|
47679c50ae | ||
|
|
76d2ca27e5 | ||
|
|
41e89c73c7 | ||
|
|
ac69d8769f | ||
|
|
6b6071866b | ||
|
|
d357bbd9c0 | ||
|
|
27c068e9d6 | ||
|
|
e94fe4cc3e | ||
|
|
2ca0ccd2f2 | ||
|
|
8d8acc3ab4 | ||
|
|
6c5e915e9a | ||
|
|
f0b82c3ab9 | ||
|
|
6f1a0479b3 | ||
|
|
b5fd774775 | ||
|
|
34ca81b1bf | ||
|
|
7f917807c6 | ||
|
|
8af1ba5346 | ||
|
|
c6f7337032 | ||
|
|
626821b0e3 | ||
|
|
27ca9437a1 | ||
|
|
d0261bd26c | ||
|
|
276801b25a | ||
|
|
d61345f366 | ||
|
|
c15c65990f | ||
|
|
fb6e32a62f | ||
|
|
d331def6cc | ||
|
|
5584275325 | ||
|
|
cc6dd878ee | ||
|
|
fc6ecebc69 | ||
|
|
49034d1570 | ||
|
|
230f5c3aa9 | ||
|
|
c550a0e634 | ||
|
|
28b2abdbea | ||
|
|
654eab3bd6 | ||
|
|
5d1291a4de | ||
|
|
8b4dd78d57 | ||
|
|
f6bac196d5 | ||
|
|
46dd1bb1be | ||
|
|
6b471f205e | ||
|
|
03a956925a | ||
|
|
f97b3cd024 | ||
|
|
5e28c41549 | ||
|
|
e59b38abef | ||
|
|
8f2d068e84 | ||
|
|
5c2d1b4710 | ||
|
|
b93520b1a5 | ||
|
|
cb8da751a0 | ||
|
|
fe0b44e876 | ||
|
|
ae83f5ede9 | ||
|
|
76c230a84d | ||
|
|
57327cc2d5 | ||
|
|
5887e82729 | ||
|
|
af9851d1d7 | ||
|
|
8fe609311d | ||
|
|
8edc964734 | ||
|
|
a37bdfc955 | ||
|
|
03de5c2410 | ||
|
|
4f572e4c14 | ||
|
|
87aee5fda1 | ||
|
|
1bb1a57ef7 | ||
|
|
7c9cdd6030 | ||
|
|
a236e15048 | ||
|
|
ad1dc50b57 | ||
|
|
019dcfc21d | ||
|
|
19521c83b8 | ||
|
|
bbd49d194a | ||
|
|
8f496cd3a3 | ||
|
|
6dc0e59b1e | ||
|
|
2702788da7 | ||
|
|
58c0a6f0fd | ||
|
|
5974685866 | ||
|
|
7fae9b358d | ||
|
|
e14f529dac | ||
|
|
fe2f437642 | ||
|
|
90b5d303db | ||
|
|
9b863c1830 | ||
|
|
11fbbc51fa | ||
|
|
d3e84b747a | ||
|
|
2e606394b1 | ||
|
|
285112fc55 | ||
|
|
9f3f42d66a | ||
|
|
a0e8577b49 | ||
|
|
a6bff116f9 | ||
|
|
36052c4911 | ||
|
|
3d2a3bc755 | ||
|
|
ad9dc05663 | ||
|
|
ff075def5c | ||
|
|
4d7dfafbe7 | ||
|
|
3390db099a | ||
|
|
c6da881849 | ||
|
|
b61facb08b | ||
|
|
4a42843513 | ||
|
|
b433fb2857 | ||
|
|
2c0303c89e | ||
|
|
0bce534c8f | ||
|
|
6bef527f9d | ||
|
|
2d186da58a | ||
|
|
3736e00ae7 | ||
|
|
40f1548b32 | ||
|
|
446320b226 | ||
|
|
54e576c88a | ||
|
|
fe19f972e1 | ||
|
|
00dc45d0f9 | ||
|
|
4bb1c48f25 | ||
|
|
bd21c82a94 | ||
|
|
1b4623e713 | ||
|
|
a1f056cf2a | ||
|
|
4612a1cd87 | ||
|
|
07417bd03f | ||
|
|
7fa007e8bf | ||
|
|
ed78a76161 | ||
|
|
eda2f8948a | ||
|
|
16cbd3d72d | ||
|
|
86daf2f75c | ||
|
|
69c057ccb1 | ||
|
|
94a7a1ec00 | ||
|
|
5864e3fbd5 | ||
|
|
d2c4f4ab21 | ||
|
|
41321e4366 | ||
|
|
e6462c2ce3 | ||
|
|
1472f4bc61 | ||
|
|
a147500dee | ||
|
|
d1c48f1606 | ||
|
|
1b8394f71f | ||
|
|
4ecfdc4716 | ||
|
|
d9381598bc | ||
|
|
403be74861 | ||
|
|
1c61e28b32 | ||
|
|
c06e373beb | ||
|
|
7bca2910c7 | ||
|
|
2cf513e973 | ||
|
|
150c9fe536 | ||
|
|
e4ffb7729a | ||
|
|
d908ccc01c | ||
|
|
2b15e00106 | ||
|
|
127d7f2071 | ||
|
|
c47010e3d2 | ||
|
|
d4dd6aaed2 | ||
|
|
d3635b08da | ||
|
|
ebd6a7a46c | ||
|
|
e0dbc2913a | ||
|
|
1d89554f1b | ||
|
|
ace2ed7b87 | ||
|
|
956251b738 | ||
|
|
6f5f488a80 | ||
|
|
916d29e58f | ||
|
|
bffdc491b3 | ||
|
|
6719e56b5b | ||
|
|
c13e9bbabf | ||
|
|
e4acd6e2fd | ||
|
|
8a89ba9275 | ||
|
|
097a105603 | ||
|
|
306ce33e1c | ||
|
|
616f9cc593 | ||
|
|
2f0faf117e | ||
|
|
8710440951 | ||
|
|
8fdffdd573 | ||
|
|
3444f06f68 | ||
|
|
8f4d93a4b7 | ||
|
|
51b361b3bb | ||
|
|
7c99b38b7c | ||
|
|
b72a686830 | ||
|
|
e3058dd88b | ||
|
|
8ea7413a64 | ||
|
|
e90229a429 | ||
|
|
cf884a9815 | ||
|
|
ddf7753631 | ||
|
|
222eedf5f3 | ||
|
|
d0e543be26 | ||
|
|
8e6d0cba5f | ||
|
|
32d46dd9b8 | ||
|
|
e41bc6cbbf | ||
|
|
55b57fcba6 | ||
|
|
39491e3b75 | ||
|
|
68168e9eae | ||
|
|
6126ad801f | ||
|
|
43df1e707c | ||
|
|
b1f4601bf9 | ||
|
|
acb82c7f16 | ||
|
|
9ef3645cc7 | ||
|
|
5f11db695b | ||
|
|
2437215221 | ||
|
|
dd27b5c4a8 | ||
|
|
70131120ab | ||
|
|
6d86cd7224 | ||
|
|
75dab1ce5e | ||
|
|
e43934d60f | ||
|
|
75edc7cc8b | ||
|
|
5897695e8a | ||
|
|
a3a55357db | ||
|
|
084dc63b4c | ||
|
|
463343fb37 | ||
|
|
5879937f58 | ||
|
|
01190b3544 | ||
|
|
c00f688c64 | ||
|
|
51573da3a4 | ||
|
|
1191949e87 | ||
|
|
3d94ed9fa0 | ||
|
|
ede27f5780 | ||
|
|
dda869051d | ||
|
|
2320073e41 | ||
|
|
c587e63631 | ||
|
|
660b905e12 | ||
|
|
4f0bd557a4 | ||
|
|
736fe99fbf | ||
|
|
6fab4012a3 | ||
|
|
2f593ee67c | ||
|
|
20e535e142 | ||
|
|
4b780553e0 | ||
|
|
9be658f701 | ||
|
|
b8f0364a1c | ||
|
|
cbe92de2b5 | ||
|
|
eeb744dc8d | ||
|
|
d5501d3a90 | ||
|
|
3c423ccfe2 | ||
|
|
738d75d3eb | ||
|
|
a992fa74eb | ||
|
|
4466875d54 | ||
|
|
5c95892b83 | ||
|
|
639d03d900 | ||
|
|
d204bb57d0 | ||
|
|
c52cbd9de9 | ||
|
|
159a3bed9e | ||
|
|
25544dbec3 | ||
|
|
04bd1e3fc0 | ||
|
|
00e30a5fc4 | ||
|
|
55ec3cc6d5 | ||
|
|
9e2b4eeac0 | ||
|
|
c273a6c37c | ||
|
|
04a9ad6e10 | ||
|
|
4e26057f66 | ||
|
|
cce68d4e91 | ||
|
|
75b3391e3f | ||
|
|
231d4a6fda | ||
|
|
64054ee396 | ||
|
|
12e69ec896 | ||
|
|
8556ca3de5 | ||
|
|
9cd2d14005 | ||
|
|
4e2e615a7c | ||
|
|
12439e1249 | ||
|
|
d93c1c113b | ||
|
|
968f7591f8 | ||
|
|
5adcc6c7b4 |
3
.hgeol
3
.hgeol
@@ -1,6 +1,9 @@
|
||||
[patterns]
|
||||
*.sh = LF
|
||||
*.MINPACK = CRLF
|
||||
scripts/*.in = LF
|
||||
debug/msvc/*.dat = CRLF
|
||||
debug/msvc/*.natvis = CRLF
|
||||
unsupported/test/mpreal/*.* = CRLF
|
||||
** = native
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
project(Eigen)
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.2)
|
||||
cmake_minimum_required(VERSION 2.8.4)
|
||||
|
||||
# guard against in-source builds
|
||||
|
||||
@@ -108,7 +108,8 @@ endif()
|
||||
set(EIGEN_TEST_MAX_SIZE "320" CACHE STRING "Maximal matrix/vector size, default is 320")
|
||||
|
||||
macro(ei_add_cxx_compiler_flag FLAG)
|
||||
string(REGEX REPLACE "-" "" SFLAG ${FLAG})
|
||||
string(REGEX REPLACE "-" "" SFLAG1 ${FLAG})
|
||||
string(REGEX REPLACE "\\+" "p" SFLAG ${SFLAG1})
|
||||
check_cxx_compiler_flag(${FLAG} COMPILER_SUPPORT_${SFLAG})
|
||||
if(COMPILER_SUPPORT_${SFLAG})
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAG}")
|
||||
@@ -118,7 +119,7 @@ endmacro(ei_add_cxx_compiler_flag)
|
||||
if(NOT MSVC)
|
||||
# We assume that other compilers are partly compatible with GNUCC
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
|
||||
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g3")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-g0 -O2")
|
||||
|
||||
@@ -142,6 +143,15 @@ if(NOT MSVC)
|
||||
ei_add_cxx_compiler_flag("-Wpointer-arith")
|
||||
ei_add_cxx_compiler_flag("-Wwrite-strings")
|
||||
ei_add_cxx_compiler_flag("-Wformat-security")
|
||||
ei_add_cxx_compiler_flag("-Wshorten-64-to-32")
|
||||
ei_add_cxx_compiler_flag("-Wenum-conversion")
|
||||
ei_add_cxx_compiler_flag("-Wc++11-extensions")
|
||||
|
||||
# -Wshadow is insanely too strict with gcc, hopefully it will become usable with gcc 6
|
||||
# if(NOT CMAKE_COMPILER_IS_GNUCXX OR (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "5.0.0"))
|
||||
if(NOT CMAKE_COMPILER_IS_GNUCXX)
|
||||
ei_add_cxx_compiler_flag("-Wshadow")
|
||||
endif()
|
||||
|
||||
ei_add_cxx_compiler_flag("-Wno-psabi")
|
||||
ei_add_cxx_compiler_flag("-Wno-variadic-macros")
|
||||
@@ -153,6 +163,7 @@ if(NOT MSVC)
|
||||
ei_add_cxx_compiler_flag("-wd981") # disable ICC's "operands are evaluated in unspecified order" remark
|
||||
ei_add_cxx_compiler_flag("-wd2304") # disbale ICC's "warning #2304: non-explicit constructor with single argument may cause implicit type conversion" produced by -Wnon-virtual-dtor
|
||||
|
||||
|
||||
# The -ansi flag must be added last, otherwise it is also used as a linker flag by check_cxx_compiler_flag making it fails
|
||||
# Moreover we should not set both -strict-ansi and -ansi
|
||||
check_cxx_compiler_flag("-strict-ansi" COMPILER_SUPPORT_STRICTANSI)
|
||||
@@ -163,6 +174,11 @@ if(NOT MSVC)
|
||||
else()
|
||||
ei_add_cxx_compiler_flag("-ansi")
|
||||
endif()
|
||||
|
||||
if(ANDROID_NDK)
|
||||
ei_add_cxx_compiler_flag("-pie")
|
||||
ei_add_cxx_compiler_flag("-fPIE")
|
||||
endif()
|
||||
|
||||
set(CMAKE_REQUIRED_FLAGS "")
|
||||
|
||||
@@ -196,18 +212,49 @@ if(NOT MSVC)
|
||||
message(STATUS "Enabling SSE4.2 in tests/examples")
|
||||
endif()
|
||||
|
||||
option(EIGEN_TEST_AVX "Enable/Disable AVX in tests/examples" OFF)
|
||||
if(EIGEN_TEST_AVX)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx")
|
||||
message(STATUS "Enabling AVX in tests/examples")
|
||||
endif()
|
||||
|
||||
option(EIGEN_TEST_FMA "Enable/Disable FMA in tests/examples" OFF)
|
||||
if(EIGEN_TEST_FMA AND NOT EIGEN_TEST_NEON)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfma")
|
||||
message(STATUS "Enabling FMA in tests/examples")
|
||||
endif()
|
||||
|
||||
option(EIGEN_TEST_ALTIVEC "Enable/Disable AltiVec in tests/examples" OFF)
|
||||
if(EIGEN_TEST_ALTIVEC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maltivec -mabi=altivec")
|
||||
message(STATUS "Enabling AltiVec in tests/examples")
|
||||
endif()
|
||||
|
||||
option(EIGEN_TEST_VSX "Enable/Disable VSX in tests/examples" OFF)
|
||||
if(EIGEN_TEST_VSX)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64 -mvsx")
|
||||
message(STATUS "Enabling VSX in tests/examples")
|
||||
endif()
|
||||
|
||||
option(EIGEN_TEST_NEON "Enable/Disable Neon in tests/examples" OFF)
|
||||
if(EIGEN_TEST_NEON)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -mcpu=cortex-a"8)
|
||||
if(EIGEN_TEST_FMA)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon-vfpv4")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon")
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfloat-abi=softfp")
|
||||
message(STATUS "Enabling NEON in tests/examples")
|
||||
endif()
|
||||
|
||||
option(EIGEN_TEST_NEON64 "Enable/Disable Neon in tests/examples" OFF)
|
||||
if(EIGEN_TEST_NEON64)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
message(STATUS "Enabling NEON in tests/examples")
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
check_cxx_compiler_flag("-fopenmp" COMPILER_SUPPORT_OPENMP)
|
||||
if(COMPILER_SUPPORT_OPENMP)
|
||||
option(EIGEN_TEST_OPENMP "Enable/Disable OpenMP in tests/examples" OFF)
|
||||
@@ -284,7 +331,13 @@ if(EIGEN_TEST_NO_EXPLICIT_ALIGNMENT)
|
||||
message(STATUS "Disabling alignment in tests/examples")
|
||||
endif()
|
||||
|
||||
option(EIGEN_TEST_C++0x "Enables all C++0x features." OFF)
|
||||
option(EIGEN_TEST_NO_EXCEPTIONS "Disables C++ exceptions" OFF)
|
||||
if(EIGEN_TEST_NO_EXCEPTIONS)
|
||||
ei_add_cxx_compiler_flag("-fno-exceptions")
|
||||
message(STATUS "Disabling exceptions in tests/examples")
|
||||
endif()
|
||||
|
||||
option(EIGEN_TEST_CXX11 "Enable testing with C++11 and C++11 features (e.g. Tensor module)." OFF)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
@@ -411,6 +464,7 @@ if(cmake_generator_tolower MATCHES "makefile")
|
||||
message(STATUS "make check | Build and run the unit-tests. Read this page:")
|
||||
message(STATUS " | http://eigen.tuxfamily.org/index.php?title=Tests")
|
||||
message(STATUS "make blas | Build BLAS library (not the same thing as Eigen)")
|
||||
message(STATUS "make uninstall| Removes files installed by make install")
|
||||
message(STATUS "--------------+--------------------------------------------------------------")
|
||||
else()
|
||||
message(STATUS "To build/run the unit tests, read this page:")
|
||||
@@ -418,3 +472,35 @@ else()
|
||||
endif()
|
||||
|
||||
message(STATUS "")
|
||||
|
||||
set ( EIGEN_CONFIG_CMAKE_PATH
|
||||
lib${LIB_SUFFIX}/cmake/eigen3
|
||||
CACHE PATH "The directory where the CMake files are installed"
|
||||
)
|
||||
if ( NOT IS_ABSOLUTE EIGEN_CONFIG_CMAKE_PATH )
|
||||
set ( EIGEN_CONFIG_CMAKE_PATH ${CMAKE_INSTALL_PREFIX}/${EIGEN_CONFIG_CMAKE_PATH} )
|
||||
endif ()
|
||||
|
||||
set ( EIGEN_USE_FILE ${EIGEN_CONFIG_CMAKE_PATH}/UseEigen3.cmake )
|
||||
set ( EIGEN_VERSION_STRING ${EIGEN_VERSION_NUMBER} )
|
||||
set ( EIGEN_VERSION_MAJOR ${EIGEN_WORLD_VERSION} )
|
||||
set ( EIGEN_VERSION_MINOR ${EIGEN_MAJOR_VERSION} )
|
||||
set ( EIGEN_VERSION_PATCH ${EIGEN_MINOR_VERSION} )
|
||||
set ( EIGEN_DEFINITIONS "")
|
||||
set ( EIGEN_INCLUDE_DIR ${INCLUDE_INSTALL_DIR} )
|
||||
set ( EIGEN_INCLUDE_DIRS ${EIGEN_INCLUDE_DIR} )
|
||||
set ( EIGEN_ROOT_DIR ${CMAKE_INSTALL_PREFIX} )
|
||||
|
||||
configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Eigen3Config.cmake.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Eigen3Config.cmake
|
||||
@ONLY ESCAPE_QUOTES
|
||||
)
|
||||
|
||||
install ( FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/UseEigen3.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Eigen3Config.cmake
|
||||
DESTINATION ${EIGEN_CONFIG_CMAKE_PATH}
|
||||
)
|
||||
|
||||
# Add uninstall target
|
||||
add_custom_target ( uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/EigenUninstall.cmake)
|
||||
|
||||
11
Eigen/Array
11
Eigen/Array
@@ -1,11 +0,0 @@
|
||||
#ifndef EIGEN_ARRAY_MODULE_H
|
||||
#define EIGEN_ARRAY_MODULE_H
|
||||
|
||||
// include Core first to handle Eigen2 support macros
|
||||
#include "Core"
|
||||
|
||||
#ifndef EIGEN2_SUPPORT
|
||||
#error The Eigen/Array header does no longer exist in Eigen3. All that functionality has moved to Eigen/Core.
|
||||
#endif
|
||||
|
||||
#endif // EIGEN_ARRAY_MODULE_H
|
||||
@@ -10,16 +10,17 @@
|
||||
*
|
||||
*
|
||||
* This module provides two variants of the Cholesky decomposition for selfadjoint (hermitian) matrices.
|
||||
* Those decompositions are accessible via the following MatrixBase methods:
|
||||
* - MatrixBase::llt(),
|
||||
* Those decompositions are also accessible via the following methods:
|
||||
* - MatrixBase::llt()
|
||||
* - MatrixBase::ldlt()
|
||||
* - SelfAdjointView::llt()
|
||||
* - SelfAdjointView::ldlt()
|
||||
*
|
||||
* \code
|
||||
* #include <Eigen/Cholesky>
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
#include "src/misc/Solve.h"
|
||||
#include "src/Cholesky/LLT.h"
|
||||
#include "src/Cholesky/LDLT.h"
|
||||
#ifdef EIGEN_USE_LAPACKE
|
||||
|
||||
@@ -33,12 +33,8 @@ extern "C" {
|
||||
*
|
||||
*/
|
||||
|
||||
#include "src/misc/Solve.h"
|
||||
#include "src/misc/SparseSolve.h"
|
||||
|
||||
#include "src/CholmodSupport/CholmodSupport.h"
|
||||
|
||||
|
||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||
|
||||
#endif // EIGEN_CHOLMODSUPPORT_MODULE_H
|
||||
|
||||
202
Eigen/Core
202
Eigen/Core
@@ -14,6 +14,48 @@
|
||||
// first thing Eigen does: stop the compiler from committing suicide
|
||||
#include "src/Core/util/DisableStupidWarnings.h"
|
||||
|
||||
// Handle NVCC/CUDA
|
||||
#ifdef __CUDACC__
|
||||
// Do not try asserts on CUDA!
|
||||
#ifndef EIGEN_NO_DEBUG
|
||||
#define EIGEN_NO_DEBUG
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_INTERNAL_DEBUGGING
|
||||
#undef EIGEN_INTERNAL_DEBUGGING
|
||||
#endif
|
||||
|
||||
// Do not try to vectorize on CUDA!
|
||||
#ifndef EIGEN_DONT_VECTORIZE
|
||||
#define EIGEN_DONT_VECTORIZE
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_EXCEPTIONS
|
||||
#undef EIGEN_EXCEPTIONS
|
||||
#endif
|
||||
|
||||
// All functions callable from CUDA code must be qualified with __device__
|
||||
#define EIGEN_DEVICE_FUNC __host__ __device__
|
||||
|
||||
#else
|
||||
#define EIGEN_DEVICE_FUNC
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__CUDA_ARCH__)
|
||||
#define EIGEN_USING_STD_MATH(FUNC) using ::FUNC;
|
||||
#else
|
||||
#define EIGEN_USING_STD_MATH(FUNC) using std::FUNC;
|
||||
#endif
|
||||
|
||||
#if (defined(_CPPUNWIND) || defined(__EXCEPTIONS)) && !defined(__CUDA_ARCH__) && !defined(EIGEN_EXCEPTIONS)
|
||||
#define EIGEN_EXCEPTIONS
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_EXCEPTIONS
|
||||
#include <new>
|
||||
#endif
|
||||
|
||||
// then include this file where all our macros are defined. It's really important to do it first because
|
||||
// it's where we do all the alignment settings (platform detection and honoring the user's will if he
|
||||
// defined e.g. EIGEN_DONT_ALIGN) so it needs to be done before we do anything with vectorization.
|
||||
@@ -21,7 +63,7 @@
|
||||
|
||||
// Disable the ipa-cp-clone optimization flag with MinGW 6.x or newer (enabled by default with -O3)
|
||||
// See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=556 for details.
|
||||
#if defined(__MINGW32__) && EIGEN_GNUC_AT_LEAST(4,6)
|
||||
#if EIGEN_COMP_MINGW && EIGEN_GNUC_AT_LEAST(4,6)
|
||||
#pragma GCC optimize ("-fno-ipa-cp-clone")
|
||||
#endif
|
||||
|
||||
@@ -31,26 +73,26 @@
|
||||
// and inclusion of their respective header files
|
||||
#include "src/Core/util/MKL_support.h"
|
||||
|
||||
// if alignment is disabled, then disable vectorization. Note: EIGEN_ALIGN is the proper check, it takes into
|
||||
// account both the user's will (EIGEN_DONT_ALIGN) and our own platform checks
|
||||
#if !EIGEN_ALIGN
|
||||
// if alignment is disabled, then disable vectorization. Note: EIGEN_MAX_ALIGN_BYTES is the proper check, it takes into
|
||||
// account both the user's will (EIGEN_MAX_ALIGN_BYTES,EIGEN_DONT_ALIGN) and our own platform checks
|
||||
#if EIGEN_MAX_ALIGN_BYTES==0
|
||||
#ifndef EIGEN_DONT_VECTORIZE
|
||||
#define EIGEN_DONT_VECTORIZE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if EIGEN_COMP_MSVC
|
||||
#include <malloc.h> // for _aligned_malloc -- need it regardless of whether vectorization is enabled
|
||||
#if (_MSC_VER >= 1500) // 2008 or later
|
||||
#if (EIGEN_COMP_MSVC >= 1500) // 2008 or later
|
||||
// Remember that usage of defined() in a #define is undefined by the standard.
|
||||
// a user reported that in 64-bit mode, MSVC doesn't care to define _M_IX86_FP.
|
||||
#if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(_M_X64)
|
||||
#if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || EIGEN_ARCH_x86_64
|
||||
#define EIGEN_SSE2_ON_MSVC_2008_OR_LATER
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
// Remember that usage of defined() in a #define is undefined by the standard
|
||||
#if (defined __SSE2__) && ( (!defined __GNUC__) || (defined __INTEL_COMPILER) || EIGEN_GNUC_AT_LEAST(4,2) )
|
||||
#if (defined __SSE2__) && ( (!EIGEN_COMP_GNUC) || EIGEN_COMP_ICC || EIGEN_GNUC_AT_LEAST(4,2) )
|
||||
#define EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC
|
||||
#endif
|
||||
#endif
|
||||
@@ -82,6 +124,19 @@
|
||||
#ifdef __SSE4_2__
|
||||
#define EIGEN_VECTORIZE_SSE4_2
|
||||
#endif
|
||||
#ifdef __AVX__
|
||||
#define EIGEN_VECTORIZE_AVX
|
||||
#define EIGEN_VECTORIZE_SSE3
|
||||
#define EIGEN_VECTORIZE_SSSE3
|
||||
#define EIGEN_VECTORIZE_SSE4_1
|
||||
#define EIGEN_VECTORIZE_SSE4_2
|
||||
#endif
|
||||
#ifdef __AVX2__
|
||||
#define EIGEN_VECTORIZE_AVX2
|
||||
#endif
|
||||
#ifdef __FMA__
|
||||
#define EIGEN_VECTORIZE_FMA
|
||||
#endif
|
||||
|
||||
// include files
|
||||
|
||||
@@ -95,7 +150,7 @@
|
||||
extern "C" {
|
||||
// In theory we should only include immintrin.h and not the other *mmintrin.h header files directly.
|
||||
// Doing so triggers some issues with ICC. However old gcc versions seems to not have this file, thus:
|
||||
#ifdef __INTEL_COMPILER
|
||||
#if EIGEN_COMP_ICC >= 1110
|
||||
#include <immintrin.h>
|
||||
#else
|
||||
#include <emmintrin.h>
|
||||
@@ -112,8 +167,20 @@
|
||||
#ifdef EIGEN_VECTORIZE_SSE4_2
|
||||
#include <nmmintrin.h>
|
||||
#endif
|
||||
#ifdef EIGEN_VECTORIZE_AVX
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
#endif
|
||||
} // end extern "C"
|
||||
#elif defined __VSX__
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_VSX
|
||||
#include <altivec.h>
|
||||
// We need to #undef all these ugly tokens defined in <altivec.h>
|
||||
// => use __vector instead of vector
|
||||
#undef bool
|
||||
#undef vector
|
||||
#undef pixel
|
||||
#elif defined __ALTIVEC__
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_ALTIVEC
|
||||
@@ -123,13 +190,18 @@
|
||||
#undef bool
|
||||
#undef vector
|
||||
#undef pixel
|
||||
#elif defined __ARM_NEON__
|
||||
#elif (defined __ARM_NEON) || (defined __ARM_NEON__)
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_NEON
|
||||
#include <arm_neon.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined __CUDACC__
|
||||
#define EIGEN_VECTORIZE_CUDA
|
||||
#include <vector_types.h>
|
||||
#endif
|
||||
|
||||
#if (defined _OPENMP) && (!defined EIGEN_DONT_PARALLELIZE)
|
||||
#define EIGEN_HAS_OPENMP
|
||||
#endif
|
||||
@@ -139,7 +211,7 @@
|
||||
#endif
|
||||
|
||||
// MSVC for windows mobile does not have the errno.h file
|
||||
#if !(defined(_MSC_VER) && defined(_WIN32_WCE)) && !defined(__ARMCC_VERSION)
|
||||
#if !(EIGEN_COMP_MSVC && EIGEN_OS_WINCE) && !EIGEN_COMP_ARM
|
||||
#define EIGEN_HAS_ERRNO
|
||||
#endif
|
||||
|
||||
@@ -165,23 +237,17 @@
|
||||
#endif
|
||||
|
||||
// required for __cpuid, needs to be included after cmath
|
||||
#if defined(_MSC_VER) && (defined(_M_IX86)||defined(_M_X64))
|
||||
#if EIGEN_COMP_MSVC && EIGEN_ARCH_i386_OR_x86_64 && !EIGEN_OS_WINCE
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#if defined(_CPPUNWIND) || defined(__EXCEPTIONS)
|
||||
#define EIGEN_EXCEPTIONS
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_EXCEPTIONS
|
||||
#include <new>
|
||||
#endif
|
||||
|
||||
/** \brief Namespace containing all symbols from the %Eigen library. */
|
||||
namespace Eigen {
|
||||
|
||||
inline static const char *SimdInstructionSetsInUse(void) {
|
||||
#if defined(EIGEN_VECTORIZE_SSE4_2)
|
||||
#if defined(EIGEN_VECTORIZE_AVX)
|
||||
return "AVX SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2";
|
||||
#elif defined(EIGEN_VECTORIZE_SSE4_2)
|
||||
return "SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2";
|
||||
#elif defined(EIGEN_VECTORIZE_SSE4_1)
|
||||
return "SSE, SSE2, SSE3, SSSE3, SSE4.1";
|
||||
@@ -193,6 +259,8 @@ inline static const char *SimdInstructionSetsInUse(void) {
|
||||
return "SSE, SSE2";
|
||||
#elif defined(EIGEN_VECTORIZE_ALTIVEC)
|
||||
return "AltiVec";
|
||||
#elif defined(EIGEN_VECTORIZE_VSX)
|
||||
return "VSX";
|
||||
#elif defined(EIGEN_VECTORIZE_NEON)
|
||||
return "ARM NEON";
|
||||
#else
|
||||
@@ -202,34 +270,9 @@ inline static const char *SimdInstructionSetsInUse(void) {
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#define STAGE10_FULL_EIGEN2_API 10
|
||||
#define STAGE20_RESOLVE_API_CONFLICTS 20
|
||||
#define STAGE30_FULL_EIGEN3_API 30
|
||||
#define STAGE40_FULL_EIGEN3_STRICTNESS 40
|
||||
#define STAGE99_NO_EIGEN2_SUPPORT 99
|
||||
|
||||
#if defined EIGEN2_SUPPORT_STAGE40_FULL_EIGEN3_STRICTNESS
|
||||
#define EIGEN2_SUPPORT
|
||||
#define EIGEN2_SUPPORT_STAGE STAGE40_FULL_EIGEN3_STRICTNESS
|
||||
#elif defined EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API
|
||||
#define EIGEN2_SUPPORT
|
||||
#define EIGEN2_SUPPORT_STAGE STAGE30_FULL_EIGEN3_API
|
||||
#elif defined EIGEN2_SUPPORT_STAGE20_RESOLVE_API_CONFLICTS
|
||||
#define EIGEN2_SUPPORT
|
||||
#define EIGEN2_SUPPORT_STAGE STAGE20_RESOLVE_API_CONFLICTS
|
||||
#elif defined EIGEN2_SUPPORT_STAGE10_FULL_EIGEN2_API
|
||||
#define EIGEN2_SUPPORT
|
||||
#define EIGEN2_SUPPORT_STAGE STAGE10_FULL_EIGEN2_API
|
||||
#elif defined EIGEN2_SUPPORT
|
||||
// default to stage 3, that's what it's always meant
|
||||
#define EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API
|
||||
#define EIGEN2_SUPPORT_STAGE STAGE30_FULL_EIGEN3_API
|
||||
#else
|
||||
#define EIGEN2_SUPPORT_STAGE STAGE99_NO_EIGEN2_SUPPORT
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
#undef minor
|
||||
#if defined EIGEN2_SUPPORT_STAGE40_FULL_EIGEN3_STRICTNESS || defined EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API || defined EIGEN2_SUPPORT_STAGE20_RESOLVE_API_CONFLICTS || defined EIGEN2_SUPPORT_STAGE10_FULL_EIGEN2_API || defined EIGEN2_SUPPORT
|
||||
// This will generate an error message:
|
||||
#error Eigen2-support is only available up to version 3.2. Please go to "http://eigen.tuxfamily.org/index.php?title=Eigen2" for further information
|
||||
#endif
|
||||
|
||||
// we use size_t frequently and we'll never remember to prepend it with std:: everytime just to
|
||||
@@ -249,8 +292,8 @@ using std::ptrdiff_t;
|
||||
*/
|
||||
|
||||
#include "src/Core/util/Constants.h"
|
||||
#include "src/Core/util/ForwardDeclarations.h"
|
||||
#include "src/Core/util/Meta.h"
|
||||
#include "src/Core/util/ForwardDeclarations.h"
|
||||
#include "src/Core/util/StaticAssert.h"
|
||||
#include "src/Core/util/XprHelper.h"
|
||||
#include "src/Core/util/Memory.h"
|
||||
@@ -259,35 +302,64 @@ using std::ptrdiff_t;
|
||||
#include "src/Core/MathFunctions.h"
|
||||
#include "src/Core/GenericPacketMath.h"
|
||||
|
||||
#if defined EIGEN_VECTORIZE_SSE
|
||||
#if defined EIGEN_VECTORIZE_AVX
|
||||
// Use AVX for floats and doubles, SSE for integers
|
||||
#include "src/Core/arch/SSE/PacketMath.h"
|
||||
#include "src/Core/arch/SSE/Complex.h"
|
||||
#include "src/Core/arch/SSE/MathFunctions.h"
|
||||
#include "src/Core/arch/AVX/PacketMath.h"
|
||||
#include "src/Core/arch/AVX/MathFunctions.h"
|
||||
#include "src/Core/arch/AVX/Complex.h"
|
||||
#include "src/Core/arch/AVX/TypeCasting.h"
|
||||
#elif defined EIGEN_VECTORIZE_SSE
|
||||
#include "src/Core/arch/SSE/PacketMath.h"
|
||||
#include "src/Core/arch/SSE/MathFunctions.h"
|
||||
#include "src/Core/arch/SSE/Complex.h"
|
||||
#elif defined EIGEN_VECTORIZE_ALTIVEC
|
||||
#include "src/Core/arch/SSE/TypeCasting.h"
|
||||
#elif defined(EIGEN_VECTORIZE_ALTIVEC) || defined(EIGEN_VECTORIZE_VSX)
|
||||
#include "src/Core/arch/AltiVec/PacketMath.h"
|
||||
#include "src/Core/arch/AltiVec/MathFunctions.h"
|
||||
#include "src/Core/arch/AltiVec/Complex.h"
|
||||
#elif defined EIGEN_VECTORIZE_NEON
|
||||
#include "src/Core/arch/NEON/PacketMath.h"
|
||||
#include "src/Core/arch/NEON/MathFunctions.h"
|
||||
#include "src/Core/arch/NEON/Complex.h"
|
||||
#endif
|
||||
|
||||
#if defined EIGEN_VECTORIZE_CUDA
|
||||
#include "src/Core/arch/CUDA/PacketMath.h"
|
||||
#include "src/Core/arch/CUDA/MathFunctions.h"
|
||||
#endif
|
||||
|
||||
#include "src/Core/arch/Default/Settings.h"
|
||||
|
||||
#include "src/Core/Functors.h"
|
||||
#include "src/Core/functors/BinaryFunctors.h"
|
||||
#include "src/Core/functors/UnaryFunctors.h"
|
||||
#include "src/Core/functors/NullaryFunctors.h"
|
||||
#include "src/Core/functors/StlFunctors.h"
|
||||
#include "src/Core/functors/AssignmentFunctors.h"
|
||||
|
||||
#include "src/Core/DenseCoeffsBase.h"
|
||||
#include "src/Core/DenseBase.h"
|
||||
#include "src/Core/MatrixBase.h"
|
||||
#include "src/Core/EigenBase.h"
|
||||
|
||||
#include "src/Core/Product.h"
|
||||
#include "src/Core/CoreEvaluators.h"
|
||||
#include "src/Core/AssignEvaluator.h"
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN // work around Doxygen bug triggered by Assign.h r814874
|
||||
// at least confirmed with Doxygen 1.5.5 and 1.5.6
|
||||
#include "src/Core/Assign.h"
|
||||
#endif
|
||||
|
||||
#include "src/Core/ArrayBase.h"
|
||||
#include "src/Core/util/BlasUtil.h"
|
||||
#include "src/Core/DenseStorage.h"
|
||||
#include "src/Core/NestByValue.h"
|
||||
#include "src/Core/ForceAlignedAccess.h"
|
||||
|
||||
// #include "src/Core/ForceAlignedAccess.h"
|
||||
|
||||
#include "src/Core/ReturnByValue.h"
|
||||
#include "src/Core/NoAlias.h"
|
||||
#include "src/Core/PlainObjectBase.h"
|
||||
@@ -300,12 +372,12 @@ using std::ptrdiff_t;
|
||||
#include "src/Core/SelfCwiseBinaryOp.h"
|
||||
#include "src/Core/Dot.h"
|
||||
#include "src/Core/StableNorm.h"
|
||||
#include "src/Core/MapBase.h"
|
||||
#include "src/Core/Stride.h"
|
||||
#include "src/Core/MapBase.h"
|
||||
#include "src/Core/Map.h"
|
||||
#include "src/Core/Ref.h"
|
||||
#include "src/Core/Block.h"
|
||||
#include "src/Core/VectorBlock.h"
|
||||
#include "src/Core/Ref.h"
|
||||
#include "src/Core/Transpose.h"
|
||||
#include "src/Core/DiagonalMatrix.h"
|
||||
#include "src/Core/Diagonal.h"
|
||||
@@ -318,14 +390,14 @@ using std::ptrdiff_t;
|
||||
#include "src/Core/IO.h"
|
||||
#include "src/Core/Swap.h"
|
||||
#include "src/Core/CommaInitializer.h"
|
||||
#include "src/Core/Flagged.h"
|
||||
#include "src/Core/ProductBase.h"
|
||||
#include "src/Core/GeneralProduct.h"
|
||||
#include "src/Core/Solve.h"
|
||||
#include "src/Core/Inverse.h"
|
||||
#include "src/Core/TriangularMatrix.h"
|
||||
#include "src/Core/SelfAdjointView.h"
|
||||
#include "src/Core/products/GeneralBlockPanelKernel.h"
|
||||
#include "src/Core/products/Parallelizer.h"
|
||||
#include "src/Core/products/CoeffBasedProduct.h"
|
||||
#include "src/Core/ProductEvaluators.h"
|
||||
#include "src/Core/products/GeneralMatrixVector.h"
|
||||
#include "src/Core/products/GeneralMatrixMatrix.h"
|
||||
#include "src/Core/SolveTriangular.h"
|
||||
@@ -347,16 +419,8 @@ using std::ptrdiff_t;
|
||||
#include "src/Core/Random.h"
|
||||
#include "src/Core/Replicate.h"
|
||||
#include "src/Core/Reverse.h"
|
||||
#include "src/Core/ArrayBase.h"
|
||||
#include "src/Core/ArrayWrapper.h"
|
||||
|
||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
||||
#include "src/Core/Product.h"
|
||||
#include "src/Core/CoreEvaluators.h"
|
||||
#include "src/Core/AssignEvaluator.h"
|
||||
#include "src/Core/ProductEvaluators.h"
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_USE_BLAS
|
||||
#include "src/Core/products/GeneralMatrixMatrix_MKL.h"
|
||||
#include "src/Core/products/GeneralMatrixVector_MKL.h"
|
||||
@@ -376,8 +440,4 @@ using std::ptrdiff_t;
|
||||
|
||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
#include "Eigen2Support"
|
||||
#endif
|
||||
|
||||
#endif // EIGEN_CORE_H
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
#include "Dense"
|
||||
//#include "Sparse"
|
||||
#include "Sparse"
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef EIGEN2SUPPORT_H
|
||||
#define EIGEN2SUPPORT_H
|
||||
|
||||
#if (!defined(EIGEN2_SUPPORT)) || (!defined(EIGEN_CORE_H))
|
||||
#error Eigen2 support must be enabled by defining EIGEN2_SUPPORT before including any Eigen header
|
||||
#endif
|
||||
|
||||
#include "src/Core/util/DisableStupidWarnings.h"
|
||||
|
||||
/** \ingroup Support_modules
|
||||
* \defgroup Eigen2Support_Module Eigen2 support module
|
||||
* This module provides a couple of deprecated functions improving the compatibility with Eigen2.
|
||||
*
|
||||
* To use it, define EIGEN2_SUPPORT before including any Eigen header
|
||||
* \code
|
||||
* #define EIGEN2_SUPPORT
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
|
||||
#include "src/Eigen2Support/Macros.h"
|
||||
#include "src/Eigen2Support/Memory.h"
|
||||
#include "src/Eigen2Support/Meta.h"
|
||||
#include "src/Eigen2Support/Lazy.h"
|
||||
#include "src/Eigen2Support/Cwise.h"
|
||||
#include "src/Eigen2Support/CwiseOperators.h"
|
||||
#include "src/Eigen2Support/TriangularSolver.h"
|
||||
#include "src/Eigen2Support/Block.h"
|
||||
#include "src/Eigen2Support/VectorBlock.h"
|
||||
#include "src/Eigen2Support/Minor.h"
|
||||
#include "src/Eigen2Support/MathFunctions.h"
|
||||
|
||||
|
||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||
|
||||
// Eigen2 used to include iostream
|
||||
#include<iostream>
|
||||
|
||||
#define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \
|
||||
using Eigen::Matrix##SizeSuffix##TypeSuffix; \
|
||||
using Eigen::Vector##SizeSuffix##TypeSuffix; \
|
||||
using Eigen::RowVector##SizeSuffix##TypeSuffix;
|
||||
|
||||
#define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(TypeSuffix) \
|
||||
EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \
|
||||
EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \
|
||||
EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \
|
||||
EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \
|
||||
|
||||
#define EIGEN_USING_MATRIX_TYPEDEFS \
|
||||
EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(i) \
|
||||
EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(f) \
|
||||
EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(d) \
|
||||
EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cf) \
|
||||
EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cd)
|
||||
|
||||
#define USING_PART_OF_NAMESPACE_EIGEN \
|
||||
EIGEN_USING_MATRIX_TYPEDEFS \
|
||||
using Eigen::Matrix; \
|
||||
using Eigen::MatrixBase; \
|
||||
using Eigen::ei_random; \
|
||||
using Eigen::ei_real; \
|
||||
using Eigen::ei_imag; \
|
||||
using Eigen::ei_conj; \
|
||||
using Eigen::ei_abs; \
|
||||
using Eigen::ei_abs2; \
|
||||
using Eigen::ei_sqrt; \
|
||||
using Eigen::ei_exp; \
|
||||
using Eigen::ei_log; \
|
||||
using Eigen::ei_sin; \
|
||||
using Eigen::ei_cos;
|
||||
|
||||
#endif // EIGEN2SUPPORT_H
|
||||
@@ -9,10 +9,6 @@
|
||||
#include "LU"
|
||||
#include <limits>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
/** \defgroup Geometry_Module Geometry module
|
||||
*
|
||||
*
|
||||
@@ -33,27 +29,23 @@
|
||||
#include "src/Geometry/OrthoMethods.h"
|
||||
#include "src/Geometry/EulerAngles.h"
|
||||
|
||||
#if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS
|
||||
#include "src/Geometry/Homogeneous.h"
|
||||
#include "src/Geometry/RotationBase.h"
|
||||
#include "src/Geometry/Rotation2D.h"
|
||||
#include "src/Geometry/Quaternion.h"
|
||||
#include "src/Geometry/AngleAxis.h"
|
||||
#include "src/Geometry/Transform.h"
|
||||
#include "src/Geometry/Translation.h"
|
||||
#include "src/Geometry/Scaling.h"
|
||||
#include "src/Geometry/Hyperplane.h"
|
||||
#include "src/Geometry/ParametrizedLine.h"
|
||||
#include "src/Geometry/AlignedBox.h"
|
||||
#include "src/Geometry/Umeyama.h"
|
||||
#include "src/Geometry/Homogeneous.h"
|
||||
#include "src/Geometry/RotationBase.h"
|
||||
#include "src/Geometry/Rotation2D.h"
|
||||
#include "src/Geometry/Quaternion.h"
|
||||
#include "src/Geometry/AngleAxis.h"
|
||||
#include "src/Geometry/Transform.h"
|
||||
#include "src/Geometry/Translation.h"
|
||||
#include "src/Geometry/Scaling.h"
|
||||
#include "src/Geometry/Hyperplane.h"
|
||||
#include "src/Geometry/ParametrizedLine.h"
|
||||
#include "src/Geometry/AlignedBox.h"
|
||||
#include "src/Geometry/Umeyama.h"
|
||||
|
||||
#if defined EIGEN_VECTORIZE_SSE
|
||||
#include "src/Geometry/arch/Geometry_SSE.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
#include "src/Eigen2Support/Geometry/All.h"
|
||||
// Use the SSE optimized version whenever possible. At the moment the
|
||||
// SSE version doesn't compile when AVX is enabled
|
||||
#if defined EIGEN_VECTORIZE_SSE && !defined EIGEN_VECTORIZE_AVX
|
||||
#include "src/Geometry/arch/Geometry_SSE.h"
|
||||
#endif
|
||||
|
||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||
|
||||
@@ -12,26 +12,26 @@
|
||||
* This module currently provides iterative methods to solve problems of the form \c A \c x = \c b, where \c A is a squared matrix, usually very large and sparse.
|
||||
* Those solvers are accessible via the following classes:
|
||||
* - ConjugateGradient for selfadjoint (hermitian) matrices,
|
||||
* - LeastSquaresConjugateGradient for rectangular least-square problems,
|
||||
* - BiCGSTAB for general square matrices.
|
||||
*
|
||||
* These iterative solvers are associated with some preconditioners:
|
||||
* - IdentityPreconditioner - not really useful
|
||||
* - DiagonalPreconditioner - also called JAcobi preconditioner, work very well on diagonal dominant matrices.
|
||||
* - IncompleteILUT - incomplete LU factorization with dual thresholding
|
||||
* - DiagonalPreconditioner - also called Jacobi preconditioner, work very well on diagonal dominant matrices.
|
||||
* - IncompleteLUT - incomplete LU factorization with dual thresholding
|
||||
*
|
||||
* Such problems can also be solved using the direct sparse decomposition modules: SparseCholesky, CholmodSupport, UmfPackSupport, SuperLUSupport.
|
||||
*
|
||||
* \code
|
||||
* #include <Eigen/IterativeLinearSolvers>
|
||||
* \endcode
|
||||
\code
|
||||
#include <Eigen/IterativeLinearSolvers>
|
||||
\endcode
|
||||
*/
|
||||
|
||||
#include "src/misc/Solve.h"
|
||||
#include "src/misc/SparseSolve.h"
|
||||
|
||||
#include "src/IterativeLinearSolvers/SolveWithGuess.h"
|
||||
#include "src/IterativeLinearSolvers/IterativeSolverBase.h"
|
||||
#include "src/IterativeLinearSolvers/BasicPreconditioners.h"
|
||||
#include "src/IterativeLinearSolvers/ConjugateGradient.h"
|
||||
#include "src/IterativeLinearSolvers/LeastSquareConjugateGradient.h"
|
||||
#include "src/IterativeLinearSolvers/BiCGSTAB.h"
|
||||
#include "src/IterativeLinearSolvers/IncompleteLUT.h"
|
||||
|
||||
|
||||
11
Eigen/LU
11
Eigen/LU
@@ -16,7 +16,6 @@
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
#include "src/misc/Solve.h"
|
||||
#include "src/misc/Kernel.h"
|
||||
#include "src/misc/Image.h"
|
||||
#include "src/LU/FullPivLU.h"
|
||||
@@ -25,16 +24,14 @@
|
||||
#include "src/LU/PartialPivLU_MKL.h"
|
||||
#endif
|
||||
#include "src/LU/Determinant.h"
|
||||
#include "src/LU/Inverse.h"
|
||||
#include "src/LU/InverseImpl.h"
|
||||
|
||||
#if defined EIGEN_VECTORIZE_SSE
|
||||
// Use the SSE optimized version whenever possible. At the moment the
|
||||
// SSE version doesn't compile when AVX is enabled
|
||||
#if defined EIGEN_VECTORIZE_SSE && !defined EIGEN_VECTORIZE_AVX
|
||||
#include "src/LU/arch/Inverse_SSE.h"
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
#include "src/Eigen2Support/LU.h"
|
||||
#endif
|
||||
|
||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||
|
||||
#endif // EIGEN_LU_MODULE_H
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
#ifndef EIGEN_REGRESSION_MODULE_H
|
||||
#define EIGEN_REGRESSION_MODULE_H
|
||||
|
||||
#ifndef EIGEN2_SUPPORT
|
||||
#error LeastSquares is only available in Eigen2 support mode (define EIGEN2_SUPPORT)
|
||||
#endif
|
||||
|
||||
// exclude from normal eigen3-only documentation
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
|
||||
#include "Core"
|
||||
|
||||
#include "src/Core/util/DisableStupidWarnings.h"
|
||||
|
||||
#include "Eigenvalues"
|
||||
#include "Geometry"
|
||||
|
||||
/** \defgroup LeastSquares_Module LeastSquares module
|
||||
* This module provides linear regression and related features.
|
||||
*
|
||||
* \code
|
||||
* #include <Eigen/LeastSquares>
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
#include "src/Eigen2Support/LeastSquares.h"
|
||||
|
||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||
|
||||
#endif // EIGEN2_SUPPORT
|
||||
|
||||
#endif // EIGEN_REGRESSION_MODULE_H
|
||||
@@ -35,12 +35,8 @@ extern "C" {
|
||||
*
|
||||
*/
|
||||
|
||||
#include "src/misc/Solve.h"
|
||||
#include "src/misc/SparseSolve.h"
|
||||
|
||||
#include "src/PaStiXSupport/PaStiXSupport.h"
|
||||
|
||||
|
||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||
|
||||
#endif // EIGEN_PASTIXSUPPORT_MODULE_H
|
||||
|
||||
13
Eigen/QR
13
Eigen/QR
@@ -15,14 +15,15 @@
|
||||
*
|
||||
* This module provides various QR decompositions
|
||||
* This module also provides some MatrixBase methods, including:
|
||||
* - MatrixBase::qr(),
|
||||
* - MatrixBase::householderQr()
|
||||
* - MatrixBase::colPivHouseholderQr()
|
||||
* - MatrixBase::fullPivHouseholderQr()
|
||||
*
|
||||
* \code
|
||||
* #include <Eigen/QR>
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
#include "src/misc/Solve.h"
|
||||
#include "src/QR/HouseholderQR.h"
|
||||
#include "src/QR/FullPivHouseholderQR.h"
|
||||
#include "src/QR/ColPivHouseholderQR.h"
|
||||
@@ -31,15 +32,7 @@
|
||||
#include "src/QR/ColPivHouseholderQR_MKL.h"
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
#include "src/Eigen2Support/QR.h"
|
||||
#endif
|
||||
|
||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
#include "Eigenvalues"
|
||||
#endif
|
||||
|
||||
#endif // EIGEN_QR_MODULE_H
|
||||
/* vim: set filetype=cpp et sw=2 ts=2 ai: */
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "src/misc/Solve.h"
|
||||
#include "src/misc/SparseSolve.h"
|
||||
#include "src/CholmodSupport/CholmodSupport.h"
|
||||
#include "src/SPQRSupport/SuiteSparseQRSupport.h"
|
||||
|
||||
|
||||
15
Eigen/SVD
15
Eigen/SVD
@@ -12,24 +12,25 @@
|
||||
*
|
||||
*
|
||||
* This module provides SVD decomposition for matrices (both real and complex).
|
||||
* This decomposition is accessible via the following MatrixBase method:
|
||||
* Two decomposition algorithms are provided:
|
||||
* - JacobiSVD implementing two-sided Jacobi iterations is numerically very accurate, fast for small matrices, but very slow for larger ones.
|
||||
* - BDCSVD implementing a recursive divide & conquer strategy on top of an upper-bidiagonalization which remains fast for large problems.
|
||||
* These decompositions are accessible via the respective classes and following MatrixBase methods:
|
||||
* - MatrixBase::jacobiSvd()
|
||||
* - MatrixBase::bdcSvd()
|
||||
*
|
||||
* \code
|
||||
* #include <Eigen/SVD>
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
#include "src/misc/Solve.h"
|
||||
#include "src/SVD/UpperBidiagonalization.h"
|
||||
#include "src/SVD/SVDBase.h"
|
||||
#include "src/SVD/JacobiSVD.h"
|
||||
#include "src/SVD/BDCSVD.h"
|
||||
#if defined(EIGEN_USE_LAPACKE) && !defined(EIGEN_USE_LAPACKE_STRICT)
|
||||
#include "src/SVD/JacobiSVD_MKL.h"
|
||||
#endif
|
||||
#include "src/SVD/UpperBidiagonalization.h"
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
#include "src/Eigen2Support/SVD.h"
|
||||
#endif
|
||||
|
||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
* - \ref SparseQR_Module
|
||||
* - \ref IterativeLinearSolvers_Module
|
||||
*
|
||||
* \code
|
||||
* #include <Eigen/Sparse>
|
||||
* \endcode
|
||||
\code
|
||||
#include <Eigen/Sparse>
|
||||
\endcode
|
||||
*/
|
||||
|
||||
#include "SparseCore"
|
||||
|
||||
@@ -34,8 +34,6 @@
|
||||
#error The SparseCholesky module has nothing to offer in MPL2 only mode
|
||||
#endif
|
||||
|
||||
#include "src/misc/Solve.h"
|
||||
#include "src/misc/SparseSolve.h"
|
||||
#include "src/SparseCholesky/SimplicialCholesky.h"
|
||||
|
||||
#ifndef EIGEN_MPL2_ONLY
|
||||
|
||||
@@ -26,37 +26,35 @@
|
||||
* This module depends on: Core.
|
||||
*/
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
/** The type used to identify a general sparse storage. */
|
||||
struct Sparse {};
|
||||
|
||||
}
|
||||
|
||||
#include "src/SparseCore/SparseUtil.h"
|
||||
#include "src/SparseCore/SparseMatrixBase.h"
|
||||
#include "src/SparseCore/SparseAssign.h"
|
||||
#include "src/SparseCore/CompressedStorage.h"
|
||||
#include "src/SparseCore/AmbiVector.h"
|
||||
#include "src/SparseCore/SparseCompressedBase.h"
|
||||
#include "src/SparseCore/SparseMatrix.h"
|
||||
#include "src/SparseCore/SparseMap.h"
|
||||
#include "src/SparseCore/MappedSparseMatrix.h"
|
||||
#include "src/SparseCore/SparseVector.h"
|
||||
#include "src/SparseCore/SparseBlock.h"
|
||||
#include "src/SparseCore/SparseTranspose.h"
|
||||
#include "src/SparseCore/SparseRef.h"
|
||||
#include "src/SparseCore/SparseCwiseUnaryOp.h"
|
||||
#include "src/SparseCore/SparseCwiseBinaryOp.h"
|
||||
#include "src/SparseCore/SparseTranspose.h"
|
||||
#include "src/SparseCore/SparseBlock.h"
|
||||
#include "src/SparseCore/SparseDot.h"
|
||||
#include "src/SparseCore/SparsePermutation.h"
|
||||
#include "src/SparseCore/SparseRedux.h"
|
||||
#include "src/SparseCore/SparseFuzzy.h"
|
||||
#include "src/SparseCore/SparseView.h"
|
||||
#include "src/SparseCore/SparseDiagonalProduct.h"
|
||||
#include "src/SparseCore/ConservativeSparseSparseProduct.h"
|
||||
#include "src/SparseCore/SparseSparseProductWithPruning.h"
|
||||
#include "src/SparseCore/SparseProduct.h"
|
||||
#include "src/SparseCore/SparseDenseProduct.h"
|
||||
#include "src/SparseCore/SparseDiagonalProduct.h"
|
||||
#include "src/SparseCore/SparseTriangularView.h"
|
||||
#include "src/SparseCore/SparseSelfAdjointView.h"
|
||||
#include "src/SparseCore/SparseTriangularView.h"
|
||||
#include "src/SparseCore/TriangularSolver.h"
|
||||
#include "src/SparseCore/SparseView.h"
|
||||
#include "src/SparseCore/SparsePermutation.h"
|
||||
#include "src/SparseCore/SparseFuzzy.h"
|
||||
#include "src/SparseCore/SparseSolverBase.h"
|
||||
|
||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||
|
||||
|
||||
@@ -20,9 +20,6 @@
|
||||
* Please, see the documentation of the SparseLU class for more details.
|
||||
*/
|
||||
|
||||
#include "src/misc/Solve.h"
|
||||
#include "src/misc/SparseSolve.h"
|
||||
|
||||
// Ordering interface
|
||||
#include "OrderingMethods"
|
||||
|
||||
|
||||
@@ -21,9 +21,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "src/misc/Solve.h"
|
||||
#include "src/misc/SparseSolve.h"
|
||||
|
||||
#include "OrderingMethods"
|
||||
#include "src/SparseCore/SparseColEtree.h"
|
||||
#include "src/SparseQR/SparseQR.h"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "Core"
|
||||
#include <deque>
|
||||
|
||||
#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */
|
||||
#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 /* MSVC auto aligns in 64 bit builds */
|
||||
|
||||
#define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...)
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "Core"
|
||||
#include <list>
|
||||
|
||||
#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */
|
||||
#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 /* MSVC auto aligns in 64 bit builds */
|
||||
|
||||
#define EIGEN_DEFINE_STL_LIST_SPECIALIZATION(...)
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "Core"
|
||||
#include <vector>
|
||||
|
||||
#if (defined(_MSC_VER) && defined(_WIN64)) /* MSVC auto aligns in 64 bit builds */
|
||||
#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 /* MSVC auto aligns in 64 bit builds */
|
||||
|
||||
#define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...)
|
||||
|
||||
|
||||
@@ -48,12 +48,8 @@ namespace Eigen { struct SluMatrix; }
|
||||
*
|
||||
*/
|
||||
|
||||
#include "src/misc/Solve.h"
|
||||
#include "src/misc/SparseSolve.h"
|
||||
|
||||
#include "src/SuperLUSupport/SuperLUSupport.h"
|
||||
|
||||
|
||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||
|
||||
#endif // EIGEN_SUPERLUSUPPORT_MODULE_H
|
||||
|
||||
@@ -26,9 +26,6 @@ extern "C" {
|
||||
*
|
||||
*/
|
||||
|
||||
#include "src/misc/Solve.h"
|
||||
#include "src/misc/SparseSolve.h"
|
||||
|
||||
#include "src/UmfPackSupport/UmfPackSupport.h"
|
||||
|
||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
template<typename MatrixType, int UpLo> struct LDLT_Traits;
|
||||
template<typename MatrixType, int UpLo> struct LDLT_Traits;
|
||||
|
||||
// PositiveSemiDef means positive semi-definite and non-zero; same for NegativeSemiDef
|
||||
enum SignMatrix { PositiveSemiDef, NegativeSemiDef, ZeroSign, Indefinite };
|
||||
}
|
||||
|
||||
/** \ingroup Cholesky_Module
|
||||
@@ -40,7 +43,7 @@ template<typename MatrixType, int UpLo> struct LDLT_Traits;
|
||||
* Remember that Cholesky decompositions are not rank-revealing. Also, do not use a Cholesky
|
||||
* decomposition to determine whether a system of equations has a solution.
|
||||
*
|
||||
* \sa MatrixBase::ldlt(), class LLT
|
||||
* \sa MatrixBase::ldlt(), SelfAdjointView::ldlt(), class LLT
|
||||
*/
|
||||
template<typename _MatrixType, int _UpLo> class LDLT
|
||||
{
|
||||
@@ -56,7 +59,8 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
||||
};
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
|
||||
typedef typename MatrixType::Index Index;
|
||||
typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
|
||||
typedef typename MatrixType::StorageIndex StorageIndex;
|
||||
typedef Matrix<Scalar, RowsAtCompileTime, 1, Options, MaxRowsAtCompileTime, 1> TmpMatrixType;
|
||||
|
||||
typedef Transpositions<RowsAtCompileTime, MaxRowsAtCompileTime> TranspositionType;
|
||||
@@ -69,7 +73,12 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
||||
* The default constructor is useful in cases in which the user intends to
|
||||
* perform decompositions via LDLT::compute(const MatrixType&).
|
||||
*/
|
||||
LDLT() : m_matrix(), m_transpositions(), m_isInitialized(false) {}
|
||||
LDLT()
|
||||
: m_matrix(),
|
||||
m_transpositions(),
|
||||
m_sign(internal::ZeroSign),
|
||||
m_isInitialized(false)
|
||||
{}
|
||||
|
||||
/** \brief Default Constructor with memory preallocation
|
||||
*
|
||||
@@ -77,10 +86,11 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
||||
* according to the specified problem \a size.
|
||||
* \sa LDLT()
|
||||
*/
|
||||
LDLT(Index size)
|
||||
explicit LDLT(Index size)
|
||||
: m_matrix(size, size),
|
||||
m_transpositions(size),
|
||||
m_temporary(size),
|
||||
m_sign(internal::ZeroSign),
|
||||
m_isInitialized(false)
|
||||
{}
|
||||
|
||||
@@ -89,10 +99,11 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
||||
* This calculates the decomposition for the input \a matrix.
|
||||
* \sa LDLT(Index size)
|
||||
*/
|
||||
LDLT(const MatrixType& matrix)
|
||||
explicit LDLT(const MatrixType& matrix)
|
||||
: m_matrix(matrix.rows(), matrix.cols()),
|
||||
m_transpositions(matrix.rows()),
|
||||
m_temporary(matrix.rows()),
|
||||
m_sign(internal::ZeroSign),
|
||||
m_isInitialized(false)
|
||||
{
|
||||
compute(matrix);
|
||||
@@ -139,21 +150,14 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
||||
inline bool isPositive() const
|
||||
{
|
||||
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
||||
return m_sign == 1;
|
||||
return m_sign == internal::PositiveSemiDef || m_sign == internal::ZeroSign;
|
||||
}
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
inline bool isPositiveDefinite() const
|
||||
{
|
||||
return isPositive();
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \returns true if the matrix is negative (semidefinite) */
|
||||
inline bool isNegative(void) const
|
||||
{
|
||||
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
||||
return m_sign == -1;
|
||||
return m_sign == internal::NegativeSemiDef || m_sign == internal::ZeroSign;
|
||||
}
|
||||
|
||||
/** \returns a solution x of \f$ A x = b \f$ using the current decomposition of A.
|
||||
@@ -169,27 +173,18 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
||||
* least-square solution of \f$ D y_3 = y_2 \f$ is computed. This does not mean that this function
|
||||
* computes the least-square solution of \f$ A x = b \f$ is \f$ A \f$ is singular.
|
||||
*
|
||||
* \sa MatrixBase::ldlt()
|
||||
* \sa MatrixBase::ldlt(), SelfAdjointView::ldlt()
|
||||
*/
|
||||
template<typename Rhs>
|
||||
inline const internal::solve_retval<LDLT, Rhs>
|
||||
inline const Solve<LDLT, Rhs>
|
||||
solve(const MatrixBase<Rhs>& b) const
|
||||
{
|
||||
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
||||
eigen_assert(m_matrix.rows()==b.rows()
|
||||
&& "LDLT::solve(): invalid number of rows of the right hand side matrix b");
|
||||
return internal::solve_retval<LDLT, Rhs>(*this, b.derived());
|
||||
return Solve<LDLT, Rhs>(*this, b.derived());
|
||||
}
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
template<typename OtherDerived, typename ResultType>
|
||||
bool solve(const MatrixBase<OtherDerived>& b, ResultType *result) const
|
||||
{
|
||||
*result = this->solve(b);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename Derived>
|
||||
bool solveInPlace(MatrixBase<Derived> &bAndX) const;
|
||||
|
||||
@@ -223,8 +218,19 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
||||
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
||||
return Success;
|
||||
}
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
template<typename RhsType, typename DstType>
|
||||
EIGEN_DEVICE_FUNC
|
||||
void _solve_impl(const RhsType &rhs, DstType &dst) const;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
static void check_template_parameters()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* Used to compute and store the Cholesky decomposition A = L D L^* = U^* D U.
|
||||
@@ -235,7 +241,7 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
||||
MatrixType m_matrix;
|
||||
TranspositionType m_transpositions;
|
||||
TmpMatrixType m_temporary;
|
||||
int m_sign;
|
||||
internal::SignMatrix m_sign;
|
||||
bool m_isInitialized;
|
||||
};
|
||||
|
||||
@@ -246,49 +252,32 @@ template<int UpLo> struct ldlt_inplace;
|
||||
template<> struct ldlt_inplace<Lower>
|
||||
{
|
||||
template<typename MatrixType, typename TranspositionType, typename Workspace>
|
||||
static bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, int* sign=0)
|
||||
static bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, SignMatrix& sign)
|
||||
{
|
||||
using std::abs;
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::RealScalar RealScalar;
|
||||
typedef typename MatrixType::Index Index;
|
||||
typedef typename TranspositionType::StorageIndex IndexType;
|
||||
eigen_assert(mat.rows()==mat.cols());
|
||||
const Index size = mat.rows();
|
||||
|
||||
if (size <= 1)
|
||||
{
|
||||
transpositions.setIdentity();
|
||||
if(sign)
|
||||
*sign = numext::real(mat.coeff(0,0))>0 ? 1:-1;
|
||||
if (numext::real(mat.coeff(0,0)) > 0) sign = PositiveSemiDef;
|
||||
else if (numext::real(mat.coeff(0,0)) < 0) sign = NegativeSemiDef;
|
||||
else sign = ZeroSign;
|
||||
return true;
|
||||
}
|
||||
|
||||
RealScalar cutoff(0), biggest_in_corner;
|
||||
|
||||
for (Index k = 0; k < size; ++k)
|
||||
{
|
||||
// Find largest diagonal element
|
||||
Index index_of_biggest_in_corner;
|
||||
biggest_in_corner = mat.diagonal().tail(size-k).cwiseAbs().maxCoeff(&index_of_biggest_in_corner);
|
||||
mat.diagonal().tail(size-k).cwiseAbs().maxCoeff(&index_of_biggest_in_corner);
|
||||
index_of_biggest_in_corner += k;
|
||||
|
||||
if(k == 0)
|
||||
{
|
||||
// The biggest overall is the point of reference to which further diagonals
|
||||
// are compared; if any diagonal is negligible compared
|
||||
// to the largest overall, the algorithm bails.
|
||||
cutoff = abs(NumTraits<Scalar>::epsilon() * biggest_in_corner);
|
||||
}
|
||||
|
||||
// Finish early if the matrix is not full rank.
|
||||
if(biggest_in_corner < cutoff)
|
||||
{
|
||||
for(Index i = k; i < size; i++) transpositions.coeffRef(i) = i;
|
||||
if(sign) *sign = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
transpositions.coeffRef(k) = index_of_biggest_in_corner;
|
||||
transpositions.coeffRef(k) = IndexType(index_of_biggest_in_corner);
|
||||
if(k != index_of_biggest_in_corner)
|
||||
{
|
||||
// apply the transposition while taking care to consider only
|
||||
@@ -297,7 +286,7 @@ template<> struct ldlt_inplace<Lower>
|
||||
mat.row(k).head(k).swap(mat.row(index_of_biggest_in_corner).head(k));
|
||||
mat.col(k).tail(s).swap(mat.col(index_of_biggest_in_corner).tail(s));
|
||||
std::swap(mat.coeffRef(k,k),mat.coeffRef(index_of_biggest_in_corner,index_of_biggest_in_corner));
|
||||
for(int i=k+1;i<index_of_biggest_in_corner;++i)
|
||||
for(Index i=k+1;i<index_of_biggest_in_corner;++i)
|
||||
{
|
||||
Scalar tmp = mat.coeffRef(i,k);
|
||||
mat.coeffRef(i,k) = numext::conj(mat.coeffRef(index_of_biggest_in_corner,i));
|
||||
@@ -318,22 +307,27 @@ template<> struct ldlt_inplace<Lower>
|
||||
|
||||
if(k>0)
|
||||
{
|
||||
temp.head(k) = mat.diagonal().head(k).asDiagonal() * A10.adjoint();
|
||||
temp.head(k) = mat.diagonal().real().head(k).asDiagonal() * A10.adjoint();
|
||||
mat.coeffRef(k,k) -= (A10 * temp.head(k)).value();
|
||||
if(rs>0)
|
||||
A21.noalias() -= A20 * temp.head(k);
|
||||
}
|
||||
if((rs>0) && (abs(mat.coeffRef(k,k)) > cutoff))
|
||||
A21 /= mat.coeffRef(k,k);
|
||||
|
||||
if(sign)
|
||||
{
|
||||
// LDLT is not guaranteed to work for indefinite matrices, but let's try to get the sign right
|
||||
int newSign = numext::real(mat.diagonal().coeff(index_of_biggest_in_corner)) > 0;
|
||||
if(k == 0)
|
||||
*sign = newSign;
|
||||
else if(*sign != newSign)
|
||||
*sign = 0;
|
||||
// In some previous versions of Eigen (e.g., 3.2.1), the scaling was omitted if the pivot
|
||||
// was smaller than the cutoff value. However, since LDLT is not rank-revealing
|
||||
// we should only make sure that we do not introduce INF or NaN values.
|
||||
// Remark that LAPACK also uses 0 as the cutoff value.
|
||||
RealScalar realAkk = numext::real(mat.coeffRef(k,k));
|
||||
if((rs>0) && (abs(realAkk) > RealScalar(0)))
|
||||
A21 /= realAkk;
|
||||
|
||||
if (sign == PositiveSemiDef) {
|
||||
if (realAkk < 0) sign = Indefinite;
|
||||
} else if (sign == NegativeSemiDef) {
|
||||
if (realAkk > 0) sign = Indefinite;
|
||||
} else if (sign == ZeroSign) {
|
||||
if (realAkk > 0) sign = PositiveSemiDef;
|
||||
else if (realAkk < 0) sign = NegativeSemiDef;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,7 +347,6 @@ template<> struct ldlt_inplace<Lower>
|
||||
using numext::isfinite;
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::RealScalar RealScalar;
|
||||
typedef typename MatrixType::Index Index;
|
||||
|
||||
const Index size = mat.rows();
|
||||
eigen_assert(mat.cols() == size && w.size()==size);
|
||||
@@ -399,7 +392,7 @@ template<> struct ldlt_inplace<Lower>
|
||||
template<> struct ldlt_inplace<Upper>
|
||||
{
|
||||
template<typename MatrixType, typename TranspositionType, typename Workspace>
|
||||
static EIGEN_STRONG_INLINE bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, int* sign=0)
|
||||
static EIGEN_STRONG_INLINE bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, SignMatrix& sign)
|
||||
{
|
||||
Transpose<MatrixType> matt(mat);
|
||||
return ldlt_inplace<Lower>::unblocked(matt, transpositions, temp, sign);
|
||||
@@ -417,16 +410,16 @@ template<typename MatrixType> struct LDLT_Traits<MatrixType,Lower>
|
||||
{
|
||||
typedef const TriangularView<const MatrixType, UnitLower> MatrixL;
|
||||
typedef const TriangularView<const typename MatrixType::AdjointReturnType, UnitUpper> MatrixU;
|
||||
static inline MatrixL getL(const MatrixType& m) { return m; }
|
||||
static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); }
|
||||
static inline MatrixL getL(const MatrixType& m) { return MatrixL(m); }
|
||||
static inline MatrixU getU(const MatrixType& m) { return MatrixU(m.adjoint()); }
|
||||
};
|
||||
|
||||
template<typename MatrixType> struct LDLT_Traits<MatrixType,Upper>
|
||||
{
|
||||
typedef const TriangularView<const typename MatrixType::AdjointReturnType, UnitLower> MatrixL;
|
||||
typedef const TriangularView<const MatrixType, UnitUpper> MatrixU;
|
||||
static inline MatrixL getL(const MatrixType& m) { return m.adjoint(); }
|
||||
static inline MatrixU getU(const MatrixType& m) { return m; }
|
||||
static inline MatrixL getL(const MatrixType& m) { return MatrixL(m.adjoint()); }
|
||||
static inline MatrixU getU(const MatrixType& m) { return MatrixU(m); }
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
@@ -436,6 +429,8 @@ template<typename MatrixType> struct LDLT_Traits<MatrixType,Upper>
|
||||
template<typename MatrixType, int _UpLo>
|
||||
LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::compute(const MatrixType& a)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
eigen_assert(a.rows()==a.cols());
|
||||
const Index size = a.rows();
|
||||
|
||||
@@ -444,8 +439,9 @@ LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::compute(const MatrixType& a)
|
||||
m_transpositions.resize(size);
|
||||
m_isInitialized = false;
|
||||
m_temporary.resize(size);
|
||||
m_sign = internal::ZeroSign;
|
||||
|
||||
internal::ldlt_inplace<UpLo>::unblocked(m_matrix, m_transpositions, m_temporary, &m_sign);
|
||||
internal::ldlt_inplace<UpLo>::unblocked(m_matrix, m_transpositions, m_temporary, m_sign);
|
||||
|
||||
m_isInitialized = true;
|
||||
return *this;
|
||||
@@ -458,8 +454,9 @@ LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::compute(const MatrixType& a)
|
||||
*/
|
||||
template<typename MatrixType, int _UpLo>
|
||||
template<typename Derived>
|
||||
LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::rankUpdate(const MatrixBase<Derived>& w, const typename NumTraits<typename MatrixType::Scalar>::Real& sigma)
|
||||
LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::rankUpdate(const MatrixBase<Derived>& w, const typename LDLT<MatrixType,_UpLo>::RealScalar& sigma)
|
||||
{
|
||||
typedef typename TranspositionType::StorageIndex IndexType;
|
||||
const Index size = w.rows();
|
||||
if (m_isInitialized)
|
||||
{
|
||||
@@ -471,9 +468,9 @@ LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::rankUpdate(const MatrixBase<Deri
|
||||
m_matrix.setZero();
|
||||
m_transpositions.resize(size);
|
||||
for (Index i = 0; i < size; i++)
|
||||
m_transpositions.coeffRef(i) = i;
|
||||
m_transpositions.coeffRef(i) = IndexType(i);
|
||||
m_temporary.resize(size);
|
||||
m_sign = sigma>=0 ? 1 : -1;
|
||||
m_sign = sigma>=0 ? internal::PositiveSemiDef : internal::NegativeSemiDef;
|
||||
m_isInitialized = true;
|
||||
}
|
||||
|
||||
@@ -482,48 +479,45 @@ LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::rankUpdate(const MatrixBase<Deri
|
||||
return *this;
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
template<typename _MatrixType, int _UpLo, typename Rhs>
|
||||
struct solve_retval<LDLT<_MatrixType,_UpLo>, Rhs>
|
||||
: solve_retval_base<LDLT<_MatrixType,_UpLo>, Rhs>
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
template<typename _MatrixType, int _UpLo>
|
||||
template<typename RhsType, typename DstType>
|
||||
void LDLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) const
|
||||
{
|
||||
typedef LDLT<_MatrixType,_UpLo> LDLTType;
|
||||
EIGEN_MAKE_SOLVE_HELPERS(LDLTType,Rhs)
|
||||
eigen_assert(rhs.rows() == rows());
|
||||
// dst = P b
|
||||
dst = m_transpositions * rhs;
|
||||
|
||||
template<typename Dest> void evalTo(Dest& dst) const
|
||||
// dst = L^-1 (P b)
|
||||
matrixL().solveInPlace(dst);
|
||||
|
||||
// dst = D^-1 (L^-1 P b)
|
||||
// more precisely, use pseudo-inverse of D (see bug 241)
|
||||
using std::abs;
|
||||
const typename Diagonal<const MatrixType>::RealReturnType vecD(vectorD());
|
||||
// In some previous versions, tolerance was set to the max of 1/highest and the maximal diagonal entry * epsilon
|
||||
// as motivated by LAPACK's xGELSS:
|
||||
// RealScalar tolerance = numext::maxi(vecD.array().abs().maxCoeff() * NumTraits<RealScalar>::epsilon(),RealScalar(1) / NumTraits<RealScalar>::highest());
|
||||
// However, LDLT is not rank revealing, and so adjusting the tolerance wrt to the highest
|
||||
// diagonal element is not well justified and leads to numerical issues in some cases.
|
||||
// Moreover, Lapack's xSYTRS routines use 0 for the tolerance.
|
||||
RealScalar tolerance = RealScalar(1) / NumTraits<RealScalar>::highest();
|
||||
|
||||
for (Index i = 0; i < vecD.size(); ++i)
|
||||
{
|
||||
eigen_assert(rhs().rows() == dec().matrixLDLT().rows());
|
||||
// dst = P b
|
||||
dst = dec().transpositionsP() * rhs();
|
||||
|
||||
// dst = L^-1 (P b)
|
||||
dec().matrixL().solveInPlace(dst);
|
||||
|
||||
// dst = D^-1 (L^-1 P b)
|
||||
// more precisely, use pseudo-inverse of D (see bug 241)
|
||||
using std::abs;
|
||||
using std::max;
|
||||
typedef typename LDLTType::MatrixType MatrixType;
|
||||
typedef typename LDLTType::Scalar Scalar;
|
||||
typedef typename LDLTType::RealScalar RealScalar;
|
||||
const Diagonal<const MatrixType> vectorD = dec().vectorD();
|
||||
RealScalar tolerance = (max)(vectorD.array().abs().maxCoeff() * NumTraits<Scalar>::epsilon(),
|
||||
RealScalar(1) / NumTraits<RealScalar>::highest()); // motivated by LAPACK's xGELSS
|
||||
for (Index i = 0; i < vectorD.size(); ++i) {
|
||||
if(abs(vectorD(i)) > tolerance)
|
||||
dst.row(i) /= vectorD(i);
|
||||
else
|
||||
dst.row(i).setZero();
|
||||
}
|
||||
|
||||
// dst = L^-T (D^-1 L^-1 P b)
|
||||
dec().matrixU().solveInPlace(dst);
|
||||
|
||||
// dst = P^-1 (L^-T D^-1 L^-1 P b) = A^-1 b
|
||||
dst = dec().transpositionsP().transpose() * dst;
|
||||
if(abs(vecD(i)) > tolerance)
|
||||
dst.row(i) /= vecD(i);
|
||||
else
|
||||
dst.row(i).setZero();
|
||||
}
|
||||
};
|
||||
|
||||
// dst = L^-T (D^-1 L^-1 P b)
|
||||
matrixU().solveInPlace(dst);
|
||||
|
||||
// dst = P^-1 (L^-T D^-1 L^-1 P b) = A^-1 b
|
||||
dst = m_transpositions.transpose() * dst;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \internal use x = ldlt_object.solve(x);
|
||||
*
|
||||
@@ -566,7 +560,7 @@ MatrixType LDLT<MatrixType,_UpLo>::reconstructedMatrix() const
|
||||
// L^* P
|
||||
res = matrixU() * res;
|
||||
// D(L^*P)
|
||||
res = vectorD().asDiagonal() * res;
|
||||
res = vectorD().real().asDiagonal() * res;
|
||||
// L(DL^*P)
|
||||
res = matrixL() * res;
|
||||
// P^T (LDL^*P)
|
||||
@@ -575,8 +569,10 @@ MatrixType LDLT<MatrixType,_UpLo>::reconstructedMatrix() const
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifndef __CUDACC__
|
||||
/** \cholesky_module
|
||||
* \returns the Cholesky decomposition with full pivoting without square root of \c *this
|
||||
* \sa MatrixBase::ldlt()
|
||||
*/
|
||||
template<typename MatrixType, unsigned int UpLo>
|
||||
inline const LDLT<typename SelfAdjointView<MatrixType, UpLo>::PlainObject, UpLo>
|
||||
@@ -587,6 +583,7 @@ SelfAdjointView<MatrixType, UpLo>::ldlt() const
|
||||
|
||||
/** \cholesky_module
|
||||
* \returns the Cholesky decomposition with full pivoting without square root of \c *this
|
||||
* \sa SelfAdjointView::ldlt()
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline const LDLT<typename MatrixBase<Derived>::PlainObject>
|
||||
@@ -594,6 +591,7 @@ MatrixBase<Derived>::ldlt() const
|
||||
{
|
||||
return LDLT<PlainObject>(derived());
|
||||
}
|
||||
#endif // __CUDACC__
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ template<typename MatrixType, int UpLo> struct LLT_Traits;
|
||||
* Example: \include LLT_example.cpp
|
||||
* Output: \verbinclude LLT_example.out
|
||||
*
|
||||
* \sa MatrixBase::llt(), class LDLT
|
||||
* \sa MatrixBase::llt(), SelfAdjointView::llt(), class LDLT
|
||||
*/
|
||||
/* HEY THIS DOX IS DISABLED BECAUSE THERE's A BUG EITHER HERE OR IN LDLT ABOUT THAT (OR BOTH)
|
||||
* Note that during the decomposition, only the upper triangular part of A is considered. Therefore,
|
||||
@@ -59,7 +59,8 @@ template<typename _MatrixType, int _UpLo> class LLT
|
||||
};
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
|
||||
typedef typename MatrixType::Index Index;
|
||||
typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
|
||||
typedef typename MatrixType::StorageIndex StorageIndex;
|
||||
|
||||
enum {
|
||||
PacketSize = internal::packet_traits<Scalar>::size,
|
||||
@@ -83,10 +84,10 @@ template<typename _MatrixType, int _UpLo> class LLT
|
||||
* according to the specified problem \a size.
|
||||
* \sa LLT()
|
||||
*/
|
||||
LLT(Index size) : m_matrix(size, size),
|
||||
explicit LLT(Index size) : m_matrix(size, size),
|
||||
m_isInitialized(false) {}
|
||||
|
||||
LLT(const MatrixType& matrix)
|
||||
explicit LLT(const MatrixType& matrix)
|
||||
: m_matrix(matrix.rows(), matrix.cols()),
|
||||
m_isInitialized(false)
|
||||
{
|
||||
@@ -115,29 +116,18 @@ template<typename _MatrixType, int _UpLo> class LLT
|
||||
* Example: \include LLT_solve.cpp
|
||||
* Output: \verbinclude LLT_solve.out
|
||||
*
|
||||
* \sa solveInPlace(), MatrixBase::llt()
|
||||
* \sa solveInPlace(), MatrixBase::llt(), SelfAdjointView::llt()
|
||||
*/
|
||||
template<typename Rhs>
|
||||
inline const internal::solve_retval<LLT, Rhs>
|
||||
inline const Solve<LLT, Rhs>
|
||||
solve(const MatrixBase<Rhs>& b) const
|
||||
{
|
||||
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
||||
eigen_assert(m_matrix.rows()==b.rows()
|
||||
&& "LLT::solve(): invalid number of rows of the right hand side matrix b");
|
||||
return internal::solve_retval<LLT, Rhs>(*this, b.derived());
|
||||
return Solve<LLT, Rhs>(*this, b.derived());
|
||||
}
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
template<typename OtherDerived, typename ResultType>
|
||||
bool solve(const MatrixBase<OtherDerived>& b, ResultType *result) const
|
||||
{
|
||||
*result = this->solve(b);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isPositiveDefinite() const { return true; }
|
||||
#endif
|
||||
|
||||
template<typename Derived>
|
||||
void solveInPlace(MatrixBase<Derived> &bAndX) const;
|
||||
|
||||
@@ -172,8 +162,20 @@ template<typename _MatrixType, int _UpLo> class LLT
|
||||
|
||||
template<typename VectorType>
|
||||
LLT rankUpdate(const VectorType& vec, const RealScalar& sigma = 1);
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
template<typename RhsType, typename DstType>
|
||||
EIGEN_DEVICE_FUNC
|
||||
void _solve_impl(const RhsType &rhs, DstType &dst) const;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
static void check_template_parameters()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* Used to compute and store L
|
||||
* The strict upper part is not used and even not initialized.
|
||||
@@ -188,12 +190,11 @@ namespace internal {
|
||||
template<typename Scalar, int UpLo> struct llt_inplace;
|
||||
|
||||
template<typename MatrixType, typename VectorType>
|
||||
static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma)
|
||||
static Index llt_rank_update_lower(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma)
|
||||
{
|
||||
using std::sqrt;
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::RealScalar RealScalar;
|
||||
typedef typename MatrixType::Index Index;
|
||||
typedef typename MatrixType::ColXpr ColXpr;
|
||||
typedef typename internal::remove_all<ColXpr>::type ColXprCleaned;
|
||||
typedef typename ColXprCleaned::SegmentReturnType ColXprSegment;
|
||||
@@ -262,10 +263,9 @@ template<typename Scalar> struct llt_inplace<Scalar, Lower>
|
||||
{
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
template<typename MatrixType>
|
||||
static typename MatrixType::Index unblocked(MatrixType& mat)
|
||||
static Index unblocked(MatrixType& mat)
|
||||
{
|
||||
using std::sqrt;
|
||||
typedef typename MatrixType::Index Index;
|
||||
|
||||
eigen_assert(mat.rows()==mat.cols());
|
||||
const Index size = mat.rows();
|
||||
@@ -289,9 +289,8 @@ template<typename Scalar> struct llt_inplace<Scalar, Lower>
|
||||
}
|
||||
|
||||
template<typename MatrixType>
|
||||
static typename MatrixType::Index blocked(MatrixType& m)
|
||||
static Index blocked(MatrixType& m)
|
||||
{
|
||||
typedef typename MatrixType::Index Index;
|
||||
eigen_assert(m.rows()==m.cols());
|
||||
Index size = m.rows();
|
||||
if(size<32)
|
||||
@@ -322,7 +321,7 @@ template<typename Scalar> struct llt_inplace<Scalar, Lower>
|
||||
}
|
||||
|
||||
template<typename MatrixType, typename VectorType>
|
||||
static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const RealScalar& sigma)
|
||||
static Index rankUpdate(MatrixType& mat, const VectorType& vec, const RealScalar& sigma)
|
||||
{
|
||||
return Eigen::internal::llt_rank_update_lower(mat, vec, sigma);
|
||||
}
|
||||
@@ -333,19 +332,19 @@ template<typename Scalar> struct llt_inplace<Scalar, Upper>
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
|
||||
template<typename MatrixType>
|
||||
static EIGEN_STRONG_INLINE typename MatrixType::Index unblocked(MatrixType& mat)
|
||||
static EIGEN_STRONG_INLINE Index unblocked(MatrixType& mat)
|
||||
{
|
||||
Transpose<MatrixType> matt(mat);
|
||||
return llt_inplace<Scalar, Lower>::unblocked(matt);
|
||||
}
|
||||
template<typename MatrixType>
|
||||
static EIGEN_STRONG_INLINE typename MatrixType::Index blocked(MatrixType& mat)
|
||||
static EIGEN_STRONG_INLINE Index blocked(MatrixType& mat)
|
||||
{
|
||||
Transpose<MatrixType> matt(mat);
|
||||
return llt_inplace<Scalar, Lower>::blocked(matt);
|
||||
}
|
||||
template<typename MatrixType, typename VectorType>
|
||||
static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const RealScalar& sigma)
|
||||
static Index rankUpdate(MatrixType& mat, const VectorType& vec, const RealScalar& sigma)
|
||||
{
|
||||
Transpose<MatrixType> matt(mat);
|
||||
return llt_inplace<Scalar, Lower>::rankUpdate(matt, vec.conjugate(), sigma);
|
||||
@@ -356,8 +355,8 @@ template<typename MatrixType> struct LLT_Traits<MatrixType,Lower>
|
||||
{
|
||||
typedef const TriangularView<const MatrixType, Lower> MatrixL;
|
||||
typedef const TriangularView<const typename MatrixType::AdjointReturnType, Upper> MatrixU;
|
||||
static inline MatrixL getL(const MatrixType& m) { return m; }
|
||||
static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); }
|
||||
static inline MatrixL getL(const MatrixType& m) { return MatrixL(m); }
|
||||
static inline MatrixU getU(const MatrixType& m) { return MatrixU(m.adjoint()); }
|
||||
static bool inplace_decomposition(MatrixType& m)
|
||||
{ return llt_inplace<typename MatrixType::Scalar, Lower>::blocked(m)==-1; }
|
||||
};
|
||||
@@ -366,8 +365,8 @@ template<typename MatrixType> struct LLT_Traits<MatrixType,Upper>
|
||||
{
|
||||
typedef const TriangularView<const typename MatrixType::AdjointReturnType, Lower> MatrixL;
|
||||
typedef const TriangularView<const MatrixType, Upper> MatrixU;
|
||||
static inline MatrixL getL(const MatrixType& m) { return m.adjoint(); }
|
||||
static inline MatrixU getU(const MatrixType& m) { return m; }
|
||||
static inline MatrixL getL(const MatrixType& m) { return MatrixL(m.adjoint()); }
|
||||
static inline MatrixU getU(const MatrixType& m) { return MatrixU(m); }
|
||||
static bool inplace_decomposition(MatrixType& m)
|
||||
{ return llt_inplace<typename MatrixType::Scalar, Upper>::blocked(m)==-1; }
|
||||
};
|
||||
@@ -384,6 +383,8 @@ template<typename MatrixType> struct LLT_Traits<MatrixType,Upper>
|
||||
template<typename MatrixType, int _UpLo>
|
||||
LLT<MatrixType,_UpLo>& LLT<MatrixType,_UpLo>::compute(const MatrixType& a)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
eigen_assert(a.rows()==a.cols());
|
||||
const Index size = a.rows();
|
||||
m_matrix.resize(size, size);
|
||||
@@ -415,22 +416,16 @@ LLT<_MatrixType,_UpLo> LLT<_MatrixType,_UpLo>::rankUpdate(const VectorType& v, c
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
template<typename _MatrixType, int UpLo, typename Rhs>
|
||||
struct solve_retval<LLT<_MatrixType, UpLo>, Rhs>
|
||||
: solve_retval_base<LLT<_MatrixType, UpLo>, Rhs>
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
template<typename _MatrixType,int _UpLo>
|
||||
template<typename RhsType, typename DstType>
|
||||
void LLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) const
|
||||
{
|
||||
typedef LLT<_MatrixType,UpLo> LLTType;
|
||||
EIGEN_MAKE_SOLVE_HELPERS(LLTType,Rhs)
|
||||
|
||||
template<typename Dest> void evalTo(Dest& dst) const
|
||||
{
|
||||
dst = rhs();
|
||||
dec().solveInPlace(dst);
|
||||
}
|
||||
};
|
||||
dst = rhs;
|
||||
solveInPlace(dst);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \internal use x = llt_object.solve(x);
|
||||
*
|
||||
@@ -465,8 +460,10 @@ MatrixType LLT<MatrixType,_UpLo>::reconstructedMatrix() const
|
||||
return matrixL() * matrixL().adjoint().toDenseMatrix();
|
||||
}
|
||||
|
||||
#ifndef __CUDACC__
|
||||
/** \cholesky_module
|
||||
* \returns the LLT decomposition of \c *this
|
||||
* \sa SelfAdjointView::llt()
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline const LLT<typename MatrixBase<Derived>::PlainObject>
|
||||
@@ -477,6 +474,7 @@ MatrixBase<Derived>::llt() const
|
||||
|
||||
/** \cholesky_module
|
||||
* \returns the LLT decomposition of \c *this
|
||||
* \sa SelfAdjointView::llt()
|
||||
*/
|
||||
template<typename MatrixType, unsigned int UpLo>
|
||||
inline const LLT<typename SelfAdjointView<MatrixType, UpLo>::PlainObject, UpLo>
|
||||
@@ -484,7 +482,8 @@ SelfAdjointView<MatrixType, UpLo>::llt() const
|
||||
{
|
||||
return LLT<PlainObject,UpLo>(m_matrix);
|
||||
}
|
||||
|
||||
#endif // __CUDACC__
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_LLT_H
|
||||
|
||||
@@ -46,7 +46,7 @@ template<typename Scalar> struct mkl_llt;
|
||||
template<> struct mkl_llt<EIGTYPE> \
|
||||
{ \
|
||||
template<typename MatrixType> \
|
||||
static inline typename MatrixType::Index potrf(MatrixType& m, char uplo) \
|
||||
static inline Index potrf(MatrixType& m, char uplo) \
|
||||
{ \
|
||||
lapack_int matrix_order; \
|
||||
lapack_int size, lda, info, StorageOrder; \
|
||||
@@ -60,30 +60,30 @@ template<> struct mkl_llt<EIGTYPE> \
|
||||
lda = m.outerStride(); \
|
||||
\
|
||||
info = LAPACKE_##MKLPREFIX##potrf( matrix_order, uplo, size, (MKLTYPE*)a, lda ); \
|
||||
info = (info==0) ? Success : NumericalIssue; \
|
||||
info = (info==0) ? -1 : info>0 ? info-1 : size; \
|
||||
return info; \
|
||||
} \
|
||||
}; \
|
||||
template<> struct llt_inplace<EIGTYPE, Lower> \
|
||||
{ \
|
||||
template<typename MatrixType> \
|
||||
static typename MatrixType::Index blocked(MatrixType& m) \
|
||||
static Index blocked(MatrixType& m) \
|
||||
{ \
|
||||
return mkl_llt<EIGTYPE>::potrf(m, 'L'); \
|
||||
} \
|
||||
template<typename MatrixType, typename VectorType> \
|
||||
static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) \
|
||||
static Index rankUpdate(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) \
|
||||
{ return Eigen::internal::llt_rank_update_lower(mat, vec, sigma); } \
|
||||
}; \
|
||||
template<> struct llt_inplace<EIGTYPE, Upper> \
|
||||
{ \
|
||||
template<typename MatrixType> \
|
||||
static typename MatrixType::Index blocked(MatrixType& m) \
|
||||
static Index blocked(MatrixType& m) \
|
||||
{ \
|
||||
return mkl_llt<EIGTYPE>::potrf(m, 'U'); \
|
||||
} \
|
||||
template<typename MatrixType, typename VectorType> \
|
||||
static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) \
|
||||
static Index rankUpdate(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) \
|
||||
{ \
|
||||
Transpose<MatrixType> matt(mat); \
|
||||
return llt_inplace<EIGTYPE, Lower>::rankUpdate(matt, vec.conjugate(), sigma); \
|
||||
|
||||
@@ -48,8 +48,8 @@ void cholmod_configure_matrix(CholmodType& mat)
|
||||
/** Wraps the Eigen sparse matrix \a mat into a Cholmod sparse matrix object.
|
||||
* Note that the data are shared.
|
||||
*/
|
||||
template<typename _Scalar, int _Options, typename _Index>
|
||||
cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_Index>& mat)
|
||||
template<typename _Scalar, int _Options, typename _StorageIndex>
|
||||
cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_StorageIndex>& mat)
|
||||
{
|
||||
cholmod_sparse res;
|
||||
res.nzmax = mat.nonZeros();
|
||||
@@ -58,10 +58,12 @@ cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_Index>& mat)
|
||||
res.p = mat.outerIndexPtr();
|
||||
res.i = mat.innerIndexPtr();
|
||||
res.x = mat.valuePtr();
|
||||
res.z = 0;
|
||||
res.sorted = 1;
|
||||
if(mat.isCompressed())
|
||||
{
|
||||
res.packed = 1;
|
||||
res.nz = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -72,11 +74,11 @@ cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_Index>& mat)
|
||||
res.dtype = 0;
|
||||
res.stype = -1;
|
||||
|
||||
if (internal::is_same<_Index,int>::value)
|
||||
if (internal::is_same<_StorageIndex,int>::value)
|
||||
{
|
||||
res.itype = CHOLMOD_INT;
|
||||
}
|
||||
else if (internal::is_same<_Index,UF_long>::value)
|
||||
else if (internal::is_same<_StorageIndex,UF_long>::value)
|
||||
{
|
||||
res.itype = CHOLMOD_LONG;
|
||||
}
|
||||
@@ -103,7 +105,7 @@ const cholmod_sparse viewAsCholmod(const SparseMatrix<_Scalar,_Options,_Index>&
|
||||
/** Returns a view of the Eigen sparse matrix \a mat as Cholmod sparse matrix.
|
||||
* The data are not copied but shared. */
|
||||
template<typename _Scalar, int _Options, typename _Index, unsigned int UpLo>
|
||||
cholmod_sparse viewAsCholmod(const SparseSelfAdjointView<SparseMatrix<_Scalar,_Options,_Index>, UpLo>& mat)
|
||||
cholmod_sparse viewAsCholmod(const SparseSelfAdjointView<const SparseMatrix<_Scalar,_Options,_Index>, UpLo>& mat)
|
||||
{
|
||||
cholmod_sparse res = viewAsCholmod(mat.matrix().const_cast_derived());
|
||||
|
||||
@@ -136,12 +138,12 @@ cholmod_dense viewAsCholmod(MatrixBase<Derived>& mat)
|
||||
|
||||
/** Returns a view of the Cholmod sparse matrix \a cm as an Eigen sparse matrix.
|
||||
* The data are not copied but shared. */
|
||||
template<typename Scalar, int Flags, typename Index>
|
||||
MappedSparseMatrix<Scalar,Flags,Index> viewAsEigen(cholmod_sparse& cm)
|
||||
template<typename Scalar, int Flags, typename StorageIndex>
|
||||
MappedSparseMatrix<Scalar,Flags,StorageIndex> viewAsEigen(cholmod_sparse& cm)
|
||||
{
|
||||
return MappedSparseMatrix<Scalar,Flags,Index>
|
||||
(cm.nrow, cm.ncol, static_cast<Index*>(cm.p)[cm.ncol],
|
||||
static_cast<Index*>(cm.p), static_cast<Index*>(cm.i),static_cast<Scalar*>(cm.x) );
|
||||
return MappedSparseMatrix<Scalar,Flags,StorageIndex>
|
||||
(cm.nrow, cm.ncol, static_cast<StorageIndex*>(cm.p)[cm.ncol],
|
||||
static_cast<StorageIndex*>(cm.p), static_cast<StorageIndex*>(cm.i),static_cast<Scalar*>(cm.x) );
|
||||
}
|
||||
|
||||
enum CholmodMode {
|
||||
@@ -155,26 +157,31 @@ enum CholmodMode {
|
||||
* \sa class CholmodSupernodalLLT, class CholmodSimplicialLDLT, class CholmodSimplicialLLT
|
||||
*/
|
||||
template<typename _MatrixType, int _UpLo, typename Derived>
|
||||
class CholmodBase : internal::noncopyable
|
||||
class CholmodBase : public SparseSolverBase<Derived>
|
||||
{
|
||||
protected:
|
||||
typedef SparseSolverBase<Derived> Base;
|
||||
using Base::derived;
|
||||
using Base::m_isInitialized;
|
||||
public:
|
||||
typedef _MatrixType MatrixType;
|
||||
enum { UpLo = _UpLo };
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::RealScalar RealScalar;
|
||||
typedef MatrixType CholMatrixType;
|
||||
typedef typename MatrixType::Index Index;
|
||||
typedef typename MatrixType::StorageIndex StorageIndex;
|
||||
|
||||
public:
|
||||
|
||||
CholmodBase()
|
||||
: m_cholmodFactor(0), m_info(Success), m_isInitialized(false)
|
||||
: m_cholmodFactor(0), m_info(Success)
|
||||
{
|
||||
m_shiftOffset[0] = m_shiftOffset[1] = RealScalar(0.0);
|
||||
cholmod_start(&m_cholmod);
|
||||
}
|
||||
|
||||
CholmodBase(const MatrixType& matrix)
|
||||
: m_cholmodFactor(0), m_info(Success), m_isInitialized(false)
|
||||
explicit CholmodBase(const MatrixType& matrix)
|
||||
: m_cholmodFactor(0), m_info(Success)
|
||||
{
|
||||
m_shiftOffset[0] = m_shiftOffset[1] = RealScalar(0.0);
|
||||
cholmod_start(&m_cholmod);
|
||||
@@ -188,11 +195,8 @@ class CholmodBase : internal::noncopyable
|
||||
cholmod_finish(&m_cholmod);
|
||||
}
|
||||
|
||||
inline Index cols() const { return m_cholmodFactor->n; }
|
||||
inline Index rows() const { return m_cholmodFactor->n; }
|
||||
|
||||
Derived& derived() { return *static_cast<Derived*>(this); }
|
||||
const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
||||
inline StorageIndex cols() const { return internal::convert_index<StorageIndex, Index>(m_cholmodFactor->n); }
|
||||
inline StorageIndex rows() const { return internal::convert_index<StorageIndex, Index>(m_cholmodFactor->n); }
|
||||
|
||||
/** \brief Reports whether previous computation was successful.
|
||||
*
|
||||
@@ -213,35 +217,7 @@ class CholmodBase : internal::noncopyable
|
||||
return derived();
|
||||
}
|
||||
|
||||
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
|
||||
*
|
||||
* \sa compute()
|
||||
*/
|
||||
template<typename Rhs>
|
||||
inline const internal::solve_retval<CholmodBase, Rhs>
|
||||
solve(const MatrixBase<Rhs>& b) const
|
||||
{
|
||||
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
||||
eigen_assert(rows()==b.rows()
|
||||
&& "CholmodDecomposition::solve(): invalid number of rows of the right hand side matrix b");
|
||||
return internal::solve_retval<CholmodBase, Rhs>(*this, b.derived());
|
||||
}
|
||||
|
||||
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
|
||||
*
|
||||
* \sa compute()
|
||||
*/
|
||||
template<typename Rhs>
|
||||
inline const internal::sparse_solve_retval<CholmodBase, Rhs>
|
||||
solve(const SparseMatrixBase<Rhs>& b) const
|
||||
{
|
||||
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
||||
eigen_assert(rows()==b.rows()
|
||||
&& "CholmodDecomposition::solve(): invalid number of rows of the right hand side matrix b");
|
||||
return internal::sparse_solve_retval<CholmodBase, Rhs>(*this, b.derived());
|
||||
}
|
||||
|
||||
/** Performs a symbolic decomposition on the sparcity of \a matrix.
|
||||
/** Performs a symbolic decomposition on the sparsity pattern of \a matrix.
|
||||
*
|
||||
* This function is particularly useful when solving for several problems having the same structure.
|
||||
*
|
||||
@@ -265,7 +241,7 @@ class CholmodBase : internal::noncopyable
|
||||
|
||||
/** Performs a numeric decomposition of \a matrix
|
||||
*
|
||||
* The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed.
|
||||
* The given matrix must have the same sparsity pattern as the matrix on which the symbolic decomposition has been performed.
|
||||
*
|
||||
* \sa analyzePattern()
|
||||
*/
|
||||
@@ -287,7 +263,7 @@ class CholmodBase : internal::noncopyable
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
/** \internal */
|
||||
template<typename Rhs,typename Dest>
|
||||
void _solve(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const
|
||||
void _solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const
|
||||
{
|
||||
eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
|
||||
const Index size = m_cholmodFactor->n;
|
||||
@@ -301,15 +277,16 @@ class CholmodBase : internal::noncopyable
|
||||
if(!x_cd)
|
||||
{
|
||||
this->m_info = NumericalIssue;
|
||||
return;
|
||||
}
|
||||
// TODO optimize this copy by swapping when possible (be carreful with alignment, etc.)
|
||||
// TODO optimize this copy by swapping when possible (be careful with alignment, etc.)
|
||||
dest = Matrix<Scalar,Dest::RowsAtCompileTime,Dest::ColsAtCompileTime>::Map(reinterpret_cast<Scalar*>(x_cd->x),b.rows(),b.cols());
|
||||
cholmod_free_dense(&x_cd, &m_cholmod);
|
||||
}
|
||||
|
||||
/** \internal */
|
||||
template<typename RhsScalar, int RhsOptions, typename RhsIndex, typename DestScalar, int DestOptions, typename DestIndex>
|
||||
void _solve(const SparseMatrix<RhsScalar,RhsOptions,RhsIndex> &b, SparseMatrix<DestScalar,DestOptions,DestIndex> &dest) const
|
||||
void _solve_impl(const SparseMatrix<RhsScalar,RhsOptions,RhsIndex> &b, SparseMatrix<DestScalar,DestOptions,DestIndex> &dest) const
|
||||
{
|
||||
eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
|
||||
const Index size = m_cholmodFactor->n;
|
||||
@@ -322,8 +299,9 @@ class CholmodBase : internal::noncopyable
|
||||
if(!x_cs)
|
||||
{
|
||||
this->m_info = NumericalIssue;
|
||||
return;
|
||||
}
|
||||
// TODO optimize this copy by swapping when possible (be carreful with alignment, etc.)
|
||||
// TODO optimize this copy by swapping when possible (be careful with alignment, etc.)
|
||||
dest = viewAsEigen<DestScalar,DestOptions,DestIndex>(*x_cs);
|
||||
cholmod_free_sparse(&x_cs, &m_cholmod);
|
||||
}
|
||||
@@ -354,7 +332,6 @@ class CholmodBase : internal::noncopyable
|
||||
cholmod_factor* m_cholmodFactor;
|
||||
RealScalar m_shiftOffset[2];
|
||||
mutable ComputationInfo m_info;
|
||||
bool m_isInitialized;
|
||||
int m_factorizationIsOk;
|
||||
int m_analysisIsOk;
|
||||
};
|
||||
@@ -365,8 +342,8 @@ class CholmodBase : internal::noncopyable
|
||||
*
|
||||
* This class allows to solve for A.X = B sparse linear problems via a simplicial LL^T Cholesky factorization
|
||||
* using the Cholmod library.
|
||||
* This simplicial variant is equivalent to Eigen's built-in SimplicialLLT class. Thefore, it has little practical interest.
|
||||
* The sparse matrix A must be selfajoint and positive definite. The vectors or matrices
|
||||
* This simplicial variant is equivalent to Eigen's built-in SimplicialLLT class. Therefore, it has little practical interest.
|
||||
* The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices
|
||||
* X and B can be either dense or sparse.
|
||||
*
|
||||
* \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<>
|
||||
@@ -392,7 +369,7 @@ class CholmodSimplicialLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimpl
|
||||
CholmodSimplicialLLT(const MatrixType& matrix) : Base()
|
||||
{
|
||||
init();
|
||||
compute(matrix);
|
||||
this->compute(matrix);
|
||||
}
|
||||
|
||||
~CholmodSimplicialLLT() {}
|
||||
@@ -412,8 +389,8 @@ class CholmodSimplicialLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimpl
|
||||
*
|
||||
* This class allows to solve for A.X = B sparse linear problems via a simplicial LDL^T Cholesky factorization
|
||||
* using the Cholmod library.
|
||||
* This simplicial variant is equivalent to Eigen's built-in SimplicialLDLT class. Thefore, it has little practical interest.
|
||||
* The sparse matrix A must be selfajoint and positive definite. The vectors or matrices
|
||||
* This simplicial variant is equivalent to Eigen's built-in SimplicialLDLT class. Therefore, it has little practical interest.
|
||||
* The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices
|
||||
* X and B can be either dense or sparse.
|
||||
*
|
||||
* \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<>
|
||||
@@ -439,7 +416,7 @@ class CholmodSimplicialLDLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimp
|
||||
CholmodSimplicialLDLT(const MatrixType& matrix) : Base()
|
||||
{
|
||||
init();
|
||||
compute(matrix);
|
||||
this->compute(matrix);
|
||||
}
|
||||
|
||||
~CholmodSimplicialLDLT() {}
|
||||
@@ -458,7 +435,7 @@ class CholmodSimplicialLDLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimp
|
||||
* This class allows to solve for A.X = B sparse linear problems via a supernodal LL^T Cholesky factorization
|
||||
* using the Cholmod library.
|
||||
* This supernodal variant performs best on dense enough problems, e.g., 3D FEM, or very high order 2D FEM.
|
||||
* The sparse matrix A must be selfajoint and positive definite. The vectors or matrices
|
||||
* The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices
|
||||
* X and B can be either dense or sparse.
|
||||
*
|
||||
* \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<>
|
||||
@@ -484,7 +461,7 @@ class CholmodSupernodalLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSuper
|
||||
CholmodSupernodalLLT(const MatrixType& matrix) : Base()
|
||||
{
|
||||
init();
|
||||
compute(matrix);
|
||||
this->compute(matrix);
|
||||
}
|
||||
|
||||
~CholmodSupernodalLLT() {}
|
||||
@@ -501,7 +478,7 @@ class CholmodSupernodalLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSuper
|
||||
* \brief A general Cholesky factorization and solver based on Cholmod
|
||||
*
|
||||
* This class allows to solve for A.X = B sparse linear problems via a LL^T or LDL^T Cholesky factorization
|
||||
* using the Cholmod library. The sparse matrix A must be selfajoint and positive definite. The vectors or matrices
|
||||
* using the Cholmod library. The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices
|
||||
* X and B can be either dense or sparse.
|
||||
*
|
||||
* This variant permits to change the underlying Cholesky method at runtime.
|
||||
@@ -531,7 +508,7 @@ class CholmodDecomposition : public CholmodBase<_MatrixType, _UpLo, CholmodDecom
|
||||
CholmodDecomposition(const MatrixType& matrix) : Base()
|
||||
{
|
||||
init();
|
||||
compute(matrix);
|
||||
this->compute(matrix);
|
||||
}
|
||||
|
||||
~CholmodDecomposition() {}
|
||||
@@ -569,36 +546,6 @@ class CholmodDecomposition : public CholmodBase<_MatrixType, _UpLo, CholmodDecom
|
||||
}
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename _MatrixType, int _UpLo, typename Derived, typename Rhs>
|
||||
struct solve_retval<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs>
|
||||
: solve_retval_base<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs>
|
||||
{
|
||||
typedef CholmodBase<_MatrixType,_UpLo,Derived> Dec;
|
||||
EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
|
||||
|
||||
template<typename Dest> void evalTo(Dest& dst) const
|
||||
{
|
||||
dec()._solve(rhs(),dst);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _MatrixType, int _UpLo, typename Derived, typename Rhs>
|
||||
struct sparse_solve_retval<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs>
|
||||
: sparse_solve_retval_base<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs>
|
||||
{
|
||||
typedef CholmodBase<_MatrixType,_UpLo,Derived> Dec;
|
||||
EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs)
|
||||
|
||||
template<typename Dest> void evalTo(Dest& dst) const
|
||||
{
|
||||
dec()._solve(rhs(),dst);
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_CHOLMODSUPPORT_H
|
||||
|
||||
@@ -24,6 +24,9 @@ namespace Eigen {
|
||||
* API for the %Matrix class provides easy access to linear-algebra
|
||||
* operations.
|
||||
*
|
||||
* See documentation of class Matrix for detailed information on the template parameters
|
||||
* storage layout.
|
||||
*
|
||||
* This class can be extended with the help of the plugin mechanism described on the page
|
||||
* \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_ARRAY_PLUGIN.
|
||||
*
|
||||
@@ -69,11 +72,27 @@ class Array
|
||||
* the usage of 'using'. This should be done only for operator=.
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Array& operator=(const EigenBase<OtherDerived> &other)
|
||||
{
|
||||
return Base::operator=(other);
|
||||
}
|
||||
|
||||
/** Set all the entries to \a value.
|
||||
* \sa DenseBase::setConstant(), DenseBase::fill()
|
||||
*/
|
||||
/* This overload is needed because the usage of
|
||||
* using Base::operator=;
|
||||
* fails on MSVC. Since the code below is working with GCC and MSVC, we skipped
|
||||
* the usage of 'using'. This should be done only for operator=.
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Array& operator=(const Scalar &value)
|
||||
{
|
||||
Base::setConstant(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Copies the value of the expression \a other into \c *this with automatic resizing.
|
||||
*
|
||||
* *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
|
||||
@@ -84,7 +103,8 @@ class Array
|
||||
* remain row-vectors and vectors remain vectors.
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE Array& operator=(const ArrayBase<OtherDerived>& other)
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Array& operator=(const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
return Base::_set(other);
|
||||
}
|
||||
@@ -92,11 +112,12 @@ class Array
|
||||
/** This is a special case of the templated operator=. Its purpose is to
|
||||
* prevent a default operator= from hiding the templated operator=.
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Array& operator=(const Array& other)
|
||||
{
|
||||
return Base::_set(other);
|
||||
}
|
||||
|
||||
|
||||
/** Default constructor.
|
||||
*
|
||||
* For fixed-size matrices, does nothing.
|
||||
@@ -107,6 +128,7 @@ class Array
|
||||
*
|
||||
* \sa resize(Index,Index)
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Array() : Base()
|
||||
{
|
||||
Base::_check_template_params();
|
||||
@@ -116,6 +138,7 @@ class Array
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
// FIXME is it still needed ??
|
||||
/** \internal */
|
||||
EIGEN_DEVICE_FUNC
|
||||
Array(internal::constructor_without_unaligned_array_assert)
|
||||
: Base(internal::constructor_without_unaligned_array_assert())
|
||||
{
|
||||
@@ -124,41 +147,64 @@ class Array
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Constructs a vector or row-vector with given dimension. \only_for_vectors
|
||||
*
|
||||
* Note that this is only useful for dynamic-size vectors. For fixed-size vectors,
|
||||
* it is redundant to pass the dimension here, so it makes more sense to use the default
|
||||
* constructor Matrix() instead.
|
||||
*/
|
||||
EIGEN_STRONG_INLINE explicit Array(Index dim)
|
||||
: Base(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim)
|
||||
#ifdef EIGEN_HAVE_RVALUE_REFERENCES
|
||||
EIGEN_DEVICE_FUNC
|
||||
Array(Array&& other)
|
||||
: Base(std::move(other))
|
||||
{
|
||||
Base::_check_template_params();
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Array)
|
||||
eigen_assert(dim >= 0);
|
||||
eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim);
|
||||
EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
||||
if (RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic)
|
||||
Base::_set_noalias(other);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
Array& operator=(Array&& other)
|
||||
{
|
||||
other.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE explicit Array(const T& x)
|
||||
{
|
||||
Base::_check_template_params();
|
||||
Base::template _init1<T>(x);
|
||||
}
|
||||
|
||||
template<typename T0, typename T1>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Array(const T0& val0, const T1& val1)
|
||||
{
|
||||
Base::_check_template_params();
|
||||
this->template _init2<T0,T1>(val0, val1);
|
||||
}
|
||||
#else
|
||||
/** constructs an uninitialized matrix with \a rows rows and \a cols columns.
|
||||
/** \brief Constructs a fixed-sized array initialized with coefficients starting at \a data */
|
||||
EIGEN_DEVICE_FUNC explicit Array(const Scalar *data);
|
||||
/** Constructs a vector or row-vector with given dimension. \only_for_vectors
|
||||
*
|
||||
* This is useful for dynamic-size matrices. For fixed-size matrices,
|
||||
* Note that this is only useful for dynamic-size vectors. For fixed-size vectors,
|
||||
* it is redundant to pass the dimension here, so it makes more sense to use the default
|
||||
* constructor Array() instead.
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE explicit Array(Index dim);
|
||||
/** constructs an initialized 1x1 Array with the given coefficient */
|
||||
Array(const Scalar& value);
|
||||
/** constructs an uninitialized array with \a rows rows and \a cols columns.
|
||||
*
|
||||
* This is useful for dynamic-size arrays. For fixed-size arrays,
|
||||
* it is redundant to pass these parameters, so one should use the default constructor
|
||||
* Matrix() instead. */
|
||||
* Array() instead. */
|
||||
Array(Index rows, Index cols);
|
||||
/** constructs an initialized 2D vector with given coefficients */
|
||||
Array(const Scalar& val0, const Scalar& val1);
|
||||
#endif
|
||||
|
||||
/** constructs an initialized 3D vector with given coefficients */
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2)
|
||||
{
|
||||
Base::_check_template_params();
|
||||
@@ -168,6 +214,7 @@ class Array
|
||||
m_storage.data()[2] = val2;
|
||||
}
|
||||
/** constructs an initialized 4D vector with given coefficients */
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2, const Scalar& val3)
|
||||
{
|
||||
Base::_check_template_params();
|
||||
@@ -178,51 +225,21 @@ class Array
|
||||
m_storage.data()[3] = val3;
|
||||
}
|
||||
|
||||
explicit Array(const Scalar *data);
|
||||
|
||||
/** Constructor copying the value of the expression \a other */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE Array(const ArrayBase<OtherDerived>& other)
|
||||
: Base(other.rows() * other.cols(), other.rows(), other.cols())
|
||||
{
|
||||
Base::_check_template_params();
|
||||
Base::_set_noalias(other);
|
||||
}
|
||||
/** Copy constructor */
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Array(const Array& other)
|
||||
: Base(other.rows() * other.cols(), other.rows(), other.cols())
|
||||
{
|
||||
Base::_check_template_params();
|
||||
Base::_set_noalias(other);
|
||||
}
|
||||
/** Copy constructor with in-place evaluation */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE Array(const ReturnByValue<OtherDerived>& other)
|
||||
{
|
||||
Base::_check_template_params();
|
||||
Base::resize(other.rows(), other.cols());
|
||||
other.evalTo(*this);
|
||||
}
|
||||
: Base(other)
|
||||
{ }
|
||||
|
||||
/** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Array(const EigenBase<OtherDerived> &other)
|
||||
: Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
|
||||
{
|
||||
Base::_check_template_params();
|
||||
Base::resize(other.rows(), other.cols());
|
||||
*this = other;
|
||||
}
|
||||
: Base(other.derived())
|
||||
{ }
|
||||
|
||||
/** Override MatrixBase::swap() since for dynamic-sized matrices of same type it is enough to swap the
|
||||
* data pointers.
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
void swap(ArrayBase<OtherDerived> const & other)
|
||||
{ this->_swap(other.derived()); }
|
||||
|
||||
inline Index innerStride() const { return 1; }
|
||||
inline Index outerStride() const { return this->innerSize(); }
|
||||
EIGEN_DEVICE_FUNC inline Index innerStride() const { return 1; }
|
||||
EIGEN_DEVICE_FUNC inline Index outerStride() const { return this->innerSize(); }
|
||||
|
||||
#ifdef EIGEN_ARRAY_PLUGIN
|
||||
#include EIGEN_ARRAY_PLUGIN
|
||||
|
||||
@@ -50,7 +50,6 @@ template<typename Derived> class ArrayBase
|
||||
typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>::operator*;
|
||||
|
||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||
typedef typename internal::traits<Derived>::Index Index;
|
||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
@@ -64,8 +63,7 @@ template<typename Derived> class ArrayBase
|
||||
using Base::MaxSizeAtCompileTime;
|
||||
using Base::IsVectorAtCompileTime;
|
||||
using Base::Flags;
|
||||
using Base::CoeffReadCost;
|
||||
|
||||
|
||||
using Base::derived;
|
||||
using Base::const_cast_derived;
|
||||
using Base::rows;
|
||||
@@ -85,22 +83,10 @@ template<typename Derived> class ArrayBase
|
||||
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
/** \internal the plain matrix type corresponding to this expression. Note that is not necessarily
|
||||
* exactly the return type of eval(): in the case of plain matrices, the return type of eval() is a const
|
||||
* reference to a matrix, not a matrix! It is however guaranteed that the return type of eval() is either
|
||||
* PlainObject or const PlainObject&.
|
||||
*/
|
||||
typedef Array<typename internal::traits<Derived>::Scalar,
|
||||
internal::traits<Derived>::RowsAtCompileTime,
|
||||
internal::traits<Derived>::ColsAtCompileTime,
|
||||
AutoAlign | (internal::traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor),
|
||||
internal::traits<Derived>::MaxRowsAtCompileTime,
|
||||
internal::traits<Derived>::MaxColsAtCompileTime
|
||||
> PlainObject;
|
||||
|
||||
typedef typename Base::PlainObject PlainObject;
|
||||
|
||||
/** \internal Represents a matrix with all coefficients equal to one another*/
|
||||
typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Derived> ConstantReturnType;
|
||||
typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,PlainObject> ConstantReturnType;
|
||||
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::ArrayBase
|
||||
@@ -118,40 +104,57 @@ template<typename Derived> class ArrayBase
|
||||
/** Special case of the template operator=, in order to prevent the compiler
|
||||
* from generating a default operator= (issue hit with g++ 4.1)
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator=(const ArrayBase& other)
|
||||
{
|
||||
return internal::assign_selector<Derived,Derived>::run(derived(), other.derived());
|
||||
internal::call_assignment(derived(), other.derived());
|
||||
return derived();
|
||||
}
|
||||
|
||||
/** Set all the entries to \a value.
|
||||
* \sa DenseBase::setConstant(), DenseBase::fill() */
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator=(const Scalar &value)
|
||||
{ Base::setConstant(value); return derived(); }
|
||||
|
||||
Derived& operator+=(const Scalar& scalar)
|
||||
{ return *this = derived() + scalar; }
|
||||
Derived& operator-=(const Scalar& scalar)
|
||||
{ return *this = derived() - scalar; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator+=(const Scalar& scalar);
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator-=(const Scalar& scalar);
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator+=(const ArrayBase<OtherDerived>& other);
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator-=(const ArrayBase<OtherDerived>& other);
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator*=(const ArrayBase<OtherDerived>& other);
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator/=(const ArrayBase<OtherDerived>& other);
|
||||
|
||||
public:
|
||||
EIGEN_DEVICE_FUNC
|
||||
ArrayBase<Derived>& array() { return *this; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
const ArrayBase<Derived>& array() const { return *this; }
|
||||
|
||||
/** \returns an \link Eigen::MatrixBase Matrix \endlink expression of this array
|
||||
* \sa MatrixBase::array() */
|
||||
MatrixWrapper<Derived> matrix() { return derived(); }
|
||||
const MatrixWrapper<const Derived> matrix() const { return derived(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
MatrixWrapper<Derived> matrix() { return MatrixWrapper<Derived>(derived()); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
const MatrixWrapper<const Derived> matrix() const { return MatrixWrapper<const Derived>(derived()); }
|
||||
|
||||
// template<typename Dest>
|
||||
// inline void evalTo(Dest& dst) const { dst = matrix(); }
|
||||
|
||||
protected:
|
||||
EIGEN_DEVICE_FUNC
|
||||
ArrayBase() : Base() {}
|
||||
|
||||
private:
|
||||
@@ -176,8 +179,7 @@ template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE Derived &
|
||||
ArrayBase<Derived>::operator-=(const ArrayBase<OtherDerived> &other)
|
||||
{
|
||||
SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, Derived, OtherDerived> tmp(derived());
|
||||
tmp = other.derived();
|
||||
call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar>());
|
||||
return derived();
|
||||
}
|
||||
|
||||
@@ -190,8 +192,7 @@ template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE Derived &
|
||||
ArrayBase<Derived>::operator+=(const ArrayBase<OtherDerived>& other)
|
||||
{
|
||||
SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, Derived, OtherDerived> tmp(derived());
|
||||
tmp = other.derived();
|
||||
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar>());
|
||||
return derived();
|
||||
}
|
||||
|
||||
@@ -204,8 +205,7 @@ template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE Derived &
|
||||
ArrayBase<Derived>::operator*=(const ArrayBase<OtherDerived>& other)
|
||||
{
|
||||
SelfCwiseBinaryOp<internal::scalar_product_op<Scalar>, Derived, OtherDerived> tmp(derived());
|
||||
tmp = other.derived();
|
||||
call_assignment(derived(), other.derived(), internal::mul_assign_op<Scalar,typename OtherDerived::Scalar>());
|
||||
return derived();
|
||||
}
|
||||
|
||||
@@ -218,8 +218,7 @@ template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE Derived &
|
||||
ArrayBase<Derived>::operator/=(const ArrayBase<OtherDerived>& other)
|
||||
{
|
||||
SelfCwiseBinaryOp<internal::scalar_quotient_op<Scalar>, Derived, OtherDerived> tmp(derived());
|
||||
tmp = other.derived();
|
||||
call_assignment(derived(), other.derived(), internal::div_assign_op<Scalar>());
|
||||
return derived();
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,11 @@ struct traits<ArrayWrapper<ExpressionType> >
|
||||
: public traits<typename remove_all<typename ExpressionType::Nested>::type >
|
||||
{
|
||||
typedef ArrayXpr XprKind;
|
||||
// Let's remove NestByRefBit
|
||||
enum {
|
||||
Flags0 = traits<typename remove_all<typename ExpressionType::Nested>::type >::Flags,
|
||||
Flags = Flags0 & ~NestByRefBit
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -39,6 +44,7 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
|
||||
typedef ArrayBase<ArrayWrapper> Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper)
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ArrayWrapper)
|
||||
typedef typename internal::remove_all<ExpressionType>::type NestedExpression;
|
||||
|
||||
typedef typename internal::conditional<
|
||||
internal::is_lvalue<ExpressionType>::value,
|
||||
@@ -46,43 +52,56 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
|
||||
const Scalar
|
||||
>::type ScalarWithConstIfNotLvalue;
|
||||
|
||||
typedef typename internal::nested<ExpressionType>::type NestedExpressionType;
|
||||
typedef typename internal::ref_selector<ExpressionType>::type NestedExpressionType;
|
||||
|
||||
inline ArrayWrapper(ExpressionType& matrix) : m_expression(matrix) {}
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit EIGEN_STRONG_INLINE ArrayWrapper(ExpressionType& matrix) : m_expression(matrix) {}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index rows() const { return m_expression.rows(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index cols() const { return m_expression.cols(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index outerStride() const { return m_expression.outerStride(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index innerStride() const { return m_expression.innerStride(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline ScalarWithConstIfNotLvalue* data() { return m_expression.const_cast_derived().data(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar* data() const { return m_expression.data(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline CoeffReturnType coeff(Index rowId, Index colId) const
|
||||
{
|
||||
return m_expression.coeff(rowId, colId);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Scalar& coeffRef(Index rowId, Index colId)
|
||||
{
|
||||
return m_expression.const_cast_derived().coeffRef(rowId, colId);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar& coeffRef(Index rowId, Index colId) const
|
||||
{
|
||||
return m_expression.const_cast_derived().coeffRef(rowId, colId);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline CoeffReturnType coeff(Index index) const
|
||||
{
|
||||
return m_expression.coeff(index);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Scalar& coeffRef(Index index)
|
||||
{
|
||||
return m_expression.const_cast_derived().coeffRef(index);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar& coeffRef(Index index) const
|
||||
{
|
||||
return m_expression.const_cast_derived().coeffRef(index);
|
||||
@@ -113,9 +132,11 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
|
||||
}
|
||||
|
||||
template<typename Dest>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline void evalTo(Dest& dst) const { dst = m_expression; }
|
||||
|
||||
const typename internal::remove_all<NestedExpressionType>::type&
|
||||
EIGEN_DEVICE_FUNC
|
||||
nestedExpression() const
|
||||
{
|
||||
return m_expression;
|
||||
@@ -123,10 +144,12 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
|
||||
|
||||
/** Forwards the resizing request to the nested expression
|
||||
* \sa DenseBase::resize(Index) */
|
||||
EIGEN_DEVICE_FUNC
|
||||
void resize(Index newSize) { m_expression.const_cast_derived().resize(newSize); }
|
||||
/** Forwards the resizing request to the nested expression
|
||||
* \sa DenseBase::resize(Index,Index)*/
|
||||
void resize(Index nbRows, Index nbCols) { m_expression.const_cast_derived().resize(nbRows,nbCols); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
void resize(Index rows, Index cols) { m_expression.const_cast_derived().resize(rows,cols); }
|
||||
|
||||
protected:
|
||||
NestedExpressionType m_expression;
|
||||
@@ -149,6 +172,11 @@ struct traits<MatrixWrapper<ExpressionType> >
|
||||
: public traits<typename remove_all<typename ExpressionType::Nested>::type >
|
||||
{
|
||||
typedef MatrixXpr XprKind;
|
||||
// Let's remove NestByRefBit
|
||||
enum {
|
||||
Flags0 = traits<typename remove_all<typename ExpressionType::Nested>::type >::Flags,
|
||||
Flags = Flags0 & ~NestByRefBit
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -159,6 +187,7 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
|
||||
typedef MatrixBase<MatrixWrapper<ExpressionType> > Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(MatrixWrapper)
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper)
|
||||
typedef typename internal::remove_all<ExpressionType>::type NestedExpression;
|
||||
|
||||
typedef typename internal::conditional<
|
||||
internal::is_lvalue<ExpressionType>::value,
|
||||
@@ -166,43 +195,56 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
|
||||
const Scalar
|
||||
>::type ScalarWithConstIfNotLvalue;
|
||||
|
||||
typedef typename internal::nested<ExpressionType>::type NestedExpressionType;
|
||||
typedef typename internal::ref_selector<ExpressionType>::type NestedExpressionType;
|
||||
|
||||
inline MatrixWrapper(ExpressionType& a_matrix) : m_expression(a_matrix) {}
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit inline MatrixWrapper(ExpressionType& matrix) : m_expression(matrix) {}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index rows() const { return m_expression.rows(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index cols() const { return m_expression.cols(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index outerStride() const { return m_expression.outerStride(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index innerStride() const { return m_expression.innerStride(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline ScalarWithConstIfNotLvalue* data() { return m_expression.const_cast_derived().data(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar* data() const { return m_expression.data(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline CoeffReturnType coeff(Index rowId, Index colId) const
|
||||
{
|
||||
return m_expression.coeff(rowId, colId);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Scalar& coeffRef(Index rowId, Index colId)
|
||||
{
|
||||
return m_expression.const_cast_derived().coeffRef(rowId, colId);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar& coeffRef(Index rowId, Index colId) const
|
||||
{
|
||||
return m_expression.derived().coeffRef(rowId, colId);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline CoeffReturnType coeff(Index index) const
|
||||
{
|
||||
return m_expression.coeff(index);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Scalar& coeffRef(Index index)
|
||||
{
|
||||
return m_expression.const_cast_derived().coeffRef(index);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar& coeffRef(Index index) const
|
||||
{
|
||||
return m_expression.const_cast_derived().coeffRef(index);
|
||||
@@ -232,6 +274,7 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
|
||||
m_expression.const_cast_derived().template writePacket<LoadMode>(index, val);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
const typename internal::remove_all<NestedExpressionType>::type&
|
||||
nestedExpression() const
|
||||
{
|
||||
@@ -240,10 +283,12 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
|
||||
|
||||
/** Forwards the resizing request to the nested expression
|
||||
* \sa DenseBase::resize(Index) */
|
||||
EIGEN_DEVICE_FUNC
|
||||
void resize(Index newSize) { m_expression.const_cast_derived().resize(newSize); }
|
||||
/** Forwards the resizing request to the nested expression
|
||||
* \sa DenseBase::resize(Index,Index)*/
|
||||
void resize(Index nbRows, Index nbCols) { m_expression.const_cast_derived().resize(nbRows,nbCols); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
void resize(Index rows, Index cols) { m_expression.const_cast_derived().resize(rows,cols); }
|
||||
|
||||
protected:
|
||||
NestedExpressionType m_expression;
|
||||
|
||||
@@ -14,471 +14,6 @@
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
/***************************************************************************
|
||||
* Part 1 : the logic deciding a strategy for traversal and unrolling *
|
||||
***************************************************************************/
|
||||
|
||||
template <typename Derived, typename OtherDerived>
|
||||
struct assign_traits
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
DstIsAligned = Derived::Flags & AlignedBit,
|
||||
DstHasDirectAccess = Derived::Flags & DirectAccessBit,
|
||||
SrcIsAligned = OtherDerived::Flags & AlignedBit,
|
||||
JointAlignment = bool(DstIsAligned) && bool(SrcIsAligned) ? Aligned : Unaligned
|
||||
};
|
||||
|
||||
private:
|
||||
enum {
|
||||
InnerSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::SizeAtCompileTime)
|
||||
: int(Derived::Flags)&RowMajorBit ? int(Derived::ColsAtCompileTime)
|
||||
: int(Derived::RowsAtCompileTime),
|
||||
InnerMaxSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::MaxSizeAtCompileTime)
|
||||
: int(Derived::Flags)&RowMajorBit ? int(Derived::MaxColsAtCompileTime)
|
||||
: int(Derived::MaxRowsAtCompileTime),
|
||||
MaxSizeAtCompileTime = Derived::SizeAtCompileTime,
|
||||
PacketSize = packet_traits<typename Derived::Scalar>::size
|
||||
};
|
||||
|
||||
enum {
|
||||
StorageOrdersAgree = (int(Derived::IsRowMajor) == int(OtherDerived::IsRowMajor)),
|
||||
MightVectorize = StorageOrdersAgree
|
||||
&& (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit),
|
||||
MayInnerVectorize = MightVectorize && int(InnerSize)!=Dynamic && int(InnerSize)%int(PacketSize)==0
|
||||
&& int(DstIsAligned) && int(SrcIsAligned),
|
||||
MayLinearize = StorageOrdersAgree && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit),
|
||||
MayLinearVectorize = MightVectorize && MayLinearize && DstHasDirectAccess
|
||||
&& (DstIsAligned || MaxSizeAtCompileTime == Dynamic),
|
||||
/* If the destination isn't aligned, we have to do runtime checks and we don't unroll,
|
||||
so it's only good for large enough sizes. */
|
||||
MaySliceVectorize = MightVectorize && DstHasDirectAccess
|
||||
&& (int(InnerMaxSize)==Dynamic || int(InnerMaxSize)>=3*PacketSize)
|
||||
/* slice vectorization can be slow, so we only want it if the slices are big, which is
|
||||
indicated by InnerMaxSize rather than InnerSize, think of the case of a dynamic block
|
||||
in a fixed-size matrix */
|
||||
};
|
||||
|
||||
public:
|
||||
enum {
|
||||
Traversal = int(MayInnerVectorize) ? int(InnerVectorizedTraversal)
|
||||
: int(MayLinearVectorize) ? int(LinearVectorizedTraversal)
|
||||
: int(MaySliceVectorize) ? int(SliceVectorizedTraversal)
|
||||
: int(MayLinearize) ? int(LinearTraversal)
|
||||
: int(DefaultTraversal),
|
||||
Vectorized = int(Traversal) == InnerVectorizedTraversal
|
||||
|| int(Traversal) == LinearVectorizedTraversal
|
||||
|| int(Traversal) == SliceVectorizedTraversal
|
||||
};
|
||||
|
||||
private:
|
||||
enum {
|
||||
UnrollingLimit = EIGEN_UNROLLING_LIMIT * (Vectorized ? int(PacketSize) : 1),
|
||||
MayUnrollCompletely = int(Derived::SizeAtCompileTime) != Dynamic
|
||||
&& int(OtherDerived::CoeffReadCost) != Dynamic
|
||||
&& int(Derived::SizeAtCompileTime) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit),
|
||||
MayUnrollInner = int(InnerSize) != Dynamic
|
||||
&& int(OtherDerived::CoeffReadCost) != Dynamic
|
||||
&& int(InnerSize) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit)
|
||||
};
|
||||
|
||||
public:
|
||||
enum {
|
||||
Unrolling = (int(Traversal) == int(InnerVectorizedTraversal) || int(Traversal) == int(DefaultTraversal))
|
||||
? (
|
||||
int(MayUnrollCompletely) ? int(CompleteUnrolling)
|
||||
: int(MayUnrollInner) ? int(InnerUnrolling)
|
||||
: int(NoUnrolling)
|
||||
)
|
||||
: int(Traversal) == int(LinearVectorizedTraversal)
|
||||
? ( bool(MayUnrollCompletely) && bool(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) )
|
||||
: int(Traversal) == int(LinearTraversal)
|
||||
? ( bool(MayUnrollCompletely) ? int(CompleteUnrolling) : int(NoUnrolling) )
|
||||
: int(NoUnrolling)
|
||||
};
|
||||
|
||||
#ifdef EIGEN_DEBUG_ASSIGN
|
||||
static void debug()
|
||||
{
|
||||
EIGEN_DEBUG_VAR(DstIsAligned)
|
||||
EIGEN_DEBUG_VAR(SrcIsAligned)
|
||||
EIGEN_DEBUG_VAR(JointAlignment)
|
||||
EIGEN_DEBUG_VAR(InnerSize)
|
||||
EIGEN_DEBUG_VAR(InnerMaxSize)
|
||||
EIGEN_DEBUG_VAR(PacketSize)
|
||||
EIGEN_DEBUG_VAR(StorageOrdersAgree)
|
||||
EIGEN_DEBUG_VAR(MightVectorize)
|
||||
EIGEN_DEBUG_VAR(MayLinearize)
|
||||
EIGEN_DEBUG_VAR(MayInnerVectorize)
|
||||
EIGEN_DEBUG_VAR(MayLinearVectorize)
|
||||
EIGEN_DEBUG_VAR(MaySliceVectorize)
|
||||
EIGEN_DEBUG_VAR(Traversal)
|
||||
EIGEN_DEBUG_VAR(UnrollingLimit)
|
||||
EIGEN_DEBUG_VAR(MayUnrollCompletely)
|
||||
EIGEN_DEBUG_VAR(MayUnrollInner)
|
||||
EIGEN_DEBUG_VAR(Unrolling)
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
* Part 2 : meta-unrollers
|
||||
***************************************************************************/
|
||||
|
||||
/************************
|
||||
*** Default traversal ***
|
||||
************************/
|
||||
|
||||
template<typename Derived1, typename Derived2, int Index, int Stop>
|
||||
struct assign_DefaultTraversal_CompleteUnrolling
|
||||
{
|
||||
enum {
|
||||
outer = Index / Derived1::InnerSizeAtCompileTime,
|
||||
inner = Index % Derived1::InnerSizeAtCompileTime
|
||||
};
|
||||
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
dst.copyCoeffByOuterInner(outer, inner, src);
|
||||
assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, int Stop>
|
||||
struct assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, int Index, int Stop>
|
||||
struct assign_DefaultTraversal_InnerUnrolling
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, typename Derived1::Index outer)
|
||||
{
|
||||
dst.copyCoeffByOuterInner(outer, Index, src);
|
||||
assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src, outer);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, int Stop>
|
||||
struct assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Stop, Stop>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, typename Derived1::Index) {}
|
||||
};
|
||||
|
||||
/***********************
|
||||
*** Linear traversal ***
|
||||
***********************/
|
||||
|
||||
template<typename Derived1, typename Derived2, int Index, int Stop>
|
||||
struct assign_LinearTraversal_CompleteUnrolling
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
dst.copyCoeff(Index, src);
|
||||
assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, int Stop>
|
||||
struct assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {}
|
||||
};
|
||||
|
||||
/**************************
|
||||
*** Inner vectorization ***
|
||||
**************************/
|
||||
|
||||
template<typename Derived1, typename Derived2, int Index, int Stop>
|
||||
struct assign_innervec_CompleteUnrolling
|
||||
{
|
||||
enum {
|
||||
outer = Index / Derived1::InnerSizeAtCompileTime,
|
||||
inner = Index % Derived1::InnerSizeAtCompileTime,
|
||||
JointAlignment = assign_traits<Derived1,Derived2>::JointAlignment
|
||||
};
|
||||
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
dst.template copyPacketByOuterInner<Derived2, Aligned, JointAlignment>(outer, inner, src);
|
||||
assign_innervec_CompleteUnrolling<Derived1, Derived2,
|
||||
Index+packet_traits<typename Derived1::Scalar>::size, Stop>::run(dst, src);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, int Stop>
|
||||
struct assign_innervec_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, int Index, int Stop>
|
||||
struct assign_innervec_InnerUnrolling
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, typename Derived1::Index outer)
|
||||
{
|
||||
dst.template copyPacketByOuterInner<Derived2, Aligned, Aligned>(outer, Index, src);
|
||||
assign_innervec_InnerUnrolling<Derived1, Derived2,
|
||||
Index+packet_traits<typename Derived1::Scalar>::size, Stop>::run(dst, src, outer);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, int Stop>
|
||||
struct assign_innervec_InnerUnrolling<Derived1, Derived2, Stop, Stop>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, typename Derived1::Index) {}
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
* Part 3 : implementation of all cases
|
||||
***************************************************************************/
|
||||
|
||||
template<typename Derived1, typename Derived2,
|
||||
int Traversal = assign_traits<Derived1, Derived2>::Traversal,
|
||||
int Unrolling = assign_traits<Derived1, Derived2>::Unrolling,
|
||||
int Version = Specialized>
|
||||
struct assign_impl;
|
||||
|
||||
/************************
|
||||
*** Default traversal ***
|
||||
************************/
|
||||
|
||||
template<typename Derived1, typename Derived2, int Unrolling, int Version>
|
||||
struct assign_impl<Derived1, Derived2, InvalidTraversal, Unrolling, Version>
|
||||
{
|
||||
static inline void run(Derived1 &, const Derived2 &) { }
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, int Version>
|
||||
struct assign_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling, Version>
|
||||
{
|
||||
typedef typename Derived1::Index Index;
|
||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
const Index innerSize = dst.innerSize();
|
||||
const Index outerSize = dst.outerSize();
|
||||
for(Index outer = 0; outer < outerSize; ++outer)
|
||||
for(Index inner = 0; inner < innerSize; ++inner)
|
||||
dst.copyCoeffByOuterInner(outer, inner, src);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, int Version>
|
||||
struct assign_impl<Derived1, Derived2, DefaultTraversal, CompleteUnrolling, Version>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
|
||||
::run(dst, src);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, int Version>
|
||||
struct assign_impl<Derived1, Derived2, DefaultTraversal, InnerUnrolling, Version>
|
||||
{
|
||||
typedef typename Derived1::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
const Index outerSize = dst.outerSize();
|
||||
for(Index outer = 0; outer < outerSize; ++outer)
|
||||
assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, 0, Derived1::InnerSizeAtCompileTime>
|
||||
::run(dst, src, outer);
|
||||
}
|
||||
};
|
||||
|
||||
/***********************
|
||||
*** Linear traversal ***
|
||||
***********************/
|
||||
|
||||
template<typename Derived1, typename Derived2, int Version>
|
||||
struct assign_impl<Derived1, Derived2, LinearTraversal, NoUnrolling, Version>
|
||||
{
|
||||
typedef typename Derived1::Index Index;
|
||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
const Index size = dst.size();
|
||||
for(Index i = 0; i < size; ++i)
|
||||
dst.copyCoeff(i, src);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, int Version>
|
||||
struct assign_impl<Derived1, Derived2, LinearTraversal, CompleteUnrolling, Version>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
|
||||
::run(dst, src);
|
||||
}
|
||||
};
|
||||
|
||||
/**************************
|
||||
*** Inner vectorization ***
|
||||
**************************/
|
||||
|
||||
template<typename Derived1, typename Derived2, int Version>
|
||||
struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, NoUnrolling, Version>
|
||||
{
|
||||
typedef typename Derived1::Index Index;
|
||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
const Index innerSize = dst.innerSize();
|
||||
const Index outerSize = dst.outerSize();
|
||||
const Index packetSize = packet_traits<typename Derived1::Scalar>::size;
|
||||
for(Index outer = 0; outer < outerSize; ++outer)
|
||||
for(Index inner = 0; inner < innerSize; inner+=packetSize)
|
||||
dst.template copyPacketByOuterInner<Derived2, Aligned, Aligned>(outer, inner, src);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, int Version>
|
||||
struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, CompleteUnrolling, Version>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
|
||||
::run(dst, src);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, int Version>
|
||||
struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, InnerUnrolling, Version>
|
||||
{
|
||||
typedef typename Derived1::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
const Index outerSize = dst.outerSize();
|
||||
for(Index outer = 0; outer < outerSize; ++outer)
|
||||
assign_innervec_InnerUnrolling<Derived1, Derived2, 0, Derived1::InnerSizeAtCompileTime>
|
||||
::run(dst, src, outer);
|
||||
}
|
||||
};
|
||||
|
||||
/***************************
|
||||
*** Linear vectorization ***
|
||||
***************************/
|
||||
|
||||
template <bool IsAligned = false>
|
||||
struct unaligned_assign_impl
|
||||
{
|
||||
template <typename Derived, typename OtherDerived>
|
||||
static EIGEN_STRONG_INLINE void run(const Derived&, OtherDerived&, typename Derived::Index, typename Derived::Index) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct unaligned_assign_impl<false>
|
||||
{
|
||||
// MSVC must not inline this functions. If it does, it fails to optimize the
|
||||
// packet access path.
|
||||
#ifdef _MSC_VER
|
||||
template <typename Derived, typename OtherDerived>
|
||||
static EIGEN_DONT_INLINE void run(const Derived& src, OtherDerived& dst, typename Derived::Index start, typename Derived::Index end)
|
||||
#else
|
||||
template <typename Derived, typename OtherDerived>
|
||||
static EIGEN_STRONG_INLINE void run(const Derived& src, OtherDerived& dst, typename Derived::Index start, typename Derived::Index end)
|
||||
#endif
|
||||
{
|
||||
for (typename Derived::Index index = start; index < end; ++index)
|
||||
dst.copyCoeff(index, src);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, int Version>
|
||||
struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling, Version>
|
||||
{
|
||||
typedef typename Derived1::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
const Index size = dst.size();
|
||||
typedef packet_traits<typename Derived1::Scalar> PacketTraits;
|
||||
enum {
|
||||
packetSize = PacketTraits::size,
|
||||
dstAlignment = PacketTraits::AlignedOnScalar ? Aligned : int(assign_traits<Derived1,Derived2>::DstIsAligned) ,
|
||||
srcAlignment = assign_traits<Derived1,Derived2>::JointAlignment
|
||||
};
|
||||
const Index alignedStart = assign_traits<Derived1,Derived2>::DstIsAligned ? 0
|
||||
: internal::first_aligned(&dst.coeffRef(0), size);
|
||||
const Index alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize;
|
||||
|
||||
unaligned_assign_impl<assign_traits<Derived1,Derived2>::DstIsAligned!=0>::run(src,dst,0,alignedStart);
|
||||
|
||||
for(Index index = alignedStart; index < alignedEnd; index += packetSize)
|
||||
{
|
||||
dst.template copyPacket<Derived2, dstAlignment, srcAlignment>(index, src);
|
||||
}
|
||||
|
||||
unaligned_assign_impl<>::run(src,dst,alignedEnd,size);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, int Version>
|
||||
struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, CompleteUnrolling, Version>
|
||||
{
|
||||
typedef typename Derived1::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
enum { size = Derived1::SizeAtCompileTime,
|
||||
packetSize = packet_traits<typename Derived1::Scalar>::size,
|
||||
alignedSize = (size/packetSize)*packetSize };
|
||||
|
||||
assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, alignedSize>::run(dst, src);
|
||||
assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, alignedSize, size>::run(dst, src);
|
||||
}
|
||||
};
|
||||
|
||||
/**************************
|
||||
*** Slice vectorization ***
|
||||
***************************/
|
||||
|
||||
template<typename Derived1, typename Derived2, int Version>
|
||||
struct assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling, Version>
|
||||
{
|
||||
typedef typename Derived1::Index Index;
|
||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
typedef packet_traits<typename Derived1::Scalar> PacketTraits;
|
||||
enum {
|
||||
packetSize = PacketTraits::size,
|
||||
alignable = PacketTraits::AlignedOnScalar,
|
||||
dstAlignment = alignable ? Aligned : int(assign_traits<Derived1,Derived2>::DstIsAligned) ,
|
||||
srcAlignment = assign_traits<Derived1,Derived2>::JointAlignment
|
||||
};
|
||||
const Index packetAlignedMask = packetSize - 1;
|
||||
const Index innerSize = dst.innerSize();
|
||||
const Index outerSize = dst.outerSize();
|
||||
const Index alignedStep = alignable ? (packetSize - dst.outerStride() % packetSize) & packetAlignedMask : 0;
|
||||
Index alignedStart = ((!alignable) || assign_traits<Derived1,Derived2>::DstIsAligned) ? 0
|
||||
: internal::first_aligned(&dst.coeffRef(0,0), innerSize);
|
||||
|
||||
for(Index outer = 0; outer < outerSize; ++outer)
|
||||
{
|
||||
const Index alignedEnd = alignedStart + ((innerSize-alignedStart) & ~packetAlignedMask);
|
||||
// do the non-vectorizable part of the assignment
|
||||
for(Index inner = 0; inner<alignedStart ; ++inner)
|
||||
dst.copyCoeffByOuterInner(outer, inner, src);
|
||||
|
||||
// do the vectorizable part of the assignment
|
||||
for(Index inner = alignedStart; inner<alignedEnd; inner+=packetSize)
|
||||
dst.template copyPacketByOuterInner<Derived2, dstAlignment, Unaligned>(outer, inner, src);
|
||||
|
||||
// do the non-vectorizable part of the assignment
|
||||
for(Index inner = alignedEnd; inner<innerSize ; ++inner)
|
||||
dst.copyCoeffByOuterInner(outer, inner, src);
|
||||
|
||||
alignedStart = std::min<Index>((alignedStart+alignedStep)%packetSize, innerSize);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
/***************************************************************************
|
||||
* Part 4 : implementation of DenseBase methods
|
||||
***************************************************************************/
|
||||
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE Derived& DenseBase<Derived>
|
||||
@@ -492,90 +27,62 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>
|
||||
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)
|
||||
EIGEN_STATIC_ASSERT(SameType,YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||
|
||||
#ifdef EIGEN_DEBUG_ASSIGN
|
||||
internal::assign_traits<Derived, OtherDerived>::debug();
|
||||
#endif
|
||||
eigen_assert(rows() == other.rows() && cols() == other.cols());
|
||||
internal::assign_impl<Derived, OtherDerived, int(SameType) ? int(internal::assign_traits<Derived, OtherDerived>::Traversal)
|
||||
: int(InvalidTraversal)>::run(derived(),other.derived());
|
||||
#ifndef EIGEN_NO_DEBUG
|
||||
checkTransposeAliasing(other.derived());
|
||||
#endif
|
||||
internal::call_assignment_no_alias(derived(),other.derived());
|
||||
|
||||
return derived();
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename Derived, typename OtherDerived,
|
||||
bool EvalBeforeAssigning = (int(internal::traits<OtherDerived>::Flags) & EvalBeforeAssigningBit) != 0,
|
||||
bool NeedToTranspose = ((int(Derived::RowsAtCompileTime) == 1 && int(OtherDerived::ColsAtCompileTime) == 1)
|
||||
| // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&".
|
||||
// revert to || as soon as not needed anymore.
|
||||
(int(Derived::ColsAtCompileTime) == 1 && int(OtherDerived::RowsAtCompileTime) == 1))
|
||||
&& int(Derived::SizeAtCompileTime) != 1>
|
||||
struct assign_selector;
|
||||
|
||||
template<typename Derived, typename OtherDerived>
|
||||
struct assign_selector<Derived,OtherDerived,false,false> {
|
||||
static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); }
|
||||
template<typename ActualDerived, typename ActualOtherDerived>
|
||||
static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { other.evalTo(dst); return dst; }
|
||||
};
|
||||
template<typename Derived, typename OtherDerived>
|
||||
struct assign_selector<Derived,OtherDerived,true,false> {
|
||||
static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); }
|
||||
};
|
||||
template<typename Derived, typename OtherDerived>
|
||||
struct assign_selector<Derived,OtherDerived,false,true> {
|
||||
static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); }
|
||||
template<typename ActualDerived, typename ActualOtherDerived>
|
||||
static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { Transpose<ActualDerived> dstTrans(dst); other.evalTo(dstTrans); return dst; }
|
||||
};
|
||||
template<typename Derived, typename OtherDerived>
|
||||
struct assign_selector<Derived,OtherDerived,true,true> {
|
||||
static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); }
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
return internal::assign_selector<Derived,OtherDerived>::run(derived(), other.derived());
|
||||
internal::call_assignment(derived(), other.derived());
|
||||
return derived();
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase& other)
|
||||
{
|
||||
return internal::assign_selector<Derived,Derived>::run(derived(), other.derived());
|
||||
internal::call_assignment(derived(), other.derived());
|
||||
return derived();
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const MatrixBase& other)
|
||||
{
|
||||
return internal::assign_selector<Derived,Derived>::run(derived(), other.derived());
|
||||
internal::call_assignment(derived(), other.derived());
|
||||
return derived();
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
template <typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
return internal::assign_selector<Derived,OtherDerived>::run(derived(), other.derived());
|
||||
internal::call_assignment(derived(), other.derived());
|
||||
return derived();
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
template <typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const EigenBase<OtherDerived>& other)
|
||||
{
|
||||
return internal::assign_selector<Derived,OtherDerived,false>::evalTo(derived(), other.derived());
|
||||
internal::call_assignment(derived(), other.derived());
|
||||
return derived();
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
|
||||
{
|
||||
return internal::assign_selector<Derived,OtherDerived,false>::evalTo(derived(), other.derived());
|
||||
other.derived().evalTo(derived());
|
||||
return derived();
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
254
Eigen/src/Core/Assign_MKL.h
Normal file → Executable file
254
Eigen/src/Core/Assign_MKL.h
Normal file → Executable file
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
Copyright (c) 2011, Intel Corporation. All rights reserved.
|
||||
|
||||
Copyright (C) 2015 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
@@ -37,17 +38,13 @@ namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename Op> struct vml_call
|
||||
{ enum { IsSupported = 0 }; };
|
||||
|
||||
template<typename Dst, typename Src, typename UnaryOp>
|
||||
template<typename Dst, typename Src>
|
||||
class vml_assign_traits
|
||||
{
|
||||
private:
|
||||
enum {
|
||||
DstHasDirectAccess = Dst::Flags & DirectAccessBit,
|
||||
SrcHasDirectAccess = Src::Flags & DirectAccessBit,
|
||||
|
||||
StorageOrdersAgree = (int(Dst::IsRowMajor) == int(Src::IsRowMajor)),
|
||||
InnerSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::SizeAtCompileTime)
|
||||
: int(Dst::Flags)&RowMajorBit ? int(Dst::ColsAtCompileTime)
|
||||
@@ -57,165 +54,118 @@ class vml_assign_traits
|
||||
: int(Dst::MaxRowsAtCompileTime),
|
||||
MaxSizeAtCompileTime = Dst::SizeAtCompileTime,
|
||||
|
||||
MightEnableVml = vml_call<UnaryOp>::IsSupported && StorageOrdersAgree && DstHasDirectAccess && SrcHasDirectAccess
|
||||
&& Src::InnerStrideAtCompileTime==1 && Dst::InnerStrideAtCompileTime==1,
|
||||
MightEnableVml = StorageOrdersAgree && DstHasDirectAccess && SrcHasDirectAccess && Src::InnerStrideAtCompileTime==1 && Dst::InnerStrideAtCompileTime==1,
|
||||
MightLinearize = MightEnableVml && (int(Dst::Flags) & int(Src::Flags) & LinearAccessBit),
|
||||
VmlSize = MightLinearize ? MaxSizeAtCompileTime : InnerMaxSize,
|
||||
LargeEnough = VmlSize==Dynamic || VmlSize>=EIGEN_MKL_VML_THRESHOLD,
|
||||
MayEnableVml = MightEnableVml && LargeEnough,
|
||||
MayLinearize = MayEnableVml && MightLinearize
|
||||
LargeEnough = VmlSize==Dynamic || VmlSize>=EIGEN_MKL_VML_THRESHOLD
|
||||
};
|
||||
public:
|
||||
enum {
|
||||
Traversal = MayLinearize ? LinearVectorizedTraversal
|
||||
: MayEnableVml ? InnerVectorizedTraversal
|
||||
: DefaultTraversal
|
||||
EnableVml = MightEnableVml && LargeEnough,
|
||||
Traversal = MightLinearize ? LinearTraversal : DefaultTraversal
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, typename UnaryOp, int Traversal, int Unrolling,
|
||||
int VmlTraversal = vml_assign_traits<Derived1, Derived2, UnaryOp>::Traversal >
|
||||
struct vml_assign_impl
|
||||
: assign_impl<Derived1, Eigen::CwiseUnaryOp<UnaryOp, Derived2>,Traversal,Unrolling,BuiltIn>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, typename UnaryOp, int Traversal, int Unrolling>
|
||||
struct vml_assign_impl<Derived1, Derived2, UnaryOp, Traversal, Unrolling, InnerVectorizedTraversal>
|
||||
{
|
||||
typedef typename Derived1::Scalar Scalar;
|
||||
typedef typename Derived1::Index Index;
|
||||
static inline void run(Derived1& dst, const CwiseUnaryOp<UnaryOp, Derived2>& src)
|
||||
{
|
||||
// in case we want to (or have to) skip VML at runtime we can call:
|
||||
// assign_impl<Derived1,Eigen::CwiseUnaryOp<UnaryOp, Derived2>,Traversal,Unrolling,BuiltIn>::run(dst,src);
|
||||
const Index innerSize = dst.innerSize();
|
||||
const Index outerSize = dst.outerSize();
|
||||
for(Index outer = 0; outer < outerSize; ++outer) {
|
||||
const Scalar *src_ptr = src.IsRowMajor ? &(src.nestedExpression().coeffRef(outer,0)) :
|
||||
&(src.nestedExpression().coeffRef(0, outer));
|
||||
Scalar *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer,0)) : &(dst.coeffRef(0, outer));
|
||||
vml_call<UnaryOp>::run(src.functor(), innerSize, src_ptr, dst_ptr );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, typename UnaryOp, int Traversal, int Unrolling>
|
||||
struct vml_assign_impl<Derived1, Derived2, UnaryOp, Traversal, Unrolling, LinearVectorizedTraversal>
|
||||
{
|
||||
static inline void run(Derived1& dst, const CwiseUnaryOp<UnaryOp, Derived2>& src)
|
||||
{
|
||||
// in case we want to (or have to) skip VML at runtime we can call:
|
||||
// assign_impl<Derived1,Eigen::CwiseUnaryOp<UnaryOp, Derived2>,Traversal,Unrolling,BuiltIn>::run(dst,src);
|
||||
vml_call<UnaryOp>::run(src.functor(), dst.size(), src.nestedExpression().data(), dst.data() );
|
||||
}
|
||||
};
|
||||
|
||||
// Macroses
|
||||
|
||||
#define EIGEN_MKL_VML_SPECIALIZE_ASSIGN(TRAVERSAL,UNROLLING) \
|
||||
template<typename Derived1, typename Derived2, typename UnaryOp> \
|
||||
struct assign_impl<Derived1, Eigen::CwiseUnaryOp<UnaryOp, Derived2>, TRAVERSAL, UNROLLING, Specialized> { \
|
||||
static inline void run(Derived1 &dst, const Eigen::CwiseUnaryOp<UnaryOp, Derived2> &src) { \
|
||||
vml_assign_impl<Derived1,Derived2,UnaryOp,TRAVERSAL,UNROLLING>::run(dst, src); \
|
||||
} \
|
||||
};
|
||||
|
||||
EIGEN_MKL_VML_SPECIALIZE_ASSIGN(DefaultTraversal,NoUnrolling)
|
||||
EIGEN_MKL_VML_SPECIALIZE_ASSIGN(DefaultTraversal,CompleteUnrolling)
|
||||
EIGEN_MKL_VML_SPECIALIZE_ASSIGN(DefaultTraversal,InnerUnrolling)
|
||||
EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearTraversal,NoUnrolling)
|
||||
EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearTraversal,CompleteUnrolling)
|
||||
EIGEN_MKL_VML_SPECIALIZE_ASSIGN(InnerVectorizedTraversal,NoUnrolling)
|
||||
EIGEN_MKL_VML_SPECIALIZE_ASSIGN(InnerVectorizedTraversal,CompleteUnrolling)
|
||||
EIGEN_MKL_VML_SPECIALIZE_ASSIGN(InnerVectorizedTraversal,InnerUnrolling)
|
||||
EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearVectorizedTraversal,CompleteUnrolling)
|
||||
EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearVectorizedTraversal,NoUnrolling)
|
||||
EIGEN_MKL_VML_SPECIALIZE_ASSIGN(SliceVectorizedTraversal,NoUnrolling)
|
||||
|
||||
|
||||
#define EIGEN_PP_EXPAND(ARG) ARG
|
||||
#if !defined (EIGEN_FAST_MATH) || (EIGEN_FAST_MATH != 1)
|
||||
#define EIGEN_MKL_VML_MODE VML_HA
|
||||
#define EIGEN_VMLMODE_EXPAND_LA , VML_HA
|
||||
#else
|
||||
#define EIGEN_MKL_VML_MODE VML_LA
|
||||
#define EIGEN_VMLMODE_EXPAND_LA , VML_LA
|
||||
#endif
|
||||
|
||||
#define EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE) \
|
||||
template<> struct vml_call< scalar_##EIGENOP##_op<EIGENTYPE> > { \
|
||||
enum { IsSupported = 1 }; \
|
||||
static inline void run( const scalar_##EIGENOP##_op<EIGENTYPE>& /*func*/, \
|
||||
int size, const EIGENTYPE* src, EIGENTYPE* dst) { \
|
||||
VMLOP(size, (const VMLTYPE*)src, (VMLTYPE*)dst); \
|
||||
} \
|
||||
#define EIGEN_VMLMODE_EXPAND__
|
||||
|
||||
#define EIGEN_VMLMODE_PREFIX_LA vm
|
||||
#define EIGEN_VMLMODE_PREFIX__ v
|
||||
#define EIGEN_VMLMODE_PREFIX(VMLMODE) EIGEN_CAT(EIGEN_VMLMODE_PREFIX_,VMLMODE)
|
||||
|
||||
#define EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE, VMLMODE) \
|
||||
template< typename DstXprType, typename SrcXprNested> \
|
||||
struct Assignment<DstXprType, CwiseUnaryOp<scalar_##EIGENOP##_op<EIGENTYPE>, SrcXprNested>, assign_op<EIGENTYPE>, \
|
||||
Dense2Dense, typename enable_if<vml_assign_traits<DstXprType,SrcXprNested>::EnableVml,EIGENTYPE>::type> { \
|
||||
typedef CwiseUnaryOp<scalar_##EIGENOP##_op<EIGENTYPE>, SrcXprNested> SrcXprType; \
|
||||
static void run(DstXprType &dst, const SrcXprType &src, const assign_op<EIGENTYPE> &/*func*/) { \
|
||||
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); \
|
||||
if(vml_assign_traits<DstXprType,SrcXprNested>::Traversal==LinearTraversal) { \
|
||||
VMLOP(dst.size(), (const VMLTYPE*)src.nestedExpression().data(), \
|
||||
(VMLTYPE*)dst.data() EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_##VMLMODE) ); \
|
||||
} else { \
|
||||
const Index outerSize = dst.outerSize(); \
|
||||
for(Index outer = 0; outer < outerSize; ++outer) { \
|
||||
const EIGENTYPE *src_ptr = src.IsRowMajor ? &(src.nestedExpression().coeffRef(outer,0)) : \
|
||||
&(src.nestedExpression().coeffRef(0, outer)); \
|
||||
EIGENTYPE *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer,0)) : &(dst.coeffRef(0, outer)); \
|
||||
VMLOP( dst.innerSize(), (const VMLTYPE*)src_ptr, \
|
||||
(VMLTYPE*)dst_ptr EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_##VMLMODE)); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
}; \
|
||||
|
||||
|
||||
#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP, VMLMODE) \
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, EIGEN_CAT(EIGEN_VMLMODE_PREFIX(VMLMODE),s##VMLOP), float, float, VMLMODE) \
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, EIGEN_CAT(EIGEN_VMLMODE_PREFIX(VMLMODE),d##VMLOP), double, double, VMLMODE)
|
||||
|
||||
#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_CPLX(EIGENOP, VMLOP, VMLMODE) \
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, EIGEN_CAT(EIGEN_VMLMODE_PREFIX(VMLMODE),c##VMLOP), scomplex, MKL_Complex8, VMLMODE) \
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, EIGEN_CAT(EIGEN_VMLMODE_PREFIX(VMLMODE),z##VMLOP), dcomplex, MKL_Complex16, VMLMODE)
|
||||
|
||||
#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS(EIGENOP, VMLOP, VMLMODE) \
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP, VMLMODE) \
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_CPLX(EIGENOP, VMLOP, VMLMODE)
|
||||
|
||||
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(sin, Sin, LA)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(asin, Asin, LA)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(sinh, Sinh, LA)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(cos, Cos, LA)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(acos, Acos, LA)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(cosh, Cosh, LA)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(tan, Tan, LA)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(atan, Atan, LA)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(tanh, Tanh, LA)
|
||||
// EIGEN_MKL_VML_DECLARE_UNARY_CALLS(abs, Abs, _)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(exp, Exp, LA)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(log, Ln, LA)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(log10, Log10, LA)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS(sqrt, Sqrt, _)
|
||||
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr, _)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_CPLX(arg, Arg, _)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(round, Round, _)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(floor, Floor, _)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(ceil, Ceil, _)
|
||||
|
||||
#define EIGEN_MKL_VML_DECLARE_POW_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE, VMLMODE) \
|
||||
template< typename DstXprType, typename SrcXprNested> \
|
||||
struct Assignment<DstXprType, CwiseUnaryOp<scalar_##EIGENOP##_op<EIGENTYPE>, SrcXprNested>, assign_op<EIGENTYPE>, \
|
||||
Dense2Dense, typename enable_if<vml_assign_traits<DstXprType,SrcXprNested>::EnableVml,EIGENTYPE>::type> { \
|
||||
typedef CwiseUnaryOp<scalar_##EIGENOP##_op<EIGENTYPE>, SrcXprNested> SrcXprType; \
|
||||
static void run(DstXprType &dst, const SrcXprType &src, const assign_op<EIGENTYPE> &/*func*/) { \
|
||||
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); \
|
||||
VMLTYPE exponent = reinterpret_cast<const VMLTYPE&>(src.functor().m_exponent); \
|
||||
if(vml_assign_traits<DstXprType,SrcXprNested>::Traversal==LinearTraversal) \
|
||||
{ \
|
||||
VMLOP( dst.size(), (const VMLTYPE*)src.nestedExpression().data(), exponent, \
|
||||
(VMLTYPE*)dst.data() EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_##VMLMODE) ); \
|
||||
} else { \
|
||||
const Index outerSize = dst.outerSize(); \
|
||||
for(Index outer = 0; outer < outerSize; ++outer) { \
|
||||
const EIGENTYPE *src_ptr = src.IsRowMajor ? &(src.nestedExpression().coeffRef(outer,0)) : \
|
||||
&(src.nestedExpression().coeffRef(0, outer)); \
|
||||
EIGENTYPE *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer,0)) : &(dst.coeffRef(0, outer)); \
|
||||
VMLOP( dst.innerSize(), (const VMLTYPE*)src_ptr, exponent, \
|
||||
(VMLTYPE*)dst_ptr EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_##VMLMODE)); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
};
|
||||
|
||||
#define EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE) \
|
||||
template<> struct vml_call< scalar_##EIGENOP##_op<EIGENTYPE> > { \
|
||||
enum { IsSupported = 1 }; \
|
||||
static inline void run( const scalar_##EIGENOP##_op<EIGENTYPE>& /*func*/, \
|
||||
int size, const EIGENTYPE* src, EIGENTYPE* dst) { \
|
||||
MKL_INT64 vmlMode = EIGEN_MKL_VML_MODE; \
|
||||
VMLOP(size, (const VMLTYPE*)src, (VMLTYPE*)dst, vmlMode); \
|
||||
} \
|
||||
};
|
||||
|
||||
#define EIGEN_MKL_VML_DECLARE_POW_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE) \
|
||||
template<> struct vml_call< scalar_##EIGENOP##_op<EIGENTYPE> > { \
|
||||
enum { IsSupported = 1 }; \
|
||||
static inline void run( const scalar_##EIGENOP##_op<EIGENTYPE>& func, \
|
||||
int size, const EIGENTYPE* src, EIGENTYPE* dst) { \
|
||||
EIGENTYPE exponent = func.m_exponent; \
|
||||
MKL_INT64 vmlMode = EIGEN_MKL_VML_MODE; \
|
||||
VMLOP(&size, (const VMLTYPE*)src, (const VMLTYPE*)&exponent, \
|
||||
(VMLTYPE*)dst, &vmlMode); \
|
||||
} \
|
||||
};
|
||||
|
||||
#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP) \
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vs##VMLOP, float, float) \
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vd##VMLOP, double, double)
|
||||
|
||||
#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX(EIGENOP, VMLOP) \
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vc##VMLOP, scomplex, MKL_Complex8) \
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vz##VMLOP, dcomplex, MKL_Complex16)
|
||||
|
||||
#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS(EIGENOP, VMLOP) \
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP) \
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX(EIGENOP, VMLOP)
|
||||
|
||||
|
||||
#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL_LA(EIGENOP, VMLOP) \
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vms##VMLOP, float, float) \
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vmd##VMLOP, double, double)
|
||||
|
||||
#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX_LA(EIGENOP, VMLOP) \
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vmc##VMLOP, scomplex, MKL_Complex8) \
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vmz##VMLOP, dcomplex, MKL_Complex16)
|
||||
|
||||
#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(EIGENOP, VMLOP) \
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL_LA(EIGENOP, VMLOP) \
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX_LA(EIGENOP, VMLOP)
|
||||
|
||||
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sin, Sin)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(asin, Asin)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(cos, Cos)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(acos, Acos)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(tan, Tan)
|
||||
//EIGEN_MKL_VML_DECLARE_UNARY_CALLS(abs, Abs)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(exp, Exp)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(log, Ln)
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sqrt, Sqrt)
|
||||
|
||||
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr)
|
||||
|
||||
// The vm*powx functions are not avaibale in the windows version of MKL.
|
||||
#ifndef _WIN32
|
||||
EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmspowx_, float, float)
|
||||
EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmdpowx_, double, double)
|
||||
EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmcpowx_, scomplex, MKL_Complex8)
|
||||
EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmzpowx_, dcomplex, MKL_Complex16)
|
||||
#endif
|
||||
|
||||
EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmsPowx, float, float, LA)
|
||||
EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmdPowx, double, double, LA)
|
||||
EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmcPowx, scomplex, MKL_Complex8, LA)
|
||||
EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmzPowx, dcomplex, MKL_Complex16, LA)
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ class BandMatrixBase : public EigenBase<Derived>
|
||||
};
|
||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||
typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> DenseMatrixType;
|
||||
typedef typename DenseMatrixType::Index Index;
|
||||
typedef typename DenseMatrixType::StorageIndex StorageIndex;
|
||||
typedef typename internal::traits<Derived>::CoefficientsType CoefficientsType;
|
||||
typedef EigenBase<Derived> Base;
|
||||
|
||||
@@ -179,7 +179,7 @@ struct traits<BandMatrix<_Scalar,_Rows,_Cols,_Supers,_Subs,_Options> >
|
||||
{
|
||||
typedef _Scalar Scalar;
|
||||
typedef Dense StorageKind;
|
||||
typedef DenseIndex Index;
|
||||
typedef Eigen::Index StorageIndex;
|
||||
enum {
|
||||
CoeffReadCost = NumTraits<Scalar>::ReadCost,
|
||||
RowsAtCompileTime = _Rows,
|
||||
@@ -201,10 +201,10 @@ class BandMatrix : public BandMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Sub
|
||||
public:
|
||||
|
||||
typedef typename internal::traits<BandMatrix>::Scalar Scalar;
|
||||
typedef typename internal::traits<BandMatrix>::Index Index;
|
||||
typedef typename internal::traits<BandMatrix>::StorageIndex StorageIndex;
|
||||
typedef typename internal::traits<BandMatrix>::CoefficientsType CoefficientsType;
|
||||
|
||||
inline BandMatrix(Index rows=Rows, Index cols=Cols, Index supers=Supers, Index subs=Subs)
|
||||
explicit inline BandMatrix(Index rows=Rows, Index cols=Cols, Index supers=Supers, Index subs=Subs)
|
||||
: m_coeffs(1+supers+subs,cols),
|
||||
m_rows(rows), m_supers(supers), m_subs(subs)
|
||||
{
|
||||
@@ -241,7 +241,7 @@ struct traits<BandMatrixWrapper<_CoefficientsType,_Rows,_Cols,_Supers,_Subs,_Opt
|
||||
{
|
||||
typedef typename _CoefficientsType::Scalar Scalar;
|
||||
typedef typename _CoefficientsType::StorageKind StorageKind;
|
||||
typedef typename _CoefficientsType::Index Index;
|
||||
typedef typename _CoefficientsType::StorageIndex StorageIndex;
|
||||
enum {
|
||||
CoeffReadCost = internal::traits<_CoefficientsType>::CoeffReadCost,
|
||||
RowsAtCompileTime = _Rows,
|
||||
@@ -264,9 +264,9 @@ class BandMatrixWrapper : public BandMatrixBase<BandMatrixWrapper<_CoefficientsT
|
||||
|
||||
typedef typename internal::traits<BandMatrixWrapper>::Scalar Scalar;
|
||||
typedef typename internal::traits<BandMatrixWrapper>::CoefficientsType CoefficientsType;
|
||||
typedef typename internal::traits<BandMatrixWrapper>::Index Index;
|
||||
typedef typename internal::traits<BandMatrixWrapper>::StorageIndex StorageIndex;
|
||||
|
||||
inline BandMatrixWrapper(const CoefficientsType& coeffs, Index rows=_Rows, Index cols=_Cols, Index supers=_Supers, Index subs=_Subs)
|
||||
explicit inline BandMatrixWrapper(const CoefficientsType& coeffs, Index rows=_Rows, Index cols=_Cols, Index supers=_Supers, Index subs=_Subs)
|
||||
: m_coeffs(coeffs),
|
||||
m_rows(rows), m_supers(supers), m_subs(subs)
|
||||
{
|
||||
@@ -312,9 +312,9 @@ template<typename Scalar, int Size, int Options>
|
||||
class TridiagonalMatrix : public BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor>
|
||||
{
|
||||
typedef BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor> Base;
|
||||
typedef typename Base::Index Index;
|
||||
typedef typename Base::StorageIndex StorageIndex;
|
||||
public:
|
||||
TridiagonalMatrix(Index size = Size) : Base(size,size,Options&SelfAdjoint?0:1,1) {}
|
||||
explicit TridiagonalMatrix(Index size = Size) : Base(size,size,Options&SelfAdjoint?0:1,1) {}
|
||||
|
||||
inline typename Base::template DiagonalIntReturnType<1>::Type super()
|
||||
{ return Base::template diagonal<1>(); }
|
||||
@@ -327,6 +327,25 @@ class TridiagonalMatrix : public BandMatrix<Scalar,Size,Size,Options&SelfAdjoint
|
||||
protected:
|
||||
};
|
||||
|
||||
|
||||
struct BandShape {};
|
||||
|
||||
template<typename _Scalar, int _Rows, int _Cols, int _Supers, int _Subs, int _Options>
|
||||
struct evaluator_traits<BandMatrix<_Scalar,_Rows,_Cols,_Supers,_Subs,_Options> >
|
||||
: public evaluator_traits_base<BandMatrix<_Scalar,_Rows,_Cols,_Supers,_Subs,_Options> >
|
||||
{
|
||||
typedef BandShape Shape;
|
||||
};
|
||||
|
||||
template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options>
|
||||
struct evaluator_traits<BandMatrixWrapper<_CoefficientsType,_Rows,_Cols,_Supers,_Subs,_Options> >
|
||||
: public evaluator_traits_base<BandMatrixWrapper<_CoefficientsType,_Rows,_Cols,_Supers,_Subs,_Options> >
|
||||
{
|
||||
typedef BandShape Shape;
|
||||
};
|
||||
|
||||
template<> struct AssignmentKind<DenseShape,BandShape> { typedef EigenBase2EigenBase Kind; };
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -21,6 +21,9 @@ namespace Eigen {
|
||||
* \param XprType the type of the expression in which we are taking a block
|
||||
* \param BlockRows the number of rows of the block we are taking at compile time (optional)
|
||||
* \param BlockCols the number of columns of the block we are taking at compile time (optional)
|
||||
* \param InnerPanel is true, if the block maps to a set of rows of a row major matrix or
|
||||
* to set of columns of a column major matrix (optional). The parameter allows to determine
|
||||
* at compile time whether aligned access is possible on the block expression.
|
||||
*
|
||||
* This class represents an expression of either a fixed-size or dynamic-size block. It is the return
|
||||
* type of DenseBase::block(Index,Index,Index,Index) and DenseBase::block<int,int>(Index,Index) and
|
||||
@@ -52,7 +55,7 @@ struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel> > : traits<XprTyp
|
||||
typedef typename traits<XprType>::Scalar Scalar;
|
||||
typedef typename traits<XprType>::StorageKind StorageKind;
|
||||
typedef typename traits<XprType>::XprKind XprKind;
|
||||
typedef typename nested<XprType>::type XprTypeNested;
|
||||
typedef typename ref_selector<XprType>::type XprTypeNested;
|
||||
typedef typename remove_reference<XprTypeNested>::type _XprTypeNested;
|
||||
enum{
|
||||
MatrixRows = traits<XprType>::RowsAtCompileTime,
|
||||
@@ -65,6 +68,7 @@ struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel> > : traits<XprTyp
|
||||
MaxColsAtCompileTime = BlockCols==0 ? 0
|
||||
: ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime)
|
||||
: int(traits<XprType>::MaxColsAtCompileTime),
|
||||
|
||||
XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0,
|
||||
IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
|
||||
: (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
|
||||
@@ -77,18 +81,16 @@ struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel> > : traits<XprTyp
|
||||
OuterStrideAtCompileTime = HasSameStorageOrderAsXprType
|
||||
? int(outer_stride_at_compile_time<XprType>::ret)
|
||||
: int(inner_stride_at_compile_time<XprType>::ret),
|
||||
MaskPacketAccessBit = (InnerSize == Dynamic || (InnerSize % packet_traits<Scalar>::size) == 0)
|
||||
&& (InnerStrideAtCompileTime == 1)
|
||||
? PacketAccessBit : 0,
|
||||
MaskAlignedBit = (InnerPanel && (OuterStrideAtCompileTime!=Dynamic) && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % 16) == 0)) ? AlignedBit : 0,
|
||||
FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
|
||||
|
||||
// FIXME, this traits is rather specialized for dense object and it needs to be cleaned further
|
||||
FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
|
||||
FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
|
||||
Flags0 = traits<XprType>::Flags & ( (HereditaryBits & ~RowMajorBit) |
|
||||
DirectAccessBit |
|
||||
MaskPacketAccessBit |
|
||||
MaskAlignedBit),
|
||||
Flags = Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit
|
||||
Flags = (traits<XprType>::Flags & (DirectAccessBit | (InnerPanel?CompressedAccessBit:0))) | FlagsLvalueBit | FlagsRowMajorBit,
|
||||
// FIXME DirectAccessBit should not be handled by expressions
|
||||
//
|
||||
// Alignment is needed by MapBase's assertions
|
||||
// We can sefely set it to false here. Internal alignment errors will be detected by an eigen_internal_assert in the respective evaluator
|
||||
Alignment = 0
|
||||
};
|
||||
};
|
||||
|
||||
@@ -108,9 +110,12 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> class
|
||||
typedef Impl Base;
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(Block)
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
|
||||
|
||||
typedef typename internal::remove_all<XprType>::type NestedExpression;
|
||||
|
||||
/** Column or Row constructor
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Block(XprType& xpr, Index i) : Impl(xpr,i)
|
||||
{
|
||||
eigen_assert( (i>=0) && (
|
||||
@@ -120,25 +125,27 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> class
|
||||
|
||||
/** Fixed-size constructor
|
||||
*/
|
||||
inline Block(XprType& xpr, Index a_startRow, Index a_startCol)
|
||||
: Impl(xpr, a_startRow, a_startCol)
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Block(XprType& xpr, Index startRow, Index startCol)
|
||||
: Impl(xpr, startRow, startCol)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
|
||||
eigen_assert(a_startRow >= 0 && BlockRows >= 1 && a_startRow + BlockRows <= xpr.rows()
|
||||
&& a_startCol >= 0 && BlockCols >= 1 && a_startCol + BlockCols <= xpr.cols());
|
||||
eigen_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= xpr.rows()
|
||||
&& startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= xpr.cols());
|
||||
}
|
||||
|
||||
/** Dynamic-size constructor
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Block(XprType& xpr,
|
||||
Index a_startRow, Index a_startCol,
|
||||
Index startRow, Index startCol,
|
||||
Index blockRows, Index blockCols)
|
||||
: Impl(xpr, a_startRow, a_startCol, blockRows, blockCols)
|
||||
: Impl(xpr, startRow, startCol, blockRows, blockCols)
|
||||
{
|
||||
eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
|
||||
&& (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
|
||||
eigen_assert(a_startRow >= 0 && blockRows >= 0 && a_startRow <= xpr.rows() - blockRows
|
||||
&& a_startCol >= 0 && blockCols >= 0 && a_startCol <= xpr.cols() - blockCols);
|
||||
eigen_assert(startRow >= 0 && blockRows >= 0 && startRow <= xpr.rows() - blockRows
|
||||
&& startCol >= 0 && blockCols >= 0 && startCol <= xpr.cols() - blockCols);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -149,14 +156,15 @@ class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Dense>
|
||||
: public internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel>
|
||||
{
|
||||
typedef internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> Impl;
|
||||
typedef typename XprType::Index Index;
|
||||
typedef typename XprType::StorageIndex StorageIndex;
|
||||
public:
|
||||
typedef Impl Base;
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
|
||||
inline BlockImpl(XprType& xpr, Index i) : Impl(xpr,i) {}
|
||||
inline BlockImpl(XprType& xpr, Index a_startRow, Index a_startCol) : Impl(xpr, a_startRow, a_startCol) {}
|
||||
inline BlockImpl(XprType& xpr, Index a_startRow, Index a_startCol, Index blockRows, Index blockCols)
|
||||
: Impl(xpr, a_startRow, a_startCol, blockRows, blockCols) {}
|
||||
EIGEN_DEVICE_FUNC inline BlockImpl(XprType& xpr, Index i) : Impl(xpr,i) {}
|
||||
EIGEN_DEVICE_FUNC inline BlockImpl(XprType& xpr, Index startRow, Index startCol) : Impl(xpr, startRow, startCol) {}
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline BlockImpl(XprType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
|
||||
: Impl(xpr, startRow, startCol, blockRows, blockCols) {}
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
@@ -172,10 +180,11 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool H
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)
|
||||
|
||||
class InnerIterator;
|
||||
// class InnerIterator; // FIXME apparently never used
|
||||
|
||||
/** Column or Row constructor
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline BlockImpl_dense(XprType& xpr, Index i)
|
||||
: m_xpr(xpr),
|
||||
// It is a row if and only if BlockRows==1 and BlockCols==XprType::ColsAtCompileTime,
|
||||
@@ -190,23 +199,26 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool H
|
||||
|
||||
/** Fixed-size constructor
|
||||
*/
|
||||
inline BlockImpl_dense(XprType& xpr, Index a_startRow, Index a_startCol)
|
||||
: m_xpr(xpr), m_startRow(a_startRow), m_startCol(a_startCol),
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
|
||||
: m_xpr(xpr), m_startRow(startRow), m_startCol(startCol),
|
||||
m_blockRows(BlockRows), m_blockCols(BlockCols)
|
||||
{}
|
||||
|
||||
/** Dynamic-size constructor
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline BlockImpl_dense(XprType& xpr,
|
||||
Index a_startRow, Index a_startCol,
|
||||
Index startRow, Index startCol,
|
||||
Index blockRows, Index blockCols)
|
||||
: m_xpr(xpr), m_startRow(a_startRow), m_startCol(a_startCol),
|
||||
: m_xpr(xpr), m_startRow(startRow), m_startCol(startCol),
|
||||
m_blockRows(blockRows), m_blockCols(blockCols)
|
||||
{}
|
||||
|
||||
inline Index rows() const { return m_blockRows.value(); }
|
||||
inline Index cols() const { return m_blockCols.value(); }
|
||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_blockRows.value(); }
|
||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_blockCols.value(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Scalar& coeffRef(Index rowId, Index colId)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_LVALUE(XprType)
|
||||
@@ -214,17 +226,20 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool H
|
||||
.coeffRef(rowId + m_startRow.value(), colId + m_startCol.value());
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar& coeffRef(Index rowId, Index colId) const
|
||||
{
|
||||
return m_xpr.derived()
|
||||
.coeffRef(rowId + m_startRow.value(), colId + m_startCol.value());
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const
|
||||
{
|
||||
return m_xpr.coeff(rowId + m_startRow.value(), colId + m_startCol.value());
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Scalar& coeffRef(Index index)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_LVALUE(XprType)
|
||||
@@ -233,6 +248,7 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool H
|
||||
m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar& coeffRef(Index index) const
|
||||
{
|
||||
return m_xpr.const_cast_derived()
|
||||
@@ -240,6 +256,7 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool H
|
||||
m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const CoeffReturnType coeff(Index index) const
|
||||
{
|
||||
return m_xpr
|
||||
@@ -279,22 +296,25 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool H
|
||||
|
||||
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
||||
/** \sa MapBase::data() */
|
||||
inline const Scalar* data() const;
|
||||
inline Index innerStride() const;
|
||||
inline Index outerStride() const;
|
||||
EIGEN_DEVICE_FUNC inline const Scalar* data() const;
|
||||
EIGEN_DEVICE_FUNC inline Index innerStride() const;
|
||||
EIGEN_DEVICE_FUNC inline Index outerStride() const;
|
||||
#endif
|
||||
|
||||
const typename internal::remove_all<typename XprType::Nested>::type& nestedExpression() const
|
||||
EIGEN_DEVICE_FUNC
|
||||
const typename internal::remove_all<typename XprType::Nested>::type& nestedExpression() const
|
||||
{
|
||||
return m_xpr;
|
||||
}
|
||||
|
||||
Index startRow() const
|
||||
EIGEN_DEVICE_FUNC
|
||||
StorageIndex startRow() const
|
||||
{
|
||||
return m_startRow.value();
|
||||
}
|
||||
|
||||
Index startCol() const
|
||||
EIGEN_DEVICE_FUNC
|
||||
StorageIndex startCol() const
|
||||
{
|
||||
return m_startCol.value();
|
||||
}
|
||||
@@ -302,10 +322,10 @@ template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool H
|
||||
protected:
|
||||
|
||||
const typename XprType::Nested m_xpr;
|
||||
const internal::variable_if_dynamic<Index, XprType::RowsAtCompileTime == 1 ? 0 : Dynamic> m_startRow;
|
||||
const internal::variable_if_dynamic<Index, XprType::ColsAtCompileTime == 1 ? 0 : Dynamic> m_startCol;
|
||||
const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_blockRows;
|
||||
const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_blockCols;
|
||||
const internal::variable_if_dynamic<StorageIndex, XprType::RowsAtCompileTime == 1 ? 0 : Dynamic> m_startRow;
|
||||
const internal::variable_if_dynamic<StorageIndex, XprType::ColsAtCompileTime == 1 ? 0 : Dynamic> m_startCol;
|
||||
const internal::variable_if_dynamic<StorageIndex, RowsAtCompileTime> m_blockRows;
|
||||
const internal::variable_if_dynamic<StorageIndex, ColsAtCompileTime> m_blockCols;
|
||||
};
|
||||
|
||||
/** \internal Internal implementation of dense Blocks in the direct access case.*/
|
||||
@@ -314,6 +334,9 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||
: public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel> >
|
||||
{
|
||||
typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
|
||||
enum {
|
||||
XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0
|
||||
};
|
||||
public:
|
||||
|
||||
typedef MapBase<BlockType> Base;
|
||||
@@ -322,10 +345,10 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||
|
||||
/** Column or Row constructor
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline BlockImpl_dense(XprType& xpr, Index i)
|
||||
: Base(internal::const_cast_ptr(&xpr.coeffRef(
|
||||
(BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0,
|
||||
(BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0)),
|
||||
: Base(xpr.data() + i * ( ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor))
|
||||
|| ((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && ( XprTypeIsRowMajor)) ? xpr.innerStride() : xpr.outerStride()),
|
||||
BlockRows==1 ? 1 : xpr.rows(),
|
||||
BlockCols==1 ? 1 : xpr.cols()),
|
||||
m_xpr(xpr)
|
||||
@@ -335,29 +358,34 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||
|
||||
/** Fixed-size constructor
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
|
||||
: Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol))), m_xpr(xpr)
|
||||
: Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol)),
|
||||
m_xpr(xpr)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
/** Dynamic-size constructor
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline BlockImpl_dense(XprType& xpr,
|
||||
Index startRow, Index startCol,
|
||||
Index blockRows, Index blockCols)
|
||||
: Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol)), blockRows, blockCols),
|
||||
: Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol), blockRows, blockCols),
|
||||
m_xpr(xpr)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
const typename internal::remove_all<typename XprType::Nested>::type& nestedExpression() const
|
||||
EIGEN_DEVICE_FUNC
|
||||
const typename internal::remove_all<typename XprType::Nested>::type& nestedExpression() const
|
||||
{
|
||||
return m_xpr;
|
||||
}
|
||||
|
||||
/** \sa MapBase::innerStride() */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index innerStride() const
|
||||
{
|
||||
return internal::traits<BlockType>::HasSameStorageOrderAsXprType
|
||||
@@ -366,6 +394,7 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||
}
|
||||
|
||||
/** \sa MapBase::outerStride() */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index outerStride() const
|
||||
{
|
||||
return m_outerStride;
|
||||
@@ -379,6 +408,7 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
/** \internal used by allowAligned() */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols)
|
||||
: Base(data, blockRows, blockCols), m_xpr(xpr)
|
||||
{
|
||||
@@ -387,6 +417,7 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||
#endif
|
||||
|
||||
protected:
|
||||
EIGEN_DEVICE_FUNC
|
||||
void init()
|
||||
{
|
||||
m_outerStride = internal::traits<BlockType>::HasSameStorageOrderAsXprType
|
||||
|
||||
@@ -17,9 +17,10 @@ namespace internal {
|
||||
template<typename Derived, int UnrollCount>
|
||||
struct all_unroller
|
||||
{
|
||||
typedef typename Derived::ExpressionTraits Traits;
|
||||
enum {
|
||||
col = (UnrollCount-1) / Derived::RowsAtCompileTime,
|
||||
row = (UnrollCount-1) % Derived::RowsAtCompileTime
|
||||
col = (UnrollCount-1) / Traits::RowsAtCompileTime,
|
||||
row = (UnrollCount-1) % Traits::RowsAtCompileTime
|
||||
};
|
||||
|
||||
static inline bool run(const Derived &mat)
|
||||
@@ -29,9 +30,9 @@ struct all_unroller
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
struct all_unroller<Derived, 1>
|
||||
struct all_unroller<Derived, 0>
|
||||
{
|
||||
static inline bool run(const Derived &mat) { return mat.coeff(0, 0); }
|
||||
static inline bool run(const Derived &/*mat*/) { return true; }
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
@@ -43,11 +44,12 @@ struct all_unroller<Derived, Dynamic>
|
||||
template<typename Derived, int UnrollCount>
|
||||
struct any_unroller
|
||||
{
|
||||
typedef typename Derived::ExpressionTraits Traits;
|
||||
enum {
|
||||
col = (UnrollCount-1) / Derived::RowsAtCompileTime,
|
||||
row = (UnrollCount-1) % Derived::RowsAtCompileTime
|
||||
col = (UnrollCount-1) / Traits::RowsAtCompileTime,
|
||||
row = (UnrollCount-1) % Traits::RowsAtCompileTime
|
||||
};
|
||||
|
||||
|
||||
static inline bool run(const Derived &mat)
|
||||
{
|
||||
return any_unroller<Derived, UnrollCount-1>::run(mat) || mat.coeff(row, col);
|
||||
@@ -55,9 +57,9 @@ struct any_unroller
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
struct any_unroller<Derived, 1>
|
||||
struct any_unroller<Derived, 0>
|
||||
{
|
||||
static inline bool run(const Derived &mat) { return mat.coeff(0, 0); }
|
||||
static inline bool run(const Derived & /*mat*/) { return false; }
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
@@ -78,19 +80,21 @@ struct any_unroller<Derived, Dynamic>
|
||||
template<typename Derived>
|
||||
inline bool DenseBase<Derived>::all() const
|
||||
{
|
||||
typedef internal::evaluator<Derived> Evaluator;
|
||||
enum {
|
||||
unroll = SizeAtCompileTime != Dynamic
|
||||
&& CoeffReadCost != Dynamic
|
||||
&& Evaluator::CoeffReadCost != Dynamic
|
||||
&& NumTraits<Scalar>::AddCost != Dynamic
|
||||
&& SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
|
||||
&& SizeAtCompileTime * (Evaluator::CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
|
||||
};
|
||||
Evaluator evaluator(derived());
|
||||
if(unroll)
|
||||
return internal::all_unroller<Derived, unroll ? int(SizeAtCompileTime) : Dynamic>::run(derived());
|
||||
return internal::all_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(evaluator);
|
||||
else
|
||||
{
|
||||
for(Index j = 0; j < cols(); ++j)
|
||||
for(Index i = 0; i < rows(); ++i)
|
||||
if (!coeff(i, j)) return false;
|
||||
if (!evaluator.coeff(i, j)) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -102,19 +106,21 @@ inline bool DenseBase<Derived>::all() const
|
||||
template<typename Derived>
|
||||
inline bool DenseBase<Derived>::any() const
|
||||
{
|
||||
typedef internal::evaluator<Derived> Evaluator;
|
||||
enum {
|
||||
unroll = SizeAtCompileTime != Dynamic
|
||||
&& CoeffReadCost != Dynamic
|
||||
&& Evaluator::CoeffReadCost != Dynamic
|
||||
&& NumTraits<Scalar>::AddCost != Dynamic
|
||||
&& SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
|
||||
&& SizeAtCompileTime * (Evaluator::CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
|
||||
};
|
||||
Evaluator evaluator(derived());
|
||||
if(unroll)
|
||||
return internal::any_unroller<Derived, unroll ? int(SizeAtCompileTime) : Dynamic>::run(derived());
|
||||
return internal::any_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(evaluator);
|
||||
else
|
||||
{
|
||||
for(Index j = 0; j < cols(); ++j)
|
||||
for(Index i = 0; i < rows(); ++i)
|
||||
if (coeff(i, j)) return true;
|
||||
if (evaluator.coeff(i, j)) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -124,14 +130,14 @@ inline bool DenseBase<Derived>::any() const
|
||||
* \sa all(), any()
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline typename DenseBase<Derived>::Index DenseBase<Derived>::count() const
|
||||
inline Eigen::Index DenseBase<Derived>::count() const
|
||||
{
|
||||
return derived().template cast<bool>().template cast<Index>().sum();
|
||||
}
|
||||
|
||||
/** \returns true is \c *this contains at least one Not A Number (NaN).
|
||||
*
|
||||
* \sa isFinite()
|
||||
* \sa allFinite()
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline bool DenseBase<Derived>::hasNaN() const
|
||||
@@ -144,7 +150,7 @@ inline bool DenseBase<Derived>::hasNaN() const
|
||||
* \sa hasNaN()
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline bool DenseBase<Derived>::isFinite() const
|
||||
inline bool DenseBase<Derived>::allFinite() const
|
||||
{
|
||||
return !((derived()-derived()).hasNaN());
|
||||
}
|
||||
|
||||
@@ -8,3 +8,4 @@ INSTALL(FILES
|
||||
ADD_SUBDIRECTORY(products)
|
||||
ADD_SUBDIRECTORY(util)
|
||||
ADD_SUBDIRECTORY(arch)
|
||||
ADD_SUBDIRECTORY(functors)
|
||||
|
||||
@@ -28,8 +28,8 @@ template<typename XprType>
|
||||
struct CommaInitializer
|
||||
{
|
||||
typedef typename XprType::Scalar Scalar;
|
||||
typedef typename XprType::Index Index;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline CommaInitializer(XprType& xpr, const Scalar& s)
|
||||
: m_xpr(xpr), m_row(0), m_col(1), m_currentBlockRows(1)
|
||||
{
|
||||
@@ -37,13 +37,27 @@ struct CommaInitializer
|
||||
}
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline CommaInitializer(XprType& xpr, const DenseBase<OtherDerived>& other)
|
||||
: m_xpr(xpr), m_row(0), m_col(other.cols()), m_currentBlockRows(other.rows())
|
||||
{
|
||||
m_xpr.block(0, 0, other.rows(), other.cols()) = other;
|
||||
}
|
||||
|
||||
/* Copy/Move constructor which transfers ownership. This is crucial in
|
||||
* absence of return value optimization to avoid assertions during destruction. */
|
||||
// FIXME in C++11 mode this could be replaced by a proper RValue constructor
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline CommaInitializer(const CommaInitializer& o)
|
||||
: m_xpr(o.m_xpr), m_row(o.m_row), m_col(o.m_col), m_currentBlockRows(o.m_currentBlockRows) {
|
||||
// Mark original object as finished. In absence of R-value references we need to const_cast:
|
||||
const_cast<CommaInitializer&>(o).m_row = m_xpr.rows();
|
||||
const_cast<CommaInitializer&>(o).m_col = m_xpr.cols();
|
||||
const_cast<CommaInitializer&>(o).m_currentBlockRows = 0;
|
||||
}
|
||||
|
||||
/* inserts a scalar value in the target matrix */
|
||||
EIGEN_DEVICE_FUNC
|
||||
CommaInitializer& operator,(const Scalar& s)
|
||||
{
|
||||
if (m_col==m_xpr.cols())
|
||||
@@ -63,6 +77,7 @@ struct CommaInitializer
|
||||
|
||||
/* inserts a matrix expression in the target matrix */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
CommaInitializer& operator,(const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
if(other.cols()==0 || other.rows()==0)
|
||||
@@ -88,7 +103,11 @@ struct CommaInitializer
|
||||
return *this;
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline ~CommaInitializer()
|
||||
#if defined VERIFY_RAISES_ASSERT && (!defined EIGEN_NO_ASSERTION_CHECKING) && defined EIGEN_EXCEPTIONS
|
||||
throw(Eigen::eigen_assert_exception)
|
||||
#endif
|
||||
{
|
||||
eigen_assert((m_row+m_currentBlockRows) == m_xpr.rows()
|
||||
&& m_col == m_xpr.cols()
|
||||
@@ -102,9 +121,10 @@ struct CommaInitializer
|
||||
* quaternion.fromRotationMatrix((Matrix3f() << axis0, axis1, axis2).finished());
|
||||
* \endcode
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline XprType& finished() { return m_xpr; }
|
||||
|
||||
XprType& m_xpr; // target expression
|
||||
XprType& m_xpr; // target expression
|
||||
Index m_row; // current row id
|
||||
Index m_col; // current col id
|
||||
Index m_currentBlockRows; // current block height
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
// Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
@@ -15,47 +15,113 @@ namespace Eigen {
|
||||
/* This file contains the respective InnerIterator definition of the expressions defined in Eigen/Core
|
||||
*/
|
||||
|
||||
/** \ingroup SparseCore_Module
|
||||
* \class InnerIterator
|
||||
* \brief An InnerIterator allows to loop over the element of a sparse (or dense) matrix or expression
|
||||
*
|
||||
* todo
|
||||
namespace internal {
|
||||
|
||||
template<typename XprType, typename EvaluatorKind>
|
||||
class inner_iterator_selector;
|
||||
|
||||
}
|
||||
|
||||
/** \class InnerIterator
|
||||
* \brief An InnerIterator allows to loop over the element of any matrix expression.
|
||||
*
|
||||
* \warning To be used with care because an evaluator is constructed every time an InnerIterator iterator is constructed.
|
||||
*
|
||||
* TODO: add a usage example
|
||||
*/
|
||||
|
||||
// generic version for dense matrix and expressions
|
||||
template<typename Derived> class DenseBase<Derived>::InnerIterator
|
||||
template<typename XprType>
|
||||
class InnerIterator
|
||||
{
|
||||
protected:
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
typedef typename Derived::Index Index;
|
||||
|
||||
enum { IsRowMajor = (Derived::Flags&RowMajorBit)==RowMajorBit };
|
||||
public:
|
||||
EIGEN_STRONG_INLINE InnerIterator(const Derived& expr, Index outer)
|
||||
: m_expression(expr), m_inner(0), m_outer(outer), m_end(expr.innerSize())
|
||||
{}
|
||||
|
||||
EIGEN_STRONG_INLINE Scalar value() const
|
||||
{
|
||||
return (IsRowMajor) ? m_expression.coeff(m_outer, m_inner)
|
||||
: m_expression.coeff(m_inner, m_outer);
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE InnerIterator& operator++() { m_inner++; return *this; }
|
||||
|
||||
EIGEN_STRONG_INLINE Index index() const { return m_inner; }
|
||||
inline Index row() const { return IsRowMajor ? m_outer : index(); }
|
||||
inline Index col() const { return IsRowMajor ? index() : m_outer; }
|
||||
|
||||
EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; }
|
||||
|
||||
protected:
|
||||
const Derived& m_expression;
|
||||
Index m_inner;
|
||||
const Index m_outer;
|
||||
const Index m_end;
|
||||
protected:
|
||||
typedef internal::inner_iterator_selector<XprType, typename internal::evaluator_traits<XprType>::Kind> IteratorType;
|
||||
typedef internal::evaluator<XprType> EvaluatorType;
|
||||
typedef typename internal::traits<XprType>::Scalar Scalar;
|
||||
public:
|
||||
/** Construct an iterator over the \a outerId -th row or column of \a xpr */
|
||||
InnerIterator(const XprType &xpr, const Index &outerId)
|
||||
: m_eval(xpr), m_iter(m_eval, outerId, xpr.innerSize())
|
||||
{}
|
||||
|
||||
/// \returns the value of the current coefficient.
|
||||
EIGEN_STRONG_INLINE Scalar value() const { return m_iter.value(); }
|
||||
/** Increment the iterator \c *this to the next non-zero coefficient.
|
||||
* Explicit zeros are not skipped over. To skip explicit zeros, see class SparseView
|
||||
*/
|
||||
EIGEN_STRONG_INLINE InnerIterator& operator++() { m_iter.operator++(); return *this; }
|
||||
/// \returns the column or row index of the current coefficient.
|
||||
EIGEN_STRONG_INLINE Index index() const { return m_iter.index(); }
|
||||
/// \returns the row index of the current coefficient.
|
||||
EIGEN_STRONG_INLINE Index row() const { return m_iter.row(); }
|
||||
/// \returns the column index of the current coefficient.
|
||||
EIGEN_STRONG_INLINE Index col() const { return m_iter.col(); }
|
||||
/// \returns \c true if the iterator \c *this still references a valid coefficient.
|
||||
EIGEN_STRONG_INLINE operator bool() const { return m_iter; }
|
||||
|
||||
protected:
|
||||
EvaluatorType m_eval;
|
||||
IteratorType m_iter;
|
||||
private:
|
||||
// If you get here, then you're not using the right InnerIterator type, e.g.:
|
||||
// SparseMatrix<double,RowMajor> A;
|
||||
// SparseMatrix<double>::InnerIterator it(A,0);
|
||||
template<typename T> InnerIterator(const EigenBase<T>&,Index outer);
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Generic inner iterator implementation for dense objects
|
||||
template<typename XprType>
|
||||
class inner_iterator_selector<XprType, IndexBased>
|
||||
{
|
||||
protected:
|
||||
typedef evaluator<XprType> EvaluatorType;
|
||||
typedef typename traits<XprType>::Scalar Scalar;
|
||||
enum { IsRowMajor = (XprType::Flags&RowMajorBit)==RowMajorBit };
|
||||
|
||||
public:
|
||||
EIGEN_STRONG_INLINE inner_iterator_selector(const EvaluatorType &eval, const Index &outerId, const Index &innerSize)
|
||||
: m_eval(eval), m_inner(0), m_outer(outerId), m_end(innerSize)
|
||||
{}
|
||||
|
||||
EIGEN_STRONG_INLINE Scalar value() const
|
||||
{
|
||||
return (IsRowMajor) ? m_eval.coeff(m_outer, m_inner)
|
||||
: m_eval.coeff(m_inner, m_outer);
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE inner_iterator_selector& operator++() { m_inner++; return *this; }
|
||||
|
||||
EIGEN_STRONG_INLINE Index index() const { return m_inner; }
|
||||
inline Index row() const { return IsRowMajor ? m_outer : index(); }
|
||||
inline Index col() const { return IsRowMajor ? index() : m_outer; }
|
||||
|
||||
EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; }
|
||||
|
||||
protected:
|
||||
const EvaluatorType& m_eval;
|
||||
Index m_inner;
|
||||
const Index m_outer;
|
||||
const Index m_end;
|
||||
};
|
||||
|
||||
// For iterator-based evaluator, inner-iterator is already implemented as
|
||||
// evaluator<>::InnerIterator
|
||||
template<typename XprType>
|
||||
class inner_iterator_selector<XprType, IteratorBased>
|
||||
: public evaluator<XprType>::InnerIterator
|
||||
{
|
||||
protected:
|
||||
typedef typename evaluator<XprType>::InnerIterator Base;
|
||||
typedef evaluator<XprType> EvaluatorType;
|
||||
|
||||
public:
|
||||
EIGEN_STRONG_INLINE inner_iterator_selector(const EvaluatorType &eval, const Index &outerId, const Index &/*innerSize*/)
|
||||
: Base(eval, outerId)
|
||||
{}
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_COREITERATORS_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
// Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
@@ -56,72 +56,51 @@ struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
|
||||
typename Rhs::Scalar
|
||||
)
|
||||
>::type Scalar;
|
||||
typedef typename promote_storage_type<typename traits<Lhs>::StorageKind,
|
||||
typename traits<Rhs>::StorageKind>::ret StorageKind;
|
||||
typedef typename promote_index_type<typename traits<Lhs>::Index,
|
||||
typename traits<Rhs>::Index>::type Index;
|
||||
typedef typename cwise_promote_storage_type<typename traits<Lhs>::StorageKind,
|
||||
typename traits<Rhs>::StorageKind,
|
||||
BinaryOp>::ret StorageKind;
|
||||
typedef typename promote_index_type<typename traits<Lhs>::StorageIndex,
|
||||
typename traits<Rhs>::StorageIndex>::type StorageIndex;
|
||||
typedef typename Lhs::Nested LhsNested;
|
||||
typedef typename Rhs::Nested RhsNested;
|
||||
typedef typename remove_reference<LhsNested>::type _LhsNested;
|
||||
typedef typename remove_reference<RhsNested>::type _RhsNested;
|
||||
enum {
|
||||
LhsCoeffReadCost = _LhsNested::CoeffReadCost,
|
||||
RhsCoeffReadCost = _RhsNested::CoeffReadCost,
|
||||
LhsFlags = _LhsNested::Flags,
|
||||
RhsFlags = _RhsNested::Flags,
|
||||
SameType = is_same<typename _LhsNested::Scalar,typename _RhsNested::Scalar>::value,
|
||||
StorageOrdersAgree = (int(Lhs::Flags)&RowMajorBit)==(int(Rhs::Flags)&RowMajorBit),
|
||||
Flags0 = (int(LhsFlags) | int(RhsFlags)) & (
|
||||
HereditaryBits
|
||||
| (int(LhsFlags) & int(RhsFlags) &
|
||||
( AlignedBit
|
||||
| (StorageOrdersAgree ? LinearAccessBit : 0)
|
||||
| (functor_traits<BinaryOp>::PacketAccess && StorageOrdersAgree && SameType ? PacketAccessBit : 0)
|
||||
)
|
||||
)
|
||||
),
|
||||
Flags = (Flags0 & ~RowMajorBit) | (LhsFlags & RowMajorBit),
|
||||
CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + functor_traits<BinaryOp>::Cost
|
||||
Flags = _LhsNested::Flags & RowMajorBit
|
||||
};
|
||||
};
|
||||
} // end namespace internal
|
||||
|
||||
// we require Lhs and Rhs to have the same scalar type. Currently there is no example of a binary functor
|
||||
// that would take two operands of different types. If there were such an example, then this check should be
|
||||
// moved to the BinaryOp functors, on a per-case basis. This would however require a change in the BinaryOp functors, as
|
||||
// currently they take only one typename Scalar template parameter.
|
||||
// It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths.
|
||||
// So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to
|
||||
// add together a float matrix and a double matrix.
|
||||
#define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \
|
||||
EIGEN_STATIC_ASSERT((internal::functor_is_product_like<BINOP>::ret \
|
||||
? int(internal::scalar_product_traits<LHS, RHS>::Defined) \
|
||||
: int(internal::is_same<LHS, RHS>::value)), \
|
||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||
|
||||
template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind>
|
||||
class CwiseBinaryOpImpl;
|
||||
|
||||
template<typename BinaryOp, typename Lhs, typename Rhs>
|
||||
class CwiseBinaryOp : internal::no_assignment_operator,
|
||||
template<typename BinaryOp, typename LhsType, typename RhsType>
|
||||
class CwiseBinaryOp :
|
||||
public CwiseBinaryOpImpl<
|
||||
BinaryOp, Lhs, Rhs,
|
||||
typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind,
|
||||
typename internal::traits<Rhs>::StorageKind>::ret>
|
||||
BinaryOp, LhsType, RhsType,
|
||||
typename internal::cwise_promote_storage_type<typename internal::traits<LhsType>::StorageKind,
|
||||
typename internal::traits<RhsType>::StorageKind,
|
||||
BinaryOp>::ret>,
|
||||
internal::no_assignment_operator
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename internal::remove_all<LhsType>::type Lhs;
|
||||
typedef typename internal::remove_all<RhsType>::type Rhs;
|
||||
|
||||
typedef typename CwiseBinaryOpImpl<
|
||||
BinaryOp, Lhs, Rhs,
|
||||
typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind,
|
||||
typename internal::traits<Rhs>::StorageKind>::ret>::Base Base;
|
||||
BinaryOp, LhsType, RhsType,
|
||||
typename internal::cwise_promote_storage_type<typename internal::traits<LhsType>::StorageKind,
|
||||
typename internal::traits<Rhs>::StorageKind,
|
||||
BinaryOp>::ret>::Base Base;
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp)
|
||||
|
||||
typedef typename internal::nested<Lhs>::type LhsNested;
|
||||
typedef typename internal::nested<Rhs>::type RhsNested;
|
||||
typedef typename internal::ref_selector<LhsType>::type LhsNested;
|
||||
typedef typename internal::ref_selector<RhsType>::type RhsNested;
|
||||
typedef typename internal::remove_reference<LhsNested>::type _LhsNested;
|
||||
typedef typename internal::remove_reference<RhsNested>::type _RhsNested;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& aLhs, const Rhs& aRhs, const BinaryOp& func = BinaryOp())
|
||||
: m_lhs(aLhs), m_rhs(aRhs), m_functor(func)
|
||||
{
|
||||
@@ -131,6 +110,7 @@ class CwiseBinaryOp : internal::no_assignment_operator,
|
||||
eigen_assert(aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols());
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index rows() const {
|
||||
// return the fixed size type if available to enable compile time optimizations
|
||||
if (internal::traits<typename internal::remove_all<LhsNested>::type>::RowsAtCompileTime==Dynamic)
|
||||
@@ -138,6 +118,7 @@ class CwiseBinaryOp : internal::no_assignment_operator,
|
||||
else
|
||||
return m_lhs.rows();
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index cols() const {
|
||||
// return the fixed size type if available to enable compile time optimizations
|
||||
if (internal::traits<typename internal::remove_all<LhsNested>::type>::ColsAtCompileTime==Dynamic)
|
||||
@@ -147,10 +128,13 @@ class CwiseBinaryOp : internal::no_assignment_operator,
|
||||
}
|
||||
|
||||
/** \returns the left hand side nested expression */
|
||||
EIGEN_DEVICE_FUNC
|
||||
const _LhsNested& lhs() const { return m_lhs; }
|
||||
/** \returns the right hand side nested expression */
|
||||
EIGEN_DEVICE_FUNC
|
||||
const _RhsNested& rhs() const { return m_rhs; }
|
||||
/** \returns the functor representing the binary operation */
|
||||
EIGEN_DEVICE_FUNC
|
||||
const BinaryOp& functor() const { return m_functor; }
|
||||
|
||||
protected:
|
||||
@@ -159,41 +143,13 @@ class CwiseBinaryOp : internal::no_assignment_operator,
|
||||
const BinaryOp m_functor;
|
||||
};
|
||||
|
||||
template<typename BinaryOp, typename Lhs, typename Rhs>
|
||||
class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Dense>
|
||||
: public internal::dense_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type
|
||||
// Generic API dispatcher
|
||||
template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind>
|
||||
class CwiseBinaryOpImpl
|
||||
: public internal::generic_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type
|
||||
{
|
||||
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived;
|
||||
public:
|
||||
|
||||
typedef typename internal::dense_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE( Derived )
|
||||
|
||||
EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const
|
||||
{
|
||||
return derived().functor()(derived().lhs().coeff(rowId, colId),
|
||||
derived().rhs().coeff(rowId, colId));
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
|
||||
{
|
||||
return derived().functor().packetOp(derived().lhs().template packet<LoadMode>(rowId, colId),
|
||||
derived().rhs().template packet<LoadMode>(rowId, colId));
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
|
||||
{
|
||||
return derived().functor()(derived().lhs().coeff(index),
|
||||
derived().rhs().coeff(index));
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
|
||||
{
|
||||
return derived().functor().packetOp(derived().lhs().template packet<LoadMode>(index),
|
||||
derived().rhs().template packet<LoadMode>(index));
|
||||
}
|
||||
public:
|
||||
typedef typename internal::generic_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type Base;
|
||||
};
|
||||
|
||||
/** replaces \c *this by \c *this - \a other.
|
||||
@@ -205,8 +161,7 @@ template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE Derived &
|
||||
MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other)
|
||||
{
|
||||
SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, Derived, OtherDerived> tmp(derived());
|
||||
tmp = other.derived();
|
||||
call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar>());
|
||||
return derived();
|
||||
}
|
||||
|
||||
@@ -219,11 +174,11 @@ template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE Derived &
|
||||
MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
|
||||
{
|
||||
SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, Derived, OtherDerived> tmp(derived());
|
||||
tmp = other.derived();
|
||||
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar>());
|
||||
return derived();
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_CWISE_BINARY_OP_H
|
||||
|
||||
|
||||
@@ -35,37 +35,35 @@ template<typename NullaryOp, typename PlainObjectType>
|
||||
struct traits<CwiseNullaryOp<NullaryOp, PlainObjectType> > : traits<PlainObjectType>
|
||||
{
|
||||
enum {
|
||||
Flags = (traits<PlainObjectType>::Flags
|
||||
& ( HereditaryBits
|
||||
| (functor_has_linear_access<NullaryOp>::ret ? LinearAccessBit : 0)
|
||||
| (functor_traits<NullaryOp>::PacketAccess ? PacketAccessBit : 0)))
|
||||
| (functor_traits<NullaryOp>::IsRepeatable ? 0 : EvalBeforeNestingBit),
|
||||
CoeffReadCost = functor_traits<NullaryOp>::Cost
|
||||
Flags = traits<PlainObjectType>::Flags & RowMajorBit
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
template<typename NullaryOp, typename PlainObjectType>
|
||||
class CwiseNullaryOp : internal::no_assignment_operator,
|
||||
public internal::dense_xpr_base< CwiseNullaryOp<NullaryOp, PlainObjectType> >::type
|
||||
class CwiseNullaryOp : public internal::dense_xpr_base< CwiseNullaryOp<NullaryOp, PlainObjectType> >::type, internal::no_assignment_operator
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename internal::dense_xpr_base<CwiseNullaryOp>::type Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(CwiseNullaryOp)
|
||||
|
||||
CwiseNullaryOp(Index nbRows, Index nbCols, const NullaryOp& func = NullaryOp())
|
||||
: m_rows(nbRows), m_cols(nbCols), m_functor(func)
|
||||
EIGEN_DEVICE_FUNC
|
||||
CwiseNullaryOp(Index rows, Index cols, const NullaryOp& func = NullaryOp())
|
||||
: m_rows(rows), m_cols(cols), m_functor(func)
|
||||
{
|
||||
eigen_assert(nbRows >= 0
|
||||
&& (RowsAtCompileTime == Dynamic || RowsAtCompileTime == nbRows)
|
||||
&& nbCols >= 0
|
||||
&& (ColsAtCompileTime == Dynamic || ColsAtCompileTime == nbCols));
|
||||
eigen_assert(rows >= 0
|
||||
&& (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
|
||||
&& cols >= 0
|
||||
&& (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index rows() const { return m_rows.value(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index cols() const { return m_cols.value(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const
|
||||
{
|
||||
return m_functor(rowId, colId);
|
||||
@@ -77,6 +75,7 @@ class CwiseNullaryOp : internal::no_assignment_operator,
|
||||
return m_functor.packetOp(rowId, colId);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
|
||||
{
|
||||
return m_functor(index);
|
||||
@@ -89,6 +88,7 @@ class CwiseNullaryOp : internal::no_assignment_operator,
|
||||
}
|
||||
|
||||
/** \returns the functor representing the nullary operation */
|
||||
EIGEN_DEVICE_FUNC
|
||||
const NullaryOp& functor() const { return m_functor; }
|
||||
|
||||
protected:
|
||||
@@ -113,10 +113,10 @@ class CwiseNullaryOp : internal::no_assignment_operator,
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename CustomNullaryOp>
|
||||
EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived>
|
||||
EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
|
||||
DenseBase<Derived>::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func)
|
||||
{
|
||||
return CwiseNullaryOp<CustomNullaryOp, Derived>(rows, cols, func);
|
||||
return CwiseNullaryOp<CustomNullaryOp, PlainObject>(rows, cols, func);
|
||||
}
|
||||
|
||||
/** \returns an expression of a matrix defined by a custom functor \a func
|
||||
@@ -132,16 +132,19 @@ DenseBase<Derived>::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& f
|
||||
*
|
||||
* The template parameter \a CustomNullaryOp is the type of the functor.
|
||||
*
|
||||
* Here is an example with C++11 random generators: \include random_cpp11.cpp
|
||||
* Output: \verbinclude random_cpp11.out
|
||||
*
|
||||
* \sa class CwiseNullaryOp
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename CustomNullaryOp>
|
||||
EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived>
|
||||
EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
|
||||
DenseBase<Derived>::NullaryExpr(Index size, const CustomNullaryOp& func)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
if(RowsAtCompileTime == 1) return CwiseNullaryOp<CustomNullaryOp, Derived>(1, size, func);
|
||||
else return CwiseNullaryOp<CustomNullaryOp, Derived>(size, 1, func);
|
||||
if(RowsAtCompileTime == 1) return CwiseNullaryOp<CustomNullaryOp, PlainObject>(1, size, func);
|
||||
else return CwiseNullaryOp<CustomNullaryOp, PlainObject>(size, 1, func);
|
||||
}
|
||||
|
||||
/** \returns an expression of a matrix defined by a custom functor \a func
|
||||
@@ -155,19 +158,19 @@ DenseBase<Derived>::NullaryExpr(Index size, const CustomNullaryOp& func)
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename CustomNullaryOp>
|
||||
EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived>
|
||||
EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
|
||||
DenseBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
|
||||
{
|
||||
return CwiseNullaryOp<CustomNullaryOp, Derived>(RowsAtCompileTime, ColsAtCompileTime, func);
|
||||
return CwiseNullaryOp<CustomNullaryOp, PlainObject>(RowsAtCompileTime, ColsAtCompileTime, func);
|
||||
}
|
||||
|
||||
/** \returns an expression of a constant matrix of value \a value
|
||||
*
|
||||
* The parameters \a nbRows and \a nbCols are the number of rows and of columns of
|
||||
* The parameters \a rows and \a cols are the number of rows and of columns of
|
||||
* the returned matrix. Must be compatible with this DenseBase type.
|
||||
*
|
||||
* This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
|
||||
* it is redundant to pass \a nbRows and \a nbCols as arguments, so Zero() should be used
|
||||
* it is redundant to pass \a rows and \a cols as arguments, so Zero() should be used
|
||||
* instead.
|
||||
*
|
||||
* The template parameter \a CustomNullaryOp is the type of the functor.
|
||||
@@ -176,9 +179,9 @@ DenseBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||
DenseBase<Derived>::Constant(Index nbRows, Index nbCols, const Scalar& value)
|
||||
DenseBase<Derived>::Constant(Index rows, Index cols, const Scalar& value)
|
||||
{
|
||||
return DenseBase<Derived>::NullaryExpr(nbRows, nbCols, internal::scalar_constant_op<Scalar>(value));
|
||||
return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_constant_op<Scalar>(value));
|
||||
}
|
||||
|
||||
/** \returns an expression of a constant matrix of value \a value
|
||||
@@ -242,7 +245,7 @@ EIGEN_STRONG_INLINE const typename DenseBase<Derived>::SequentialLinSpacedReturn
|
||||
DenseBase<Derived>::LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,false>(low,high,size));
|
||||
return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,PacketScalar,false>(low,high,size));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -255,7 +258,7 @@ DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& hig
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
||||
return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,false>(low,high,Derived::SizeAtCompileTime));
|
||||
return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,PacketScalar,false>(low,high,Derived::SizeAtCompileTime));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -276,7 +279,7 @@ EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedRetu
|
||||
DenseBase<Derived>::LinSpaced(Index size, const Scalar& low, const Scalar& high)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,true>(low,high,size));
|
||||
return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,PacketScalar,true>(low,high,size));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,7 +292,7 @@ DenseBase<Derived>::LinSpaced(const Scalar& low, const Scalar& high)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
||||
return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,true>(low,high,Derived::SizeAtCompileTime));
|
||||
return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,PacketScalar,true>(low,high,Derived::SizeAtCompileTime));
|
||||
}
|
||||
|
||||
/** \returns true if all coefficients in this matrix are approximately equal to \a val, to within precision \a prec */
|
||||
@@ -297,9 +300,10 @@ template<typename Derived>
|
||||
bool DenseBase<Derived>::isApproxToConstant
|
||||
(const Scalar& val, const RealScalar& prec) const
|
||||
{
|
||||
typename internal::nested_eval<Derived,1>::type self(derived());
|
||||
for(Index j = 0; j < cols(); ++j)
|
||||
for(Index i = 0; i < rows(); ++i)
|
||||
if(!internal::isApprox(this->coeff(i, j), val, prec))
|
||||
if(!internal::isApprox(self.coeff(i, j), val, prec))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@@ -353,8 +357,8 @@ PlainObjectBase<Derived>::setConstant(Index size, const Scalar& val)
|
||||
|
||||
/** Resizes to the given size, and sets all coefficients in this expression to the given \a value.
|
||||
*
|
||||
* \param nbRows the new number of rows
|
||||
* \param nbCols the new number of columns
|
||||
* \param rows the new number of rows
|
||||
* \param cols the new number of columns
|
||||
* \param val the value to which all coefficients are set
|
||||
*
|
||||
* Example: \include Matrix_setConstant_int_int.cpp
|
||||
@@ -364,9 +368,9 @@ PlainObjectBase<Derived>::setConstant(Index size, const Scalar& val)
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived&
|
||||
PlainObjectBase<Derived>::setConstant(Index nbRows, Index nbCols, const Scalar& val)
|
||||
PlainObjectBase<Derived>::setConstant(Index rows, Index cols, const Scalar& val)
|
||||
{
|
||||
resize(nbRows, nbCols);
|
||||
resize(rows, cols);
|
||||
return setConstant(val);
|
||||
}
|
||||
|
||||
@@ -387,7 +391,7 @@ template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index newSize, const Scalar& low, const Scalar& high)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
return derived() = Derived::NullaryExpr(newSize, internal::linspaced_op<Scalar,false>(low,high,newSize));
|
||||
return derived() = Derived::NullaryExpr(newSize, internal::linspaced_op<Scalar,PacketScalar,false>(low,high,newSize));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -425,9 +429,9 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(const Scalar& low,
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||
DenseBase<Derived>::Zero(Index nbRows, Index nbCols)
|
||||
DenseBase<Derived>::Zero(Index rows, Index cols)
|
||||
{
|
||||
return Constant(nbRows, nbCols, Scalar(0));
|
||||
return Constant(rows, cols, Scalar(0));
|
||||
}
|
||||
|
||||
/** \returns an expression of a zero vector.
|
||||
@@ -481,9 +485,10 @@ DenseBase<Derived>::Zero()
|
||||
template<typename Derived>
|
||||
bool DenseBase<Derived>::isZero(const RealScalar& prec) const
|
||||
{
|
||||
typename internal::nested_eval<Derived,1>::type self(derived());
|
||||
for(Index j = 0; j < cols(); ++j)
|
||||
for(Index i = 0; i < rows(); ++i)
|
||||
if(!internal::isMuchSmallerThan(this->coeff(i, j), static_cast<Scalar>(1), prec))
|
||||
if(!internal::isMuchSmallerThan(self.coeff(i, j), static_cast<Scalar>(1), prec))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@@ -520,8 +525,8 @@ PlainObjectBase<Derived>::setZero(Index newSize)
|
||||
|
||||
/** Resizes to the given size, and sets all coefficients in this expression to zero.
|
||||
*
|
||||
* \param nbRows the new number of rows
|
||||
* \param nbCols the new number of columns
|
||||
* \param rows the new number of rows
|
||||
* \param cols the new number of columns
|
||||
*
|
||||
* Example: \include Matrix_setZero_int_int.cpp
|
||||
* Output: \verbinclude Matrix_setZero_int_int.out
|
||||
@@ -530,9 +535,9 @@ PlainObjectBase<Derived>::setZero(Index newSize)
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived&
|
||||
PlainObjectBase<Derived>::setZero(Index nbRows, Index nbCols)
|
||||
PlainObjectBase<Derived>::setZero(Index rows, Index cols)
|
||||
{
|
||||
resize(nbRows, nbCols);
|
||||
resize(rows, cols);
|
||||
return setConstant(Scalar(0));
|
||||
}
|
||||
|
||||
@@ -540,7 +545,7 @@ PlainObjectBase<Derived>::setZero(Index nbRows, Index nbCols)
|
||||
|
||||
/** \returns an expression of a matrix where all coefficients equal one.
|
||||
*
|
||||
* The parameters \a nbRows and \a nbCols are the number of rows and of columns of
|
||||
* The parameters \a rows and \a cols are the number of rows and of columns of
|
||||
* the returned matrix. Must be compatible with this MatrixBase type.
|
||||
*
|
||||
* This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
|
||||
@@ -554,9 +559,9 @@ PlainObjectBase<Derived>::setZero(Index nbRows, Index nbCols)
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
|
||||
DenseBase<Derived>::Ones(Index nbRows, Index nbCols)
|
||||
DenseBase<Derived>::Ones(Index rows, Index cols)
|
||||
{
|
||||
return Constant(nbRows, nbCols, Scalar(1));
|
||||
return Constant(rows, cols, Scalar(1));
|
||||
}
|
||||
|
||||
/** \returns an expression of a vector where all coefficients equal one.
|
||||
@@ -646,8 +651,8 @@ PlainObjectBase<Derived>::setOnes(Index newSize)
|
||||
|
||||
/** Resizes to the given size, and sets all coefficients in this expression to one.
|
||||
*
|
||||
* \param nbRows the new number of rows
|
||||
* \param nbCols the new number of columns
|
||||
* \param rows the new number of rows
|
||||
* \param cols the new number of columns
|
||||
*
|
||||
* Example: \include Matrix_setOnes_int_int.cpp
|
||||
* Output: \verbinclude Matrix_setOnes_int_int.out
|
||||
@@ -656,9 +661,9 @@ PlainObjectBase<Derived>::setOnes(Index newSize)
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived&
|
||||
PlainObjectBase<Derived>::setOnes(Index nbRows, Index nbCols)
|
||||
PlainObjectBase<Derived>::setOnes(Index rows, Index cols)
|
||||
{
|
||||
resize(nbRows, nbCols);
|
||||
resize(rows, cols);
|
||||
return setConstant(Scalar(1));
|
||||
}
|
||||
|
||||
@@ -666,7 +671,7 @@ PlainObjectBase<Derived>::setOnes(Index nbRows, Index nbCols)
|
||||
|
||||
/** \returns an expression of the identity matrix (not necessarily square).
|
||||
*
|
||||
* The parameters \a nbRows and \a nbCols are the number of rows and of columns of
|
||||
* The parameters \a rows and \a cols are the number of rows and of columns of
|
||||
* the returned matrix. Must be compatible with this MatrixBase type.
|
||||
*
|
||||
* This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
|
||||
@@ -680,9 +685,9 @@ PlainObjectBase<Derived>::setOnes(Index nbRows, Index nbCols)
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
|
||||
MatrixBase<Derived>::Identity(Index nbRows, Index nbCols)
|
||||
MatrixBase<Derived>::Identity(Index rows, Index cols)
|
||||
{
|
||||
return DenseBase<Derived>::NullaryExpr(nbRows, nbCols, internal::scalar_identity_op<Scalar>());
|
||||
return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_identity_op<Scalar>());
|
||||
}
|
||||
|
||||
/** \returns an expression of the identity matrix (not necessarily square).
|
||||
@@ -716,18 +721,19 @@ template<typename Derived>
|
||||
bool MatrixBase<Derived>::isIdentity
|
||||
(const RealScalar& prec) const
|
||||
{
|
||||
typename internal::nested_eval<Derived,1>::type self(derived());
|
||||
for(Index j = 0; j < cols(); ++j)
|
||||
{
|
||||
for(Index i = 0; i < rows(); ++i)
|
||||
{
|
||||
if(i == j)
|
||||
{
|
||||
if(!internal::isApprox(this->coeff(i, j), static_cast<Scalar>(1), prec))
|
||||
if(!internal::isApprox(self.coeff(i, j), static_cast<Scalar>(1), prec))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!internal::isMuchSmallerThan(this->coeff(i, j), static_cast<RealScalar>(1), prec))
|
||||
if(!internal::isMuchSmallerThan(self.coeff(i, j), static_cast<RealScalar>(1), prec))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -740,6 +746,7 @@ namespace internal {
|
||||
template<typename Derived, bool Big = (Derived::SizeAtCompileTime>=16)>
|
||||
struct setIdentity_impl
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static EIGEN_STRONG_INLINE Derived& run(Derived& m)
|
||||
{
|
||||
return m = Derived::Identity(m.rows(), m.cols());
|
||||
@@ -749,7 +756,7 @@ struct setIdentity_impl
|
||||
template<typename Derived>
|
||||
struct setIdentity_impl<Derived, true>
|
||||
{
|
||||
typedef typename Derived::Index Index;
|
||||
EIGEN_DEVICE_FUNC
|
||||
static EIGEN_STRONG_INLINE Derived& run(Derived& m)
|
||||
{
|
||||
m.setZero();
|
||||
@@ -776,8 +783,8 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity()
|
||||
|
||||
/** \brief Resizes to the given size, and writes the identity expression (not necessarily square) into *this.
|
||||
*
|
||||
* \param nbRows the new number of rows
|
||||
* \param nbCols the new number of columns
|
||||
* \param rows the new number of rows
|
||||
* \param cols the new number of columns
|
||||
*
|
||||
* Example: \include Matrix_setIdentity_int_int.cpp
|
||||
* Output: \verbinclude Matrix_setIdentity_int_int.out
|
||||
@@ -785,9 +792,9 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity()
|
||||
* \sa MatrixBase::setIdentity(), class CwiseNullaryOp, MatrixBase::Identity()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity(Index nbRows, Index nbCols)
|
||||
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity(Index rows, Index cols)
|
||||
{
|
||||
derived().resize(nbRows, nbCols);
|
||||
derived().resize(rows, cols);
|
||||
return setIdentity();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
// Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
@@ -44,10 +44,7 @@ struct traits<CwiseUnaryOp<UnaryOp, XprType> >
|
||||
typedef typename XprType::Nested XprTypeNested;
|
||||
typedef typename remove_reference<XprTypeNested>::type _XprTypeNested;
|
||||
enum {
|
||||
Flags = _XprTypeNested::Flags & (
|
||||
HereditaryBits | LinearAccessBit | AlignedBit
|
||||
| (functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0)),
|
||||
CoeffReadCost = _XprTypeNested::CoeffReadCost + functor_traits<UnaryOp>::Cost
|
||||
Flags = _XprTypeNested::Flags & RowMajorBit
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -56,28 +53,34 @@ template<typename UnaryOp, typename XprType, typename StorageKind>
|
||||
class CwiseUnaryOpImpl;
|
||||
|
||||
template<typename UnaryOp, typename XprType>
|
||||
class CwiseUnaryOp : internal::no_assignment_operator,
|
||||
public CwiseUnaryOpImpl<UnaryOp, XprType, typename internal::traits<XprType>::StorageKind>
|
||||
class CwiseUnaryOp : public CwiseUnaryOpImpl<UnaryOp, XprType, typename internal::traits<XprType>::StorageKind>, internal::no_assignment_operator
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename CwiseUnaryOpImpl<UnaryOp, XprType,typename internal::traits<XprType>::StorageKind>::Base Base;
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryOp)
|
||||
typedef typename internal::remove_all<XprType>::type NestedExpression;
|
||||
|
||||
inline CwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp())
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit inline CwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp())
|
||||
: m_xpr(xpr), m_functor(func) {}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index rows() const { return m_xpr.rows(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index cols() const { return m_xpr.cols(); }
|
||||
|
||||
/** \returns the functor representing the unary operation */
|
||||
EIGEN_DEVICE_FUNC
|
||||
const UnaryOp& functor() const { return m_functor; }
|
||||
|
||||
/** \returns the nested expression */
|
||||
EIGEN_DEVICE_FUNC
|
||||
const typename internal::remove_all<typename XprType::Nested>::type&
|
||||
nestedExpression() const { return m_xpr; }
|
||||
|
||||
/** \returns the nested expression */
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename internal::remove_all<typename XprType::Nested>::type&
|
||||
nestedExpression() { return m_xpr.const_cast_derived(); }
|
||||
|
||||
@@ -86,39 +89,13 @@ class CwiseUnaryOp : internal::no_assignment_operator,
|
||||
const UnaryOp m_functor;
|
||||
};
|
||||
|
||||
// This is the generic implementation for dense storage.
|
||||
// It can be used for any expression types implementing the dense concept.
|
||||
template<typename UnaryOp, typename XprType>
|
||||
class CwiseUnaryOpImpl<UnaryOp,XprType,Dense>
|
||||
: public internal::dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type
|
||||
// Generic API dispatcher
|
||||
template<typename UnaryOp, typename XprType, typename StorageKind>
|
||||
class CwiseUnaryOpImpl
|
||||
: public internal::generic_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type
|
||||
{
|
||||
public:
|
||||
|
||||
typedef CwiseUnaryOp<UnaryOp, XprType> Derived;
|
||||
typedef typename internal::dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
||||
|
||||
EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const
|
||||
{
|
||||
return derived().functor()(derived().nestedExpression().coeff(rowId, colId));
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
|
||||
{
|
||||
return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(rowId, colId));
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
|
||||
{
|
||||
return derived().functor()(derived().nestedExpression().coeff(index));
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
|
||||
{
|
||||
return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(index));
|
||||
}
|
||||
public:
|
||||
typedef typename internal::generic_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base;
|
||||
};
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -37,8 +37,8 @@ struct traits<CwiseUnaryView<ViewOp, MatrixType> >
|
||||
typedef typename MatrixType::Nested MatrixTypeNested;
|
||||
typedef typename remove_all<MatrixTypeNested>::type _MatrixTypeNested;
|
||||
enum {
|
||||
Flags = (traits<_MatrixTypeNested>::Flags & (HereditaryBits | LvalueBit | LinearAccessBit | DirectAccessBit)),
|
||||
CoeffReadCost = traits<_MatrixTypeNested>::CoeffReadCost + functor_traits<ViewOp>::Cost,
|
||||
FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
|
||||
Flags = traits<_MatrixTypeNested>::Flags & (RowMajorBit | FlagsLvalueBit | DirectAccessBit), // FIXME DirectAccessBit should not be handled by expressions
|
||||
MatrixTypeInnerStride = inner_stride_at_compile_time<MatrixType>::ret,
|
||||
// need to cast the sizeof's from size_t to int explicitly, otherwise:
|
||||
// "error: no integral type can represent all of the enumerator values
|
||||
@@ -62,8 +62,9 @@ class CwiseUnaryView : public CwiseUnaryViewImpl<ViewOp, MatrixType, typename in
|
||||
|
||||
typedef typename CwiseUnaryViewImpl<ViewOp, MatrixType,typename internal::traits<MatrixType>::StorageKind>::Base Base;
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryView)
|
||||
typedef typename internal::remove_all<MatrixType>::type NestedExpression;
|
||||
|
||||
inline CwiseUnaryView(const MatrixType& mat, const ViewOp& func = ViewOp())
|
||||
explicit inline CwiseUnaryView(MatrixType& mat, const ViewOp& func = ViewOp())
|
||||
: m_matrix(mat), m_functor(func) {}
|
||||
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryView)
|
||||
@@ -83,11 +84,19 @@ class CwiseUnaryView : public CwiseUnaryViewImpl<ViewOp, MatrixType, typename in
|
||||
nestedExpression() { return m_matrix.const_cast_derived(); }
|
||||
|
||||
protected:
|
||||
// FIXME changed from MatrixType::Nested because of a weird compilation error with sun CC
|
||||
typename internal::nested<MatrixType>::type m_matrix;
|
||||
typename internal::ref_selector<MatrixType>::type m_matrix;
|
||||
ViewOp m_functor;
|
||||
};
|
||||
|
||||
// Generic API dispatcher
|
||||
template<typename ViewOp, typename XprType, typename StorageKind>
|
||||
class CwiseUnaryViewImpl
|
||||
: public internal::generic_xpr_base<CwiseUnaryView<ViewOp, XprType> >::type
|
||||
{
|
||||
public:
|
||||
typedef typename internal::generic_xpr_base<CwiseUnaryView<ViewOp, XprType> >::type Base;
|
||||
};
|
||||
|
||||
template<typename ViewOp, typename MatrixType>
|
||||
class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
|
||||
: public internal::dense_xpr_base< CwiseUnaryView<ViewOp, MatrixType> >::type
|
||||
@@ -100,38 +109,18 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryViewImpl)
|
||||
|
||||
inline Scalar* data() { return &coeffRef(0); }
|
||||
inline const Scalar* data() const { return &coeff(0); }
|
||||
EIGEN_DEVICE_FUNC inline Scalar* data() { return &(this->coeffRef(0)); }
|
||||
EIGEN_DEVICE_FUNC inline const Scalar* data() const { return &(this->coeff(0)); }
|
||||
|
||||
inline Index innerStride() const
|
||||
EIGEN_DEVICE_FUNC inline Index innerStride() const
|
||||
{
|
||||
return derived().nestedExpression().innerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
|
||||
}
|
||||
|
||||
inline Index outerStride() const
|
||||
EIGEN_DEVICE_FUNC inline Index outerStride() const
|
||||
{
|
||||
return derived().nestedExpression().outerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
|
||||
{
|
||||
return derived().functor()(derived().nestedExpression().coeff(row, col));
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
|
||||
{
|
||||
return derived().functor()(derived().nestedExpression().coeff(index));
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
|
||||
{
|
||||
return derived().functor()(const_cast_derived().nestedExpression().coeffRef(row, col));
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
|
||||
{
|
||||
return derived().functor()(const_cast_derived().nestedExpression().coeffRef(index));
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -49,22 +49,37 @@ template<typename Derived> class DenseBase
|
||||
public:
|
||||
using internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
|
||||
typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>::operator*;
|
||||
using internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
|
||||
typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>::operator/;
|
||||
|
||||
class InnerIterator;
|
||||
|
||||
/** Inner iterator type to iterate over the coefficients of a row or column.
|
||||
* \sa class InnerIterator
|
||||
*/
|
||||
typedef Eigen::InnerIterator<Derived> InnerIterator;
|
||||
|
||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||
|
||||
/** \brief The type of indices
|
||||
* \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
|
||||
* \sa \ref TopicPreprocessorDirectives.
|
||||
*/
|
||||
typedef typename internal::traits<Derived>::Index Index;
|
||||
/**
|
||||
* \brief The type used to store indices
|
||||
* \details This typedef is relevant for types that store multiple indices such as
|
||||
* PermutationMatrix or Transpositions, otherwise it defaults to Eigen::Index
|
||||
* \sa \ref TopicPreprocessorDirectives, Eigen::Index, SparseMatrixBase.
|
||||
*/
|
||||
typedef typename internal::traits<Derived>::StorageIndex StorageIndex;
|
||||
|
||||
/** The numeric type of the expression' coefficients, e.g. float, double, int or std::complex<float>, etc. */
|
||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
|
||||
|
||||
/** The numeric type of the expression' coefficients, e.g. float, double, int or std::complex<float>, etc.
|
||||
*
|
||||
* It is an alias for the Scalar type */
|
||||
typedef Scalar value_type;
|
||||
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
|
||||
typedef DenseCoeffsBase<Derived> Base;
|
||||
typedef internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
|
||||
typename NumTraits<typename internal::traits<Derived>::Scalar>::Real> Base;
|
||||
using Base::derived;
|
||||
using Base::const_cast_derived;
|
||||
using Base::rows;
|
||||
@@ -74,16 +89,6 @@ template<typename Derived> class DenseBase
|
||||
using Base::colIndexByOuterInner;
|
||||
using Base::coeff;
|
||||
using Base::coeffByOuterInner;
|
||||
using Base::packet;
|
||||
using Base::packetByOuterInner;
|
||||
using Base::writePacket;
|
||||
using Base::writePacketByOuterInner;
|
||||
using Base::coeffRef;
|
||||
using Base::coeffRefByOuterInner;
|
||||
using Base::copyCoeff;
|
||||
using Base::copyCoeffByOuterInner;
|
||||
using Base::copyPacket;
|
||||
using Base::copyPacketByOuterInner;
|
||||
using Base::operator();
|
||||
using Base::operator[];
|
||||
using Base::x;
|
||||
@@ -169,19 +174,46 @@ template<typename Derived> class DenseBase
|
||||
InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
|
||||
: int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
|
||||
|
||||
CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
|
||||
/**< This is a rough measure of how expensive it is to read one coefficient from
|
||||
* this expression.
|
||||
*/
|
||||
|
||||
InnerStrideAtCompileTime = internal::inner_stride_at_compile_time<Derived>::ret,
|
||||
OuterStrideAtCompileTime = internal::outer_stride_at_compile_time<Derived>::ret
|
||||
};
|
||||
|
||||
typedef typename internal::find_best_packet<Scalar,SizeAtCompileTime>::type PacketScalar;
|
||||
|
||||
enum { ThisConstantIsPrivateInPlainObjectBase };
|
||||
enum { IsPlainObjectBase = 0 };
|
||||
|
||||
/** The plain matrix type corresponding to this expression.
|
||||
* \sa PlainObject */
|
||||
typedef Matrix<typename internal::traits<Derived>::Scalar,
|
||||
internal::traits<Derived>::RowsAtCompileTime,
|
||||
internal::traits<Derived>::ColsAtCompileTime,
|
||||
AutoAlign | (internal::traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor),
|
||||
internal::traits<Derived>::MaxRowsAtCompileTime,
|
||||
internal::traits<Derived>::MaxColsAtCompileTime
|
||||
> PlainMatrix;
|
||||
|
||||
/** The plain array type corresponding to this expression.
|
||||
* \sa PlainObject */
|
||||
typedef Array<typename internal::traits<Derived>::Scalar,
|
||||
internal::traits<Derived>::RowsAtCompileTime,
|
||||
internal::traits<Derived>::ColsAtCompileTime,
|
||||
AutoAlign | (internal::traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor),
|
||||
internal::traits<Derived>::MaxRowsAtCompileTime,
|
||||
internal::traits<Derived>::MaxColsAtCompileTime
|
||||
> PlainArray;
|
||||
|
||||
/** \brief The plain matrix or array type corresponding to this expression.
|
||||
*
|
||||
* This is not necessarily exactly the return type of eval(). In the case of plain matrices,
|
||||
* the return type of eval() is a const reference to a matrix, not a matrix! It is however guaranteed
|
||||
* that the return type of eval() is either PlainObject or const PlainObject&.
|
||||
*/
|
||||
typedef typename internal::conditional<internal::is_same<typename internal::traits<Derived>::XprKind,MatrixXpr >::value,
|
||||
PlainMatrix, PlainArray>::type PlainObject;
|
||||
|
||||
/** \returns the number of nonzero coefficients which is in practice the number
|
||||
* of stored coefficients. */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index nonZeros() const { return size(); }
|
||||
/** \returns true if either the number of rows or the number of columns is equal to 1.
|
||||
* In other words, this function returns
|
||||
@@ -193,6 +225,7 @@ template<typename Derived> class DenseBase
|
||||
* \note For a vector, this returns just 1. For a matrix (non-vector), this is the major dimension
|
||||
* with respect to the \ref TopicStorageOrders "storage order", i.e., the number of columns for a
|
||||
* column-major matrix, and the number of rows for a row-major matrix. */
|
||||
EIGEN_DEVICE_FUNC
|
||||
Index outerSize() const
|
||||
{
|
||||
return IsVectorAtCompileTime ? 1
|
||||
@@ -204,6 +237,7 @@ template<typename Derived> class DenseBase
|
||||
* \note For a vector, this is just the size. For a matrix (non-vector), this is the minor dimension
|
||||
* with respect to the \ref TopicStorageOrders "storage order", i.e., the number of rows for a
|
||||
* column-major matrix, and the number of columns for a row-major matrix. */
|
||||
EIGEN_DEVICE_FUNC
|
||||
Index innerSize() const
|
||||
{
|
||||
return IsVectorAtCompileTime ? this->size()
|
||||
@@ -214,6 +248,7 @@ template<typename Derived> class DenseBase
|
||||
* Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does
|
||||
* nothing else.
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
void resize(Index newSize)
|
||||
{
|
||||
EIGEN_ONLY_USED_FOR_DEBUG(newSize);
|
||||
@@ -224,22 +259,22 @@ template<typename Derived> class DenseBase
|
||||
* Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does
|
||||
* nothing else.
|
||||
*/
|
||||
void resize(Index nbRows, Index nbCols)
|
||||
EIGEN_DEVICE_FUNC
|
||||
void resize(Index rows, Index cols)
|
||||
{
|
||||
EIGEN_ONLY_USED_FOR_DEBUG(nbRows);
|
||||
EIGEN_ONLY_USED_FOR_DEBUG(nbCols);
|
||||
eigen_assert(nbRows == this->rows() && nbCols == this->cols()
|
||||
EIGEN_ONLY_USED_FOR_DEBUG(rows);
|
||||
EIGEN_ONLY_USED_FOR_DEBUG(cols);
|
||||
eigen_assert(rows == this->rows() && cols == this->cols()
|
||||
&& "DenseBase::resize() does not actually allow to resize.");
|
||||
}
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
/** \internal Represents a matrix with all coefficients equal to one another*/
|
||||
typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Derived> ConstantReturnType;
|
||||
typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,PlainObject> ConstantReturnType;
|
||||
/** \internal Represents a vector with linearly spaced coefficients that allows sequential access only. */
|
||||
typedef CwiseNullaryOp<internal::linspaced_op<Scalar,false>,Derived> SequentialLinSpacedReturnType;
|
||||
typedef CwiseNullaryOp<internal::linspaced_op<Scalar,PacketScalar,false>,PlainObject> SequentialLinSpacedReturnType;
|
||||
/** \internal Represents a vector with linearly spaced coefficients that allows random access. */
|
||||
typedef CwiseNullaryOp<internal::linspaced_op<Scalar,true>,Derived> RandomAccessLinSpacedReturnType;
|
||||
typedef CwiseNullaryOp<internal::linspaced_op<Scalar,PacketScalar,true>,PlainObject> RandomAccessLinSpacedReturnType;
|
||||
/** \internal the return type of MatrixBase::eigenvalues() */
|
||||
typedef Matrix<typename NumTraits<typename internal::traits<Derived>::Scalar>::Real, internal::traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType;
|
||||
|
||||
@@ -247,110 +282,122 @@ template<typename Derived> class DenseBase
|
||||
|
||||
/** Copies \a other into *this. \returns a reference to *this. */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator=(const DenseBase<OtherDerived>& other);
|
||||
|
||||
/** Special case of the template operator=, in order to prevent the compiler
|
||||
* from generating a default operator= (issue hit with g++ 4.1)
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator=(const DenseBase& other);
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator=(const EigenBase<OtherDerived> &other);
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator+=(const EigenBase<OtherDerived> &other);
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator-=(const EigenBase<OtherDerived> &other);
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator=(const ReturnByValue<OtherDerived>& func);
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
/** Copies \a other into *this without evaluating other. \returns a reference to *this. */
|
||||
/** \ínternal
|
||||
* Copies \a other into *this without evaluating other. \returns a reference to *this.
|
||||
* \deprecated */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& lazyAssign(const DenseBase<OtherDerived>& other);
|
||||
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
CommaInitializer<Derived> operator<< (const Scalar& s);
|
||||
|
||||
/** \deprecated it now returns \c *this */
|
||||
template<unsigned int Added,unsigned int Removed>
|
||||
const Flagged<Derived, Added, Removed> flagged() const;
|
||||
EIGEN_DEPRECATED
|
||||
const Derived& flagged() const
|
||||
{ return derived(); }
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
CommaInitializer<Derived> operator<< (const DenseBase<OtherDerived>& other);
|
||||
|
||||
Eigen::Transpose<Derived> transpose();
|
||||
typedef typename internal::add_const<Transpose<const Derived> >::type ConstTransposeReturnType;
|
||||
typedef Transpose<Derived> TransposeReturnType;
|
||||
EIGEN_DEVICE_FUNC
|
||||
TransposeReturnType transpose();
|
||||
typedef typename internal::add_const<Transpose<const Derived> >::type ConstTransposeReturnType;
|
||||
EIGEN_DEVICE_FUNC
|
||||
ConstTransposeReturnType transpose() const;
|
||||
EIGEN_DEVICE_FUNC
|
||||
void transposeInPlace();
|
||||
#ifndef EIGEN_NO_DEBUG
|
||||
protected:
|
||||
template<typename OtherDerived>
|
||||
void checkTransposeAliasing(const OtherDerived& other) const;
|
||||
public:
|
||||
#endif
|
||||
|
||||
|
||||
static const ConstantReturnType
|
||||
EIGEN_DEVICE_FUNC static const ConstantReturnType
|
||||
Constant(Index rows, Index cols, const Scalar& value);
|
||||
static const ConstantReturnType
|
||||
EIGEN_DEVICE_FUNC static const ConstantReturnType
|
||||
Constant(Index size, const Scalar& value);
|
||||
static const ConstantReturnType
|
||||
EIGEN_DEVICE_FUNC static const ConstantReturnType
|
||||
Constant(const Scalar& value);
|
||||
|
||||
static const SequentialLinSpacedReturnType
|
||||
EIGEN_DEVICE_FUNC static const SequentialLinSpacedReturnType
|
||||
LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high);
|
||||
static const RandomAccessLinSpacedReturnType
|
||||
EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType
|
||||
LinSpaced(Index size, const Scalar& low, const Scalar& high);
|
||||
static const SequentialLinSpacedReturnType
|
||||
EIGEN_DEVICE_FUNC static const SequentialLinSpacedReturnType
|
||||
LinSpaced(Sequential_t, const Scalar& low, const Scalar& high);
|
||||
static const RandomAccessLinSpacedReturnType
|
||||
EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType
|
||||
LinSpaced(const Scalar& low, const Scalar& high);
|
||||
|
||||
template<typename CustomNullaryOp>
|
||||
static const CwiseNullaryOp<CustomNullaryOp, Derived>
|
||||
template<typename CustomNullaryOp> EIGEN_DEVICE_FUNC
|
||||
static const CwiseNullaryOp<CustomNullaryOp, PlainObject>
|
||||
NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func);
|
||||
template<typename CustomNullaryOp>
|
||||
static const CwiseNullaryOp<CustomNullaryOp, Derived>
|
||||
template<typename CustomNullaryOp> EIGEN_DEVICE_FUNC
|
||||
static const CwiseNullaryOp<CustomNullaryOp, PlainObject>
|
||||
NullaryExpr(Index size, const CustomNullaryOp& func);
|
||||
template<typename CustomNullaryOp>
|
||||
static const CwiseNullaryOp<CustomNullaryOp, Derived>
|
||||
template<typename CustomNullaryOp> EIGEN_DEVICE_FUNC
|
||||
static const CwiseNullaryOp<CustomNullaryOp, PlainObject>
|
||||
NullaryExpr(const CustomNullaryOp& func);
|
||||
|
||||
static const ConstantReturnType Zero(Index rows, Index cols);
|
||||
static const ConstantReturnType Zero(Index size);
|
||||
static const ConstantReturnType Zero();
|
||||
static const ConstantReturnType Ones(Index rows, Index cols);
|
||||
static const ConstantReturnType Ones(Index size);
|
||||
static const ConstantReturnType Ones();
|
||||
EIGEN_DEVICE_FUNC static const ConstantReturnType Zero(Index rows, Index cols);
|
||||
EIGEN_DEVICE_FUNC static const ConstantReturnType Zero(Index size);
|
||||
EIGEN_DEVICE_FUNC static const ConstantReturnType Zero();
|
||||
EIGEN_DEVICE_FUNC static const ConstantReturnType Ones(Index rows, Index cols);
|
||||
EIGEN_DEVICE_FUNC static const ConstantReturnType Ones(Index size);
|
||||
EIGEN_DEVICE_FUNC static const ConstantReturnType Ones();
|
||||
|
||||
void fill(const Scalar& value);
|
||||
Derived& setConstant(const Scalar& value);
|
||||
Derived& setLinSpaced(Index size, const Scalar& low, const Scalar& high);
|
||||
Derived& setLinSpaced(const Scalar& low, const Scalar& high);
|
||||
Derived& setZero();
|
||||
Derived& setOnes();
|
||||
Derived& setRandom();
|
||||
EIGEN_DEVICE_FUNC void fill(const Scalar& value);
|
||||
EIGEN_DEVICE_FUNC Derived& setConstant(const Scalar& value);
|
||||
EIGEN_DEVICE_FUNC Derived& setLinSpaced(Index size, const Scalar& low, const Scalar& high);
|
||||
EIGEN_DEVICE_FUNC Derived& setLinSpaced(const Scalar& low, const Scalar& high);
|
||||
EIGEN_DEVICE_FUNC Derived& setZero();
|
||||
EIGEN_DEVICE_FUNC Derived& setOnes();
|
||||
EIGEN_DEVICE_FUNC Derived& setRandom();
|
||||
|
||||
template<typename OtherDerived>
|
||||
template<typename OtherDerived> EIGEN_DEVICE_FUNC
|
||||
bool isApprox(const DenseBase<OtherDerived>& other,
|
||||
const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||
EIGEN_DEVICE_FUNC
|
||||
bool isMuchSmallerThan(const RealScalar& other,
|
||||
const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||
template<typename OtherDerived>
|
||||
template<typename OtherDerived> EIGEN_DEVICE_FUNC
|
||||
bool isMuchSmallerThan(const DenseBase<OtherDerived>& other,
|
||||
const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||
|
||||
bool isApproxToConstant(const Scalar& value, const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||
bool isConstant(const Scalar& value, const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||
bool isZero(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||
bool isOnes(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||
EIGEN_DEVICE_FUNC bool isApproxToConstant(const Scalar& value, const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||
EIGEN_DEVICE_FUNC bool isConstant(const Scalar& value, const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||
EIGEN_DEVICE_FUNC bool isZero(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||
EIGEN_DEVICE_FUNC bool isOnes(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||
|
||||
inline bool hasNaN() const;
|
||||
inline bool isFinite() const;
|
||||
inline bool allFinite() const;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Derived& operator*=(const Scalar& other);
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Derived& operator/=(const Scalar& other);
|
||||
|
||||
typedef typename internal::add_const_on_value_type<typename internal::eval<Derived>::type>::type EvalReturnType;
|
||||
@@ -358,7 +405,10 @@ template<typename Derived> class DenseBase
|
||||
*
|
||||
* Notice that in the case of a plain matrix or vector (not an expression) this function just returns
|
||||
* a const reference, in order to avoid a useless copy.
|
||||
*
|
||||
* \warning Be carefull with eval() and the auto C++ keyword, as detailed in this \link TopicPitfalls_auto_keyword page \endlink.
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE EvalReturnType eval() const
|
||||
{
|
||||
// Even though MSVC does not honor strong inlining when the return type
|
||||
@@ -366,61 +416,68 @@ template<typename Derived> class DenseBase
|
||||
// size types on MSVC.
|
||||
return typename internal::eval<Derived>::type(derived());
|
||||
}
|
||||
|
||||
|
||||
/** swaps *this with the expression \a other.
|
||||
*
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
void swap(const DenseBase<OtherDerived>& other,
|
||||
int = OtherDerived::ThisConstantIsPrivateInPlainObjectBase)
|
||||
EIGEN_DEVICE_FUNC
|
||||
void swap(const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
SwapWrapper<Derived>(derived()).lazyAssign(other.derived());
|
||||
EIGEN_STATIC_ASSERT(!OtherDerived::IsPlainObjectBase,THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
|
||||
eigen_assert(rows()==other.rows() && cols()==other.cols());
|
||||
call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
|
||||
}
|
||||
|
||||
/** swaps *this with the matrix or array \a other.
|
||||
*
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
void swap(PlainObjectBase<OtherDerived>& other)
|
||||
{
|
||||
SwapWrapper<Derived>(derived()).lazyAssign(other.derived());
|
||||
eigen_assert(rows()==other.rows() && cols()==other.cols());
|
||||
call_assignment(derived(), other.derived(), internal::swap_assign_op<Scalar>());
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC inline const NestByValue<Derived> nestByValue() const;
|
||||
EIGEN_DEVICE_FUNC inline const ForceAlignedAccess<Derived> forceAlignedAccess() const;
|
||||
EIGEN_DEVICE_FUNC inline ForceAlignedAccess<Derived> forceAlignedAccess();
|
||||
template<bool Enable> EIGEN_DEVICE_FUNC
|
||||
inline const typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf() const;
|
||||
template<bool Enable> EIGEN_DEVICE_FUNC
|
||||
inline typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf();
|
||||
|
||||
inline const NestByValue<Derived> nestByValue() const;
|
||||
inline const ForceAlignedAccess<Derived> forceAlignedAccess() const;
|
||||
inline ForceAlignedAccess<Derived> forceAlignedAccess();
|
||||
template<bool Enable> inline const typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf() const;
|
||||
template<bool Enable> inline typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf();
|
||||
EIGEN_DEVICE_FUNC Scalar sum() const;
|
||||
EIGEN_DEVICE_FUNC Scalar mean() const;
|
||||
EIGEN_DEVICE_FUNC Scalar trace() const;
|
||||
|
||||
Scalar sum() const;
|
||||
Scalar mean() const;
|
||||
Scalar trace() const;
|
||||
EIGEN_DEVICE_FUNC Scalar prod() const;
|
||||
|
||||
Scalar prod() const;
|
||||
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar minCoeff() const;
|
||||
EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar maxCoeff() const;
|
||||
|
||||
typename internal::traits<Derived>::Scalar minCoeff() const;
|
||||
typename internal::traits<Derived>::Scalar maxCoeff() const;
|
||||
|
||||
template<typename IndexType>
|
||||
template<typename IndexType> EIGEN_DEVICE_FUNC
|
||||
typename internal::traits<Derived>::Scalar minCoeff(IndexType* row, IndexType* col) const;
|
||||
template<typename IndexType>
|
||||
template<typename IndexType> EIGEN_DEVICE_FUNC
|
||||
typename internal::traits<Derived>::Scalar maxCoeff(IndexType* row, IndexType* col) const;
|
||||
template<typename IndexType>
|
||||
template<typename IndexType> EIGEN_DEVICE_FUNC
|
||||
typename internal::traits<Derived>::Scalar minCoeff(IndexType* index) const;
|
||||
template<typename IndexType>
|
||||
template<typename IndexType> EIGEN_DEVICE_FUNC
|
||||
typename internal::traits<Derived>::Scalar maxCoeff(IndexType* index) const;
|
||||
|
||||
template<typename BinaryOp>
|
||||
typename internal::result_of<BinaryOp(typename internal::traits<Derived>::Scalar)>::type
|
||||
redux(const BinaryOp& func) const;
|
||||
EIGEN_DEVICE_FUNC
|
||||
Scalar redux(const BinaryOp& func) const;
|
||||
|
||||
template<typename Visitor>
|
||||
EIGEN_DEVICE_FUNC
|
||||
void visit(Visitor& func) const;
|
||||
|
||||
inline const WithFormat<Derived> format(const IOFormat& fmt) const;
|
||||
|
||||
/** \returns the unique coefficient of a 1x1 expression */
|
||||
EIGEN_DEVICE_FUNC
|
||||
CoeffReturnType value() const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
|
||||
@@ -428,8 +485,8 @@ template<typename Derived> class DenseBase
|
||||
return derived().coeff(0,0);
|
||||
}
|
||||
|
||||
bool all(void) const;
|
||||
bool any(void) const;
|
||||
bool all() const;
|
||||
bool any() const;
|
||||
Index count() const;
|
||||
|
||||
typedef VectorwiseOp<Derived, Horizontal> RowwiseReturnType;
|
||||
@@ -437,14 +494,35 @@ template<typename Derived> class DenseBase
|
||||
typedef VectorwiseOp<Derived, Vertical> ColwiseReturnType;
|
||||
typedef const VectorwiseOp<const Derived, Vertical> ConstColwiseReturnType;
|
||||
|
||||
ConstRowwiseReturnType rowwise() const;
|
||||
RowwiseReturnType rowwise();
|
||||
ConstColwiseReturnType colwise() const;
|
||||
ColwiseReturnType colwise();
|
||||
/** \returns a VectorwiseOp wrapper of *this providing additional partial reduction operations
|
||||
*
|
||||
* Example: \include MatrixBase_rowwise.cpp
|
||||
* Output: \verbinclude MatrixBase_rowwise.out
|
||||
*
|
||||
* \sa colwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
|
||||
*/
|
||||
//Code moved here due to a CUDA compiler bug
|
||||
EIGEN_DEVICE_FUNC inline ConstRowwiseReturnType rowwise() const {
|
||||
return ConstRowwiseReturnType(derived());
|
||||
}
|
||||
EIGEN_DEVICE_FUNC RowwiseReturnType rowwise();
|
||||
|
||||
static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random(Index rows, Index cols);
|
||||
static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random(Index size);
|
||||
static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random();
|
||||
/** \returns a VectorwiseOp wrapper of *this providing additional partial reduction operations
|
||||
*
|
||||
* Example: \include MatrixBase_colwise.cpp
|
||||
* Output: \verbinclude MatrixBase_colwise.out
|
||||
*
|
||||
* \sa rowwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC inline ConstColwiseReturnType colwise() const {
|
||||
return ConstColwiseReturnType(derived());
|
||||
}
|
||||
EIGEN_DEVICE_FUNC ColwiseReturnType colwise();
|
||||
|
||||
typedef CwiseNullaryOp<internal::scalar_random_op<Scalar>,PlainObject> RandomReturnType;
|
||||
static const RandomReturnType Random(Index rows, Index cols);
|
||||
static const RandomReturnType Random(Index size);
|
||||
static const RandomReturnType Random();
|
||||
|
||||
template<typename ThenDerived,typename ElseDerived>
|
||||
const Select<Derived,ThenDerived,ElseDerived>
|
||||
@@ -462,14 +540,33 @@ template<typename Derived> class DenseBase
|
||||
template<int p> RealScalar lpNorm() const;
|
||||
|
||||
template<int RowFactor, int ColFactor>
|
||||
EIGEN_DEVICE_FUNC
|
||||
const Replicate<Derived,RowFactor,ColFactor> replicate() const;
|
||||
const Replicate<Derived,Dynamic,Dynamic> replicate(Index rowFacor,Index colFactor) const;
|
||||
/**
|
||||
* \return an expression of the replication of \c *this
|
||||
*
|
||||
* Example: \include MatrixBase_replicate_int_int.cpp
|
||||
* Output: \verbinclude MatrixBase_replicate_int_int.out
|
||||
*
|
||||
* \sa VectorwiseOp::replicate(), DenseBase::replicate<int,int>(), class Replicate
|
||||
*/
|
||||
//Code moved here due to a CUDA compiler bug
|
||||
EIGEN_DEVICE_FUNC
|
||||
const Replicate<Derived, Dynamic, Dynamic> replicate(Index rowFactor, Index colFactor) const
|
||||
{
|
||||
return Replicate<Derived, Dynamic, Dynamic>(derived(), rowFactor, colFactor);
|
||||
}
|
||||
|
||||
typedef Reverse<Derived, BothDirections> ReverseReturnType;
|
||||
typedef const Reverse<const Derived, BothDirections> ConstReverseReturnType;
|
||||
ReverseReturnType reverse();
|
||||
ConstReverseReturnType reverse() const;
|
||||
void reverseInPlace();
|
||||
EIGEN_DEVICE_FUNC ReverseReturnType reverse();
|
||||
/** This is the const version of reverse(). */
|
||||
//Code moved here due to a CUDA compiler bug
|
||||
EIGEN_DEVICE_FUNC ConstReverseReturnType reverse() const
|
||||
{
|
||||
return ConstReverseReturnType(derived());
|
||||
}
|
||||
EIGEN_DEVICE_FUNC void reverseInPlace();
|
||||
|
||||
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::DenseBase
|
||||
# include "../plugins/BlockMethods.h"
|
||||
@@ -478,27 +575,18 @@ template<typename Derived> class DenseBase
|
||||
# endif
|
||||
#undef EIGEN_CURRENT_STORAGE_BASE_CLASS
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
|
||||
Block<Derived> corner(CornerType type, Index cRows, Index cCols);
|
||||
const Block<Derived> corner(CornerType type, Index cRows, Index cCols) const;
|
||||
template<int CRows, int CCols>
|
||||
Block<Derived, CRows, CCols> corner(CornerType type);
|
||||
template<int CRows, int CCols>
|
||||
const Block<Derived, CRows, CCols> corner(CornerType type) const;
|
||||
|
||||
#endif // EIGEN2_SUPPORT
|
||||
|
||||
|
||||
// disable the use of evalTo for dense objects with a nice compilation error
|
||||
template<typename Dest> inline void evalTo(Dest& ) const
|
||||
template<typename Dest>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline void evalTo(Dest& ) const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT((internal::is_same<Dest,void>::value),THE_EVAL_EVALTO_FUNCTION_SHOULD_NEVER_BE_CALLED_FOR_DENSE_OBJECTS);
|
||||
}
|
||||
|
||||
protected:
|
||||
/** Default constructor. Do nothing. */
|
||||
DenseBase()
|
||||
EIGEN_DEVICE_FUNC DenseBase()
|
||||
{
|
||||
/* Just checks for self-consistency of the flags.
|
||||
* Only do it when debugging Eigen, as this borders on paranoiac and could slow compilation down
|
||||
@@ -511,9 +599,9 @@ template<typename Derived> class DenseBase
|
||||
}
|
||||
|
||||
private:
|
||||
explicit DenseBase(int);
|
||||
DenseBase(int,int);
|
||||
template<typename OtherDerived> explicit DenseBase(const DenseBase<OtherDerived>&);
|
||||
EIGEN_DEVICE_FUNC explicit DenseBase(int);
|
||||
EIGEN_DEVICE_FUNC DenseBase(int,int);
|
||||
template<typename OtherDerived> EIGEN_DEVICE_FUNC explicit DenseBase(const DenseBase<OtherDerived>&);
|
||||
};
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -35,7 +35,6 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
||||
{
|
||||
public:
|
||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||
typedef typename internal::traits<Derived>::Index Index;
|
||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
|
||||
|
||||
@@ -61,6 +60,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
||||
using Base::size;
|
||||
using Base::derived;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index rowIndexByOuterInner(Index outer, Index inner) const
|
||||
{
|
||||
return int(Derived::RowsAtCompileTime) == 1 ? 0
|
||||
@@ -69,6 +69,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
||||
: inner;
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index colIndexByOuterInner(Index outer, Index inner) const
|
||||
{
|
||||
return int(Derived::ColsAtCompileTime) == 1 ? 0
|
||||
@@ -91,13 +92,15 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
||||
*
|
||||
* \sa operator()(Index,Index) const, coeffRef(Index,Index), coeff(Index) const
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
|
||||
{
|
||||
eigen_internal_assert(row >= 0 && row < rows()
|
||||
&& col >= 0 && col < cols());
|
||||
return derived().coeff(row, col);
|
||||
&& col >= 0 && col < cols());
|
||||
return internal::evaluator<Derived>(derived()).coeff(row,col);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE CoeffReturnType coeffByOuterInner(Index outer, Index inner) const
|
||||
{
|
||||
return coeff(rowIndexByOuterInner(outer, inner),
|
||||
@@ -108,11 +111,12 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
||||
*
|
||||
* \sa operator()(Index,Index), operator[](Index)
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE CoeffReturnType operator()(Index row, Index col) const
|
||||
{
|
||||
eigen_assert(row >= 0 && row < rows()
|
||||
&& col >= 0 && col < cols());
|
||||
return derived().coeff(row, col);
|
||||
return coeff(row, col);
|
||||
}
|
||||
|
||||
/** Short version: don't use this function, use
|
||||
@@ -130,11 +134,12 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
||||
* \sa operator[](Index) const, coeffRef(Index), coeff(Index,Index) const
|
||||
*/
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE CoeffReturnType
|
||||
coeff(Index index) const
|
||||
{
|
||||
eigen_internal_assert(index >= 0 && index < size());
|
||||
return derived().coeff(index);
|
||||
return internal::evaluator<Derived>(derived()).coeff(index);
|
||||
}
|
||||
|
||||
|
||||
@@ -146,15 +151,14 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
||||
* z() const, w() const
|
||||
*/
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE CoeffReturnType
|
||||
operator[](Index index) const
|
||||
{
|
||||
#ifndef EIGEN2_SUPPORT
|
||||
EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
|
||||
THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
|
||||
#endif
|
||||
eigen_assert(index >= 0 && index < size());
|
||||
return derived().coeff(index);
|
||||
return coeff(index);
|
||||
}
|
||||
|
||||
/** \returns the coefficient at given index.
|
||||
@@ -167,30 +171,35 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
||||
* z() const, w() const
|
||||
*/
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE CoeffReturnType
|
||||
operator()(Index index) const
|
||||
{
|
||||
eigen_assert(index >= 0 && index < size());
|
||||
return derived().coeff(index);
|
||||
return coeff(index);
|
||||
}
|
||||
|
||||
/** equivalent to operator[](0). */
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE CoeffReturnType
|
||||
x() const { return (*this)[0]; }
|
||||
|
||||
/** equivalent to operator[](1). */
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE CoeffReturnType
|
||||
y() const { return (*this)[1]; }
|
||||
|
||||
/** equivalent to operator[](2). */
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE CoeffReturnType
|
||||
z() const { return (*this)[2]; }
|
||||
|
||||
/** equivalent to operator[](3). */
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE CoeffReturnType
|
||||
w() const { return (*this)[3]; }
|
||||
|
||||
@@ -207,9 +216,9 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
||||
template<int LoadMode>
|
||||
EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const
|
||||
{
|
||||
eigen_internal_assert(row >= 0 && row < rows()
|
||||
&& col >= 0 && col < cols());
|
||||
return derived().template packet<LoadMode>(row,col);
|
||||
typedef typename internal::packet_traits<Scalar>::type DefaultPacketType;
|
||||
eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
|
||||
return internal::evaluator<Derived>(derived()).template packet<LoadMode,DefaultPacketType>(row,col);
|
||||
}
|
||||
|
||||
|
||||
@@ -234,8 +243,9 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
||||
template<int LoadMode>
|
||||
EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
|
||||
{
|
||||
typedef typename internal::packet_traits<Scalar>::type DefaultPacketType;
|
||||
eigen_internal_assert(index >= 0 && index < size());
|
||||
return derived().template packet<LoadMode>(index);
|
||||
return internal::evaluator<Derived>(derived()).template packet<LoadMode,DefaultPacketType>(index);
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -278,7 +288,6 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
||||
typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
|
||||
|
||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||
typedef typename internal::traits<Derived>::Index Index;
|
||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
@@ -311,13 +320,15 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
||||
*
|
||||
* \sa operator()(Index,Index), coeff(Index, Index) const, coeffRef(Index)
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
|
||||
{
|
||||
eigen_internal_assert(row >= 0 && row < rows()
|
||||
&& col >= 0 && col < cols());
|
||||
return derived().coeffRef(row, col);
|
||||
&& col >= 0 && col < cols());
|
||||
return internal::evaluator<Derived>(derived()).coeffRef(row,col);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Scalar&
|
||||
coeffRefByOuterInner(Index outer, Index inner)
|
||||
{
|
||||
@@ -330,12 +341,13 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
||||
* \sa operator[](Index)
|
||||
*/
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Scalar&
|
||||
operator()(Index row, Index col)
|
||||
{
|
||||
eigen_assert(row >= 0 && row < rows()
|
||||
&& col >= 0 && col < cols());
|
||||
return derived().coeffRef(row, col);
|
||||
return coeffRef(row, col);
|
||||
}
|
||||
|
||||
|
||||
@@ -354,11 +366,12 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
||||
* \sa operator[](Index), coeff(Index) const, coeffRef(Index,Index)
|
||||
*/
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Scalar&
|
||||
coeffRef(Index index)
|
||||
{
|
||||
eigen_internal_assert(index >= 0 && index < size());
|
||||
return derived().coeffRef(index);
|
||||
return internal::evaluator<Derived>(derived()).coeffRef(index);
|
||||
}
|
||||
|
||||
/** \returns a reference to the coefficient at given index.
|
||||
@@ -368,15 +381,14 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
||||
* \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w()
|
||||
*/
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Scalar&
|
||||
operator[](Index index)
|
||||
{
|
||||
#ifndef EIGEN2_SUPPORT
|
||||
EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
|
||||
THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
|
||||
#endif
|
||||
eigen_assert(index >= 0 && index < size());
|
||||
return derived().coeffRef(index);
|
||||
return coeffRef(index);
|
||||
}
|
||||
|
||||
/** \returns a reference to the coefficient at given index.
|
||||
@@ -388,167 +400,37 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
||||
* \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w()
|
||||
*/
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Scalar&
|
||||
operator()(Index index)
|
||||
{
|
||||
eigen_assert(index >= 0 && index < size());
|
||||
return derived().coeffRef(index);
|
||||
return coeffRef(index);
|
||||
}
|
||||
|
||||
/** equivalent to operator[](0). */
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Scalar&
|
||||
x() { return (*this)[0]; }
|
||||
|
||||
/** equivalent to operator[](1). */
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Scalar&
|
||||
y() { return (*this)[1]; }
|
||||
|
||||
/** equivalent to operator[](2). */
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Scalar&
|
||||
z() { return (*this)[2]; }
|
||||
|
||||
/** equivalent to operator[](3). */
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Scalar&
|
||||
w() { return (*this)[3]; }
|
||||
|
||||
/** \internal
|
||||
* Stores the given packet of coefficients, at the given row and column of this expression. It is your responsibility
|
||||
* to ensure that a packet really starts there. This method is only available on expressions having the
|
||||
* PacketAccessBit.
|
||||
*
|
||||
* The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select
|
||||
* the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
|
||||
* starting at an address which is a multiple of the packet size.
|
||||
*/
|
||||
|
||||
template<int StoreMode>
|
||||
EIGEN_STRONG_INLINE void writePacket
|
||||
(Index row, Index col, const typename internal::packet_traits<Scalar>::type& val)
|
||||
{
|
||||
eigen_internal_assert(row >= 0 && row < rows()
|
||||
&& col >= 0 && col < cols());
|
||||
derived().template writePacket<StoreMode>(row,col,val);
|
||||
}
|
||||
|
||||
|
||||
/** \internal */
|
||||
template<int StoreMode>
|
||||
EIGEN_STRONG_INLINE void writePacketByOuterInner
|
||||
(Index outer, Index inner, const typename internal::packet_traits<Scalar>::type& val)
|
||||
{
|
||||
writePacket<StoreMode>(rowIndexByOuterInner(outer, inner),
|
||||
colIndexByOuterInner(outer, inner),
|
||||
val);
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* Stores the given packet of coefficients, at the given index in this expression. It is your responsibility
|
||||
* to ensure that a packet really starts there. This method is only available on expressions having the
|
||||
* PacketAccessBit and the LinearAccessBit.
|
||||
*
|
||||
* The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select
|
||||
* the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
|
||||
* starting at an address which is a multiple of the packet size.
|
||||
*/
|
||||
template<int StoreMode>
|
||||
EIGEN_STRONG_INLINE void writePacket
|
||||
(Index index, const typename internal::packet_traits<Scalar>::type& val)
|
||||
{
|
||||
eigen_internal_assert(index >= 0 && index < size());
|
||||
derived().template writePacket<StoreMode>(index,val);
|
||||
}
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
/** \internal Copies the coefficient at position (row,col) of other into *this.
|
||||
*
|
||||
* This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
|
||||
* with usual assignments.
|
||||
*
|
||||
* Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
|
||||
*/
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
eigen_internal_assert(row >= 0 && row < rows()
|
||||
&& col >= 0 && col < cols());
|
||||
derived().coeffRef(row, col) = other.derived().coeff(row, col);
|
||||
}
|
||||
|
||||
/** \internal Copies the coefficient at the given index of other into *this.
|
||||
*
|
||||
* This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
|
||||
* with usual assignments.
|
||||
*
|
||||
* Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
|
||||
*/
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE void copyCoeff(Index index, const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
eigen_internal_assert(index >= 0 && index < size());
|
||||
derived().coeffRef(index) = other.derived().coeff(index);
|
||||
}
|
||||
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE void copyCoeffByOuterInner(Index outer, Index inner, const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
const Index row = rowIndexByOuterInner(outer,inner);
|
||||
const Index col = colIndexByOuterInner(outer,inner);
|
||||
// derived() is important here: copyCoeff() may be reimplemented in Derived!
|
||||
derived().copyCoeff(row, col, other);
|
||||
}
|
||||
|
||||
/** \internal Copies the packet at position (row,col) of other into *this.
|
||||
*
|
||||
* This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
|
||||
* with usual assignments.
|
||||
*
|
||||
* Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
|
||||
*/
|
||||
|
||||
template<typename OtherDerived, int StoreMode, int LoadMode>
|
||||
EIGEN_STRONG_INLINE void copyPacket(Index row, Index col, const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
eigen_internal_assert(row >= 0 && row < rows()
|
||||
&& col >= 0 && col < cols());
|
||||
derived().template writePacket<StoreMode>(row, col,
|
||||
other.derived().template packet<LoadMode>(row, col));
|
||||
}
|
||||
|
||||
/** \internal Copies the packet at the given index of other into *this.
|
||||
*
|
||||
* This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
|
||||
* with usual assignments.
|
||||
*
|
||||
* Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
|
||||
*/
|
||||
|
||||
template<typename OtherDerived, int StoreMode, int LoadMode>
|
||||
EIGEN_STRONG_INLINE void copyPacket(Index index, const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
eigen_internal_assert(index >= 0 && index < size());
|
||||
derived().template writePacket<StoreMode>(index,
|
||||
other.derived().template packet<LoadMode>(index));
|
||||
}
|
||||
|
||||
/** \internal */
|
||||
template<typename OtherDerived, int StoreMode, int LoadMode>
|
||||
EIGEN_STRONG_INLINE void copyPacketByOuterInner(Index outer, Index inner, const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
const Index row = rowIndexByOuterInner(outer,inner);
|
||||
const Index col = colIndexByOuterInner(outer,inner);
|
||||
// derived() is important here: copyCoeff() may be reimplemented in Derived!
|
||||
derived().template copyPacket< OtherDerived, StoreMode, LoadMode>(row, col, other);
|
||||
}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
/** \brief Base class providing direct read-only coefficient access to matrices and arrays.
|
||||
@@ -568,7 +450,6 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
||||
public:
|
||||
|
||||
typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
|
||||
typedef typename internal::traits<Derived>::Index Index;
|
||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
|
||||
@@ -581,6 +462,7 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
||||
*
|
||||
* \sa outerStride(), rowStride(), colStride()
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index innerStride() const
|
||||
{
|
||||
return derived().innerStride();
|
||||
@@ -591,6 +473,7 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
||||
*
|
||||
* \sa innerStride(), rowStride(), colStride()
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index outerStride() const
|
||||
{
|
||||
return derived().outerStride();
|
||||
@@ -606,6 +489,7 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
||||
*
|
||||
* \sa innerStride(), outerStride(), colStride()
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index rowStride() const
|
||||
{
|
||||
return Derived::IsRowMajor ? outerStride() : innerStride();
|
||||
@@ -615,6 +499,7 @@ class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived
|
||||
*
|
||||
* \sa innerStride(), outerStride(), rowStride()
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index colStride() const
|
||||
{
|
||||
return Derived::IsRowMajor ? innerStride() : outerStride();
|
||||
@@ -639,7 +524,6 @@ class DenseCoeffsBase<Derived, DirectWriteAccessors>
|
||||
public:
|
||||
|
||||
typedef DenseCoeffsBase<Derived, WriteAccessors> Base;
|
||||
typedef typename internal::traits<Derived>::Index Index;
|
||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
|
||||
@@ -652,6 +536,7 @@ class DenseCoeffsBase<Derived, DirectWriteAccessors>
|
||||
*
|
||||
* \sa outerStride(), rowStride(), colStride()
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index innerStride() const
|
||||
{
|
||||
return derived().innerStride();
|
||||
@@ -662,6 +547,7 @@ class DenseCoeffsBase<Derived, DirectWriteAccessors>
|
||||
*
|
||||
* \sa innerStride(), rowStride(), colStride()
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index outerStride() const
|
||||
{
|
||||
return derived().outerStride();
|
||||
@@ -677,6 +563,7 @@ class DenseCoeffsBase<Derived, DirectWriteAccessors>
|
||||
*
|
||||
* \sa innerStride(), outerStride(), colStride()
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index rowStride() const
|
||||
{
|
||||
return Derived::IsRowMajor ? outerStride() : innerStride();
|
||||
@@ -686,6 +573,7 @@ class DenseCoeffsBase<Derived, DirectWriteAccessors>
|
||||
*
|
||||
* \sa innerStride(), outerStride(), rowStride()
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index colStride() const
|
||||
{
|
||||
return Derived::IsRowMajor ? innerStride() : outerStride();
|
||||
@@ -694,33 +582,42 @@ class DenseCoeffsBase<Derived, DirectWriteAccessors>
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename Derived, bool JustReturnZero>
|
||||
template<int Alignment, typename Derived, bool JustReturnZero>
|
||||
struct first_aligned_impl
|
||||
{
|
||||
static inline typename Derived::Index run(const Derived&)
|
||||
static inline Index run(const Derived&)
|
||||
{ return 0; }
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
struct first_aligned_impl<Derived, false>
|
||||
template<int Alignment, typename Derived>
|
||||
struct first_aligned_impl<Alignment, Derived, false>
|
||||
{
|
||||
static inline typename Derived::Index run(const Derived& m)
|
||||
static inline Index run(const Derived& m)
|
||||
{
|
||||
return internal::first_aligned(&m.const_cast_derived().coeffRef(0,0), m.size());
|
||||
return internal::first_aligned<Alignment>(&m.const_cast_derived().coeffRef(0,0), m.size());
|
||||
}
|
||||
};
|
||||
|
||||
/** \internal \returns the index of the first element of the array that is well aligned for vectorization.
|
||||
/** \internal \returns the index of the first element of the array stored by \a m that is properly aligned with respect to \a Alignment for vectorization.
|
||||
*
|
||||
* \tparam Alignment requested alignment in Bytes.
|
||||
*
|
||||
* There is also the variant first_aligned(const Scalar*, Integer) defined in Memory.h. See it for more
|
||||
* documentation.
|
||||
*/
|
||||
template<typename Derived>
|
||||
static inline typename Derived::Index first_aligned(const Derived& m)
|
||||
template<int Alignment, typename Derived>
|
||||
static inline Index first_aligned(const DenseBase<Derived>& m)
|
||||
{
|
||||
return first_aligned_impl
|
||||
<Derived, (Derived::Flags & AlignedBit) || !(Derived::Flags & DirectAccessBit)>
|
||||
::run(m);
|
||||
enum { ReturnZero = (int(evaluator<Derived>::Alignment) >= Alignment) || !(Derived::Flags & DirectAccessBit) };
|
||||
return first_aligned_impl<Alignment, Derived, ReturnZero>::run(m.derived());
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
static inline Index first_default_aligned(const DenseBase<Derived>& m)
|
||||
{
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
typedef typename packet_traits<Scalar>::type DefaultPacketType;
|
||||
return first_aligned<unpacket_traits<DefaultPacketType>::alignment>(m);
|
||||
}
|
||||
|
||||
template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
// Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
// Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com>
|
||||
// Copyright (C) 2010-2013 Hauke Heibel <hauke.heibel@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
@@ -24,26 +24,37 @@ namespace internal {
|
||||
|
||||
struct constructor_without_unaligned_array_assert {};
|
||||
|
||||
template<typename T, int Size>
|
||||
EIGEN_DEVICE_FUNC
|
||||
void check_static_allocation_size()
|
||||
{
|
||||
// if EIGEN_STACK_ALLOCATION_LIMIT is defined to 0, then no limit
|
||||
#if EIGEN_STACK_ALLOCATION_LIMIT
|
||||
EIGEN_STATIC_ASSERT(Size * sizeof(T) <= EIGEN_STACK_ALLOCATION_LIMIT, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* Static array. If the MatrixOrArrayOptions require auto-alignment, the array will be automatically aligned:
|
||||
* to 16 bytes boundary if the total size is a multiple of 16 bytes.
|
||||
*/
|
||||
template <typename T, int Size, int MatrixOrArrayOptions,
|
||||
int Alignment = (MatrixOrArrayOptions&DontAlign) ? 0
|
||||
: (((Size*sizeof(T))%16)==0) ? 16
|
||||
: 0 >
|
||||
: compute_default_alignment<T,Size>::value >
|
||||
struct plain_array
|
||||
{
|
||||
T array[Size];
|
||||
|
||||
plain_array()
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT(Size * sizeof(T) <= 128 * 128 * 8, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
|
||||
plain_array(constructor_without_unaligned_array_assert)
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array(constructor_without_unaligned_array_assert)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT(Size * sizeof(T) <= 128 * 128 * 8, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -56,41 +67,100 @@ struct plain_array
|
||||
template<typename PtrType>
|
||||
EIGEN_ALWAYS_INLINE PtrType eigen_unaligned_array_assert_workaround_gcc47(PtrType array) { return array; }
|
||||
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
|
||||
eigen_assert((reinterpret_cast<size_t>(eigen_unaligned_array_assert_workaround_gcc47(array)) & sizemask) == 0 \
|
||||
eigen_assert((reinterpret_cast<size_t>(eigen_unaligned_array_assert_workaround_gcc47(array)) & (sizemask)) == 0 \
|
||||
&& "this assertion is explained here: " \
|
||||
"http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \
|
||||
" **** READ THIS WEB PAGE !!! ****");
|
||||
#else
|
||||
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
|
||||
eigen_assert((reinterpret_cast<size_t>(array) & sizemask) == 0 \
|
||||
eigen_assert((reinterpret_cast<size_t>(array) & (sizemask)) == 0 \
|
||||
&& "this assertion is explained here: " \
|
||||
"http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \
|
||||
" **** READ THIS WEB PAGE !!! ****");
|
||||
#endif
|
||||
|
||||
template <typename T, int Size, int MatrixOrArrayOptions>
|
||||
struct plain_array<T, Size, MatrixOrArrayOptions, 16>
|
||||
struct plain_array<T, Size, MatrixOrArrayOptions, 8>
|
||||
{
|
||||
EIGEN_USER_ALIGN16 T array[Size];
|
||||
EIGEN_ALIGN_TO_BOUNDARY(8) T array[Size];
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array()
|
||||
{
|
||||
EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(0xf);
|
||||
EIGEN_STATIC_ASSERT(Size * sizeof(T) <= 128 * 128 * 8, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
|
||||
{
|
||||
EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(7);
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array(constructor_without_unaligned_array_assert)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT(Size * sizeof(T) <= 128 * 128 * 8, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, int Size, int MatrixOrArrayOptions>
|
||||
struct plain_array<T, Size, MatrixOrArrayOptions, 16>
|
||||
{
|
||||
EIGEN_ALIGN_TO_BOUNDARY(16) T array[Size];
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array()
|
||||
{
|
||||
EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(15);
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array(constructor_without_unaligned_array_assert)
|
||||
{
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, int Size, int MatrixOrArrayOptions>
|
||||
struct plain_array<T, Size, MatrixOrArrayOptions, 32>
|
||||
{
|
||||
EIGEN_ALIGN_TO_BOUNDARY(32) T array[Size];
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array()
|
||||
{
|
||||
EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(31);
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array(constructor_without_unaligned_array_assert)
|
||||
{
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, int Size, int MatrixOrArrayOptions>
|
||||
struct plain_array<T, Size, MatrixOrArrayOptions, 64>
|
||||
{
|
||||
EIGEN_ALIGN_TO_BOUNDARY(64) T array[Size];
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array()
|
||||
{
|
||||
EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(63);
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
plain_array(constructor_without_unaligned_array_assert)
|
||||
{
|
||||
check_static_allocation_size<T,Size>();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, int MatrixOrArrayOptions, int Alignment>
|
||||
struct plain_array<T, 0, MatrixOrArrayOptions, Alignment>
|
||||
{
|
||||
EIGEN_USER_ALIGN16 T array[1];
|
||||
plain_array() {}
|
||||
plain_array(constructor_without_unaligned_array_assert) {}
|
||||
T array[1];
|
||||
EIGEN_DEVICE_FUNC plain_array() {}
|
||||
EIGEN_DEVICE_FUNC plain_array(constructor_without_unaligned_array_assert) {}
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
@@ -114,33 +184,50 @@ template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseSt
|
||||
{
|
||||
internal::plain_array<T,Size,_Options> m_data;
|
||||
public:
|
||||
inline DenseStorage() {}
|
||||
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
EIGEN_DEVICE_FUNC DenseStorage() {}
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
: m_data(internal::constructor_without_unaligned_array_assert()) {}
|
||||
inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
|
||||
inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); }
|
||||
static inline DenseIndex rows(void) {return _Rows;}
|
||||
static inline DenseIndex cols(void) {return _Cols;}
|
||||
inline void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {}
|
||||
inline void resize(DenseIndex,DenseIndex,DenseIndex) {}
|
||||
inline const T *data() const { return m_data.array; }
|
||||
inline T *data() { return m_data.array; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
DenseStorage(const DenseStorage& other) : m_data(other.m_data) {}
|
||||
EIGEN_DEVICE_FUNC
|
||||
DenseStorage& operator=(const DenseStorage& other)
|
||||
{
|
||||
if (this != &other) m_data = other.m_data;
|
||||
return *this;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) {
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
||||
eigen_internal_assert(size==rows*cols && rows==_Rows && cols==_Cols);
|
||||
EIGEN_UNUSED_VARIABLE(size);
|
||||
EIGEN_UNUSED_VARIABLE(rows);
|
||||
EIGEN_UNUSED_VARIABLE(cols);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); }
|
||||
EIGEN_DEVICE_FUNC static Index rows(void) {return _Rows;}
|
||||
EIGEN_DEVICE_FUNC static Index cols(void) {return _Cols;}
|
||||
EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
|
||||
EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {}
|
||||
EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
|
||||
EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
|
||||
};
|
||||
|
||||
// null matrix
|
||||
template<typename T, int _Rows, int _Cols, int _Options> class DenseStorage<T, 0, _Rows, _Cols, _Options>
|
||||
{
|
||||
public:
|
||||
inline DenseStorage() {}
|
||||
inline DenseStorage(internal::constructor_without_unaligned_array_assert) {}
|
||||
inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
|
||||
inline void swap(DenseStorage& ) {}
|
||||
static inline DenseIndex rows(void) {return _Rows;}
|
||||
static inline DenseIndex cols(void) {return _Cols;}
|
||||
inline void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {}
|
||||
inline void resize(DenseIndex,DenseIndex,DenseIndex) {}
|
||||
inline const T *data() const { return 0; }
|
||||
inline T *data() { return 0; }
|
||||
EIGEN_DEVICE_FUNC DenseStorage() {}
|
||||
EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) {}
|
||||
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage&) {}
|
||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage&) { return *this; }
|
||||
EIGEN_DEVICE_FUNC DenseStorage(Index,Index,Index) {}
|
||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& ) {}
|
||||
EIGEN_DEVICE_FUNC static Index rows(void) {return _Rows;}
|
||||
EIGEN_DEVICE_FUNC static Index cols(void) {return _Cols;}
|
||||
EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
|
||||
EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {}
|
||||
EIGEN_DEVICE_FUNC const T *data() const { return 0; }
|
||||
EIGEN_DEVICE_FUNC T *data() { return 0; }
|
||||
};
|
||||
|
||||
// more specializations for null matrices; these are necessary to resolve ambiguities
|
||||
@@ -157,86 +244,157 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, 0, Dynamic,
|
||||
template<typename T, int Size, int _Options> class DenseStorage<T, Size, Dynamic, Dynamic, _Options>
|
||||
{
|
||||
internal::plain_array<T,Size,_Options> m_data;
|
||||
DenseIndex m_rows;
|
||||
DenseIndex m_cols;
|
||||
Index m_rows;
|
||||
Index m_cols;
|
||||
public:
|
||||
inline DenseStorage() : m_rows(0), m_cols(0) {}
|
||||
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0), m_cols(0) {}
|
||||
EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
|
||||
inline DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) : m_rows(nbRows), m_cols(nbCols) {}
|
||||
inline void swap(DenseStorage& other)
|
||||
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows), m_cols(other.m_cols) {}
|
||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
m_data = other.m_data;
|
||||
m_rows = other.m_rows;
|
||||
m_cols = other.m_cols;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index cols) : m_rows(rows), m_cols(cols) {}
|
||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
|
||||
{ std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
|
||||
inline DenseIndex rows() const {return m_rows;}
|
||||
inline DenseIndex cols() const {return m_cols;}
|
||||
inline void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; }
|
||||
inline void resize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; }
|
||||
inline const T *data() const { return m_data.array; }
|
||||
inline T *data() { return m_data.array; }
|
||||
EIGEN_DEVICE_FUNC Index rows() const {return m_rows;}
|
||||
EIGEN_DEVICE_FUNC Index cols() const {return m_cols;}
|
||||
EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index cols) { m_rows = rows; m_cols = cols; }
|
||||
EIGEN_DEVICE_FUNC void resize(Index, Index rows, Index cols) { m_rows = rows; m_cols = cols; }
|
||||
EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
|
||||
EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
|
||||
};
|
||||
|
||||
// dynamic-size matrix with fixed-size storage and fixed width
|
||||
template<typename T, int Size, int _Cols, int _Options> class DenseStorage<T, Size, Dynamic, _Cols, _Options>
|
||||
{
|
||||
internal::plain_array<T,Size,_Options> m_data;
|
||||
DenseIndex m_rows;
|
||||
Index m_rows;
|
||||
public:
|
||||
inline DenseStorage() : m_rows(0) {}
|
||||
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0) {}
|
||||
EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {}
|
||||
inline DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex) : m_rows(nbRows) {}
|
||||
inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
|
||||
inline DenseIndex rows(void) const {return m_rows;}
|
||||
inline DenseIndex cols(void) const {return _Cols;}
|
||||
inline void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; }
|
||||
inline void resize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; }
|
||||
inline const T *data() const { return m_data.array; }
|
||||
inline T *data() { return m_data.array; }
|
||||
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows) {}
|
||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
m_data = other.m_data;
|
||||
m_rows = other.m_rows;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index) : m_rows(rows) {}
|
||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
|
||||
EIGEN_DEVICE_FUNC Index rows(void) const {return m_rows;}
|
||||
EIGEN_DEVICE_FUNC Index cols(void) const {return _Cols;}
|
||||
EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index) { m_rows = rows; }
|
||||
EIGEN_DEVICE_FUNC void resize(Index, Index rows, Index) { m_rows = rows; }
|
||||
EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
|
||||
EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
|
||||
};
|
||||
|
||||
// dynamic-size matrix with fixed-size storage and fixed height
|
||||
template<typename T, int Size, int _Rows, int _Options> class DenseStorage<T, Size, _Rows, Dynamic, _Options>
|
||||
{
|
||||
internal::plain_array<T,Size,_Options> m_data;
|
||||
DenseIndex m_cols;
|
||||
Index m_cols;
|
||||
public:
|
||||
inline DenseStorage() : m_cols(0) {}
|
||||
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
EIGEN_DEVICE_FUNC DenseStorage() : m_cols(0) {}
|
||||
EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
: m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {}
|
||||
inline DenseStorage(DenseIndex, DenseIndex, DenseIndex nbCols) : m_cols(nbCols) {}
|
||||
inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
|
||||
inline DenseIndex rows(void) const {return _Rows;}
|
||||
inline DenseIndex cols(void) const {return m_cols;}
|
||||
inline void conservativeResize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; }
|
||||
inline void resize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; }
|
||||
inline const T *data() const { return m_data.array; }
|
||||
inline T *data() { return m_data.array; }
|
||||
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_cols(other.m_cols) {}
|
||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
m_data = other.m_data;
|
||||
m_cols = other.m_cols;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC DenseStorage(Index, Index, Index cols) : m_cols(cols) {}
|
||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
|
||||
EIGEN_DEVICE_FUNC Index rows(void) const {return _Rows;}
|
||||
EIGEN_DEVICE_FUNC Index cols(void) const {return m_cols;}
|
||||
void conservativeResize(Index, Index, Index cols) { m_cols = cols; }
|
||||
void resize(Index, Index, Index cols) { m_cols = cols; }
|
||||
EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
|
||||
EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
|
||||
};
|
||||
|
||||
// purely dynamic matrix.
|
||||
template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynamic, _Options>
|
||||
{
|
||||
T *m_data;
|
||||
DenseIndex m_rows;
|
||||
DenseIndex m_cols;
|
||||
Index m_rows;
|
||||
Index m_cols;
|
||||
public:
|
||||
inline DenseStorage() : m_data(0), m_rows(0), m_cols(0) {}
|
||||
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
EIGEN_DEVICE_FUNC DenseStorage() : m_data(0), m_rows(0), m_cols(0) {}
|
||||
EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
: m_data(0), m_rows(0), m_cols(0) {}
|
||||
inline DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols)
|
||||
: m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(nbRows), m_cols(nbCols)
|
||||
{ EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
|
||||
inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); }
|
||||
inline void swap(DenseStorage& other)
|
||||
EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols)
|
||||
: m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(rows), m_cols(cols)
|
||||
{
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
||||
eigen_internal_assert(size==rows*cols && rows>=0 && cols >=0);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
|
||||
: m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(other.m_rows*other.m_cols))
|
||||
, m_rows(other.m_rows)
|
||||
, m_cols(other.m_cols)
|
||||
{
|
||||
internal::smart_copy(other.m_data, other.m_data+other.m_rows*other.m_cols, m_data);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
DenseStorage tmp(other);
|
||||
this->swap(tmp);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#ifdef EIGEN_HAVE_RVALUE_REFERENCES
|
||||
EIGEN_DEVICE_FUNC
|
||||
DenseStorage(DenseStorage&& other)
|
||||
: m_data(std::move(other.m_data))
|
||||
, m_rows(std::move(other.m_rows))
|
||||
, m_cols(std::move(other.m_cols))
|
||||
{
|
||||
other.m_data = nullptr;
|
||||
other.m_rows = 0;
|
||||
other.m_cols = 0;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
DenseStorage& operator=(DenseStorage&& other)
|
||||
{
|
||||
using std::swap;
|
||||
swap(m_data, other.m_data);
|
||||
swap(m_rows, other.m_rows);
|
||||
swap(m_cols, other.m_cols);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); }
|
||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
|
||||
{ std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
|
||||
inline DenseIndex rows(void) const {return m_rows;}
|
||||
inline DenseIndex cols(void) const {return m_cols;}
|
||||
inline void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols)
|
||||
EIGEN_DEVICE_FUNC Index rows(void) const {return m_rows;}
|
||||
EIGEN_DEVICE_FUNC Index cols(void) const {return m_cols;}
|
||||
void conservativeResize(Index size, Index rows, Index cols)
|
||||
{
|
||||
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*m_cols);
|
||||
m_rows = nbRows;
|
||||
m_cols = nbCols;
|
||||
m_rows = rows;
|
||||
m_cols = cols;
|
||||
}
|
||||
void resize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols)
|
||||
EIGEN_DEVICE_FUNC void resize(Index size, Index rows, Index cols)
|
||||
{
|
||||
if(size != m_rows*m_cols)
|
||||
{
|
||||
@@ -247,33 +405,70 @@ template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynam
|
||||
m_data = 0;
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
||||
}
|
||||
m_rows = nbRows;
|
||||
m_cols = nbCols;
|
||||
m_rows = rows;
|
||||
m_cols = cols;
|
||||
}
|
||||
inline const T *data() const { return m_data; }
|
||||
inline T *data() { return m_data; }
|
||||
EIGEN_DEVICE_FUNC const T *data() const { return m_data; }
|
||||
EIGEN_DEVICE_FUNC T *data() { return m_data; }
|
||||
};
|
||||
|
||||
// matrix with dynamic width and fixed height (so that matrix has dynamic size).
|
||||
template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Rows, Dynamic, _Options>
|
||||
{
|
||||
T *m_data;
|
||||
DenseIndex m_cols;
|
||||
Index m_cols;
|
||||
public:
|
||||
inline DenseStorage() : m_data(0), m_cols(0) {}
|
||||
inline DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
|
||||
inline DenseStorage(DenseIndex size, DenseIndex, DenseIndex nbCols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_cols(nbCols)
|
||||
{ EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
|
||||
inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); }
|
||||
inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
|
||||
static inline DenseIndex rows(void) {return _Rows;}
|
||||
inline DenseIndex cols(void) const {return m_cols;}
|
||||
inline void conservativeResize(DenseIndex size, DenseIndex, DenseIndex nbCols)
|
||||
EIGEN_DEVICE_FUNC DenseStorage() : m_data(0), m_cols(0) {}
|
||||
explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
|
||||
EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_cols(cols)
|
||||
{
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
||||
eigen_internal_assert(size==rows*cols && rows==_Rows && cols >=0);
|
||||
EIGEN_UNUSED_VARIABLE(rows);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
|
||||
: m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(_Rows*other.m_cols))
|
||||
, m_cols(other.m_cols)
|
||||
{
|
||||
internal::smart_copy(other.m_data, other.m_data+_Rows*m_cols, m_data);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
DenseStorage tmp(other);
|
||||
this->swap(tmp);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#ifdef EIGEN_HAVE_RVALUE_REFERENCES
|
||||
EIGEN_DEVICE_FUNC
|
||||
DenseStorage(DenseStorage&& other)
|
||||
: m_data(std::move(other.m_data))
|
||||
, m_cols(std::move(other.m_cols))
|
||||
{
|
||||
other.m_data = nullptr;
|
||||
other.m_cols = 0;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
DenseStorage& operator=(DenseStorage&& other)
|
||||
{
|
||||
using std::swap;
|
||||
swap(m_data, other.m_data);
|
||||
swap(m_cols, other.m_cols);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); }
|
||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
|
||||
EIGEN_DEVICE_FUNC static Index rows(void) {return _Rows;}
|
||||
EIGEN_DEVICE_FUNC Index cols(void) const {return m_cols;}
|
||||
EIGEN_DEVICE_FUNC void conservativeResize(Index size, Index, Index cols)
|
||||
{
|
||||
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, _Rows*m_cols);
|
||||
m_cols = nbCols;
|
||||
m_cols = cols;
|
||||
}
|
||||
EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex, DenseIndex nbCols)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(Index size, Index, Index cols)
|
||||
{
|
||||
if(size != _Rows*m_cols)
|
||||
{
|
||||
@@ -284,32 +479,69 @@ template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Ro
|
||||
m_data = 0;
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
||||
}
|
||||
m_cols = nbCols;
|
||||
m_cols = cols;
|
||||
}
|
||||
inline const T *data() const { return m_data; }
|
||||
inline T *data() { return m_data; }
|
||||
EIGEN_DEVICE_FUNC const T *data() const { return m_data; }
|
||||
EIGEN_DEVICE_FUNC T *data() { return m_data; }
|
||||
};
|
||||
|
||||
// matrix with dynamic height and fixed width (so that matrix has dynamic size).
|
||||
template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dynamic, _Cols, _Options>
|
||||
{
|
||||
T *m_data;
|
||||
DenseIndex m_rows;
|
||||
Index m_rows;
|
||||
public:
|
||||
inline DenseStorage() : m_data(0), m_rows(0) {}
|
||||
inline DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
|
||||
inline DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(nbRows)
|
||||
{ EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
|
||||
inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); }
|
||||
inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
|
||||
inline DenseIndex rows(void) const {return m_rows;}
|
||||
static inline DenseIndex cols(void) {return _Cols;}
|
||||
inline void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex)
|
||||
EIGEN_DEVICE_FUNC DenseStorage() : m_data(0), m_rows(0) {}
|
||||
explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
|
||||
EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(rows)
|
||||
{
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
||||
eigen_internal_assert(size==rows*cols && rows>=0 && cols == _Cols);
|
||||
EIGEN_UNUSED_VARIABLE(cols);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
|
||||
: m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(other.m_rows*_Cols))
|
||||
, m_rows(other.m_rows)
|
||||
{
|
||||
internal::smart_copy(other.m_data, other.m_data+other.m_rows*_Cols, m_data);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
DenseStorage tmp(other);
|
||||
this->swap(tmp);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#ifdef EIGEN_HAVE_RVALUE_REFERENCES
|
||||
EIGEN_DEVICE_FUNC
|
||||
DenseStorage(DenseStorage&& other)
|
||||
: m_data(std::move(other.m_data))
|
||||
, m_rows(std::move(other.m_rows))
|
||||
{
|
||||
other.m_data = nullptr;
|
||||
other.m_rows = 0;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
DenseStorage& operator=(DenseStorage&& other)
|
||||
{
|
||||
using std::swap;
|
||||
swap(m_data, other.m_data);
|
||||
swap(m_rows, other.m_rows);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); }
|
||||
EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
|
||||
EIGEN_DEVICE_FUNC Index rows(void) const {return m_rows;}
|
||||
EIGEN_DEVICE_FUNC static Index cols(void) {return _Cols;}
|
||||
void conservativeResize(Index size, Index rows, Index)
|
||||
{
|
||||
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*_Cols);
|
||||
m_rows = nbRows;
|
||||
m_rows = rows;
|
||||
}
|
||||
EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex nbRows, DenseIndex)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(Index size, Index rows, Index)
|
||||
{
|
||||
if(size != m_rows*_Cols)
|
||||
{
|
||||
@@ -320,10 +552,10 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dyn
|
||||
m_data = 0;
|
||||
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
|
||||
}
|
||||
m_rows = nbRows;
|
||||
m_rows = rows;
|
||||
}
|
||||
inline const T *data() const { return m_data; }
|
||||
inline T *data() { return m_data; }
|
||||
EIGEN_DEVICE_FUNC const T *data() const { return m_data; }
|
||||
EIGEN_DEVICE_FUNC T *data() { return m_data; }
|
||||
};
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -37,7 +37,7 @@ template<typename MatrixType, int DiagIndex>
|
||||
struct traits<Diagonal<MatrixType,DiagIndex> >
|
||||
: traits<MatrixType>
|
||||
{
|
||||
typedef typename nested<MatrixType>::type MatrixTypeNested;
|
||||
typedef typename ref_selector<MatrixType>::type MatrixTypeNested;
|
||||
typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
|
||||
typedef typename MatrixType::StorageKind StorageKind;
|
||||
enum {
|
||||
@@ -52,8 +52,7 @@ struct traits<Diagonal<MatrixType,DiagIndex> >
|
||||
MatrixType::MaxColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))),
|
||||
MaxColsAtCompileTime = 1,
|
||||
MaskLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
|
||||
Flags = (unsigned int)_MatrixTypeNested::Flags & (HereditaryBits | LinearAccessBit | MaskLvalueBit | DirectAccessBit) & ~RowMajorBit,
|
||||
CoeffReadCost = _MatrixTypeNested::CoeffReadCost,
|
||||
Flags = (unsigned int)_MatrixTypeNested::Flags & (RowMajorBit | MaskLvalueBit | DirectAccessBit) & ~RowMajorBit, // FIXME DirectAccessBit should not be handled by expressions
|
||||
MatrixTypeOuterStride = outer_stride_at_compile_time<MatrixType>::ret,
|
||||
InnerStrideAtCompileTime = MatrixTypeOuterStride == Dynamic ? Dynamic : MatrixTypeOuterStride+1,
|
||||
OuterStrideAtCompileTime = 0
|
||||
@@ -70,20 +69,28 @@ template<typename MatrixType, int _DiagIndex> class Diagonal
|
||||
typedef typename internal::dense_xpr_base<Diagonal>::type Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Diagonal)
|
||||
|
||||
inline Diagonal(MatrixType& matrix, Index a_index = DiagIndex) : m_matrix(matrix), m_index(a_index) {}
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit inline Diagonal(MatrixType& matrix, Index a_index = DiagIndex) : m_matrix(matrix), m_index(a_index) {}
|
||||
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Diagonal)
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index rows() const
|
||||
{ return m_index.value()<0 ? (std::min<Index>)(m_matrix.cols(),m_matrix.rows()+m_index.value()) : (std::min<Index>)(m_matrix.rows(),m_matrix.cols()-m_index.value()); }
|
||||
{
|
||||
return m_index.value()<0 ? numext::mini<Index>(m_matrix.cols(),m_matrix.rows()+m_index.value())
|
||||
: numext::mini<Index>(m_matrix.rows(),m_matrix.cols()-m_index.value());
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index cols() const { return 1; }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index innerStride() const
|
||||
{
|
||||
return m_matrix.outerStride() + 1;
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index outerStride() const
|
||||
{
|
||||
return 0;
|
||||
@@ -95,48 +102,58 @@ template<typename MatrixType, int _DiagIndex> class Diagonal
|
||||
const Scalar
|
||||
>::type ScalarWithConstIfNotLvalue;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline ScalarWithConstIfNotLvalue* data() { return &(m_matrix.const_cast_derived().coeffRef(rowOffset(), colOffset())); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar* data() const { return &(m_matrix.const_cast_derived().coeffRef(rowOffset(), colOffset())); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Scalar& coeffRef(Index row, Index)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
|
||||
return m_matrix.const_cast_derived().coeffRef(row+rowOffset(), row+colOffset());
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar& coeffRef(Index row, Index) const
|
||||
{
|
||||
return m_matrix.const_cast_derived().coeffRef(row+rowOffset(), row+colOffset());
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline CoeffReturnType coeff(Index row, Index) const
|
||||
{
|
||||
return m_matrix.coeff(row+rowOffset(), row+colOffset());
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Scalar& coeffRef(Index idx)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
|
||||
return m_matrix.const_cast_derived().coeffRef(idx+rowOffset(), idx+colOffset());
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar& coeffRef(Index idx) const
|
||||
{
|
||||
return m_matrix.const_cast_derived().coeffRef(idx+rowOffset(), idx+colOffset());
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline CoeffReturnType coeff(Index idx) const
|
||||
{
|
||||
return m_matrix.coeff(idx+rowOffset(), idx+colOffset());
|
||||
}
|
||||
|
||||
const typename internal::remove_all<typename MatrixType::Nested>::type&
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const typename internal::remove_all<typename MatrixType::Nested>::type&
|
||||
nestedExpression() const
|
||||
{
|
||||
return m_matrix;
|
||||
}
|
||||
|
||||
int index() const
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index index() const
|
||||
{
|
||||
return m_index.value();
|
||||
}
|
||||
@@ -147,10 +164,13 @@ template<typename MatrixType, int _DiagIndex> class Diagonal
|
||||
|
||||
private:
|
||||
// some compilers may fail to optimize std::max etc in case of compile-time constants...
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index absDiagIndex() const { return m_index.value()>0 ? m_index.value() : -m_index.value(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index rowOffset() const { return m_index.value()>0 ? 0 : -m_index.value(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index colOffset() const { return m_index.value()>0 ? m_index.value() : 0; }
|
||||
// triger a compile time error is someone try to call packet
|
||||
// trigger a compile-time error if someone try to call packet
|
||||
template<int LoadMode> typename MatrixType::PacketReturnType packet(Index) const;
|
||||
template<int LoadMode> typename MatrixType::PacketReturnType packet(Index,Index) const;
|
||||
};
|
||||
@@ -167,7 +187,7 @@ template<typename Derived>
|
||||
inline typename MatrixBase<Derived>::DiagonalReturnType
|
||||
MatrixBase<Derived>::diagonal()
|
||||
{
|
||||
return derived();
|
||||
return DiagonalReturnType(derived());
|
||||
}
|
||||
|
||||
/** This is the const version of diagonal(). */
|
||||
@@ -190,18 +210,18 @@ MatrixBase<Derived>::diagonal() const
|
||||
*
|
||||
* \sa MatrixBase::diagonal(), class Diagonal */
|
||||
template<typename Derived>
|
||||
inline typename MatrixBase<Derived>::template DiagonalIndexReturnType<DynamicIndex>::Type
|
||||
inline typename MatrixBase<Derived>::DiagonalDynamicIndexReturnType
|
||||
MatrixBase<Derived>::diagonal(Index index)
|
||||
{
|
||||
return typename DiagonalIndexReturnType<DynamicIndex>::Type(derived(), index);
|
||||
return DiagonalDynamicIndexReturnType(derived(), index);
|
||||
}
|
||||
|
||||
/** This is the const version of diagonal(Index). */
|
||||
template<typename Derived>
|
||||
inline typename MatrixBase<Derived>::template ConstDiagonalIndexReturnType<DynamicIndex>::Type
|
||||
inline typename MatrixBase<Derived>::ConstDiagonalDynamicIndexReturnType
|
||||
MatrixBase<Derived>::diagonal(Index index) const
|
||||
{
|
||||
return typename ConstDiagonalIndexReturnType<DynamicIndex>::Type(derived(), index);
|
||||
return ConstDiagonalDynamicIndexReturnType(derived(), index);
|
||||
}
|
||||
|
||||
/** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this
|
||||
@@ -216,20 +236,20 @@ MatrixBase<Derived>::diagonal(Index index) const
|
||||
*
|
||||
* \sa MatrixBase::diagonal(), class Diagonal */
|
||||
template<typename Derived>
|
||||
template<int Index>
|
||||
inline typename MatrixBase<Derived>::template DiagonalIndexReturnType<Index>::Type
|
||||
template<int Index_>
|
||||
inline typename MatrixBase<Derived>::template DiagonalIndexReturnType<Index_>::Type
|
||||
MatrixBase<Derived>::diagonal()
|
||||
{
|
||||
return derived();
|
||||
return typename DiagonalIndexReturnType<Index_>::Type(derived());
|
||||
}
|
||||
|
||||
/** This is the const version of diagonal<int>(). */
|
||||
template<typename Derived>
|
||||
template<int Index>
|
||||
inline typename MatrixBase<Derived>::template ConstDiagonalIndexReturnType<Index>::Type
|
||||
template<int Index_>
|
||||
inline typename MatrixBase<Derived>::template ConstDiagonalIndexReturnType<Index_>::Type
|
||||
MatrixBase<Derived>::diagonal() const
|
||||
{
|
||||
return derived();
|
||||
return typename ConstDiagonalIndexReturnType<Index_>::Type(derived());
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -22,7 +22,7 @@ class DiagonalBase : public EigenBase<Derived>
|
||||
typedef typename DiagonalVectorType::Scalar Scalar;
|
||||
typedef typename DiagonalVectorType::RealScalar RealScalar;
|
||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||
typedef typename internal::traits<Derived>::Index Index;
|
||||
typedef typename internal::traits<Derived>::StorageIndex StorageIndex;
|
||||
|
||||
enum {
|
||||
RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
|
||||
@@ -30,79 +30,62 @@ class DiagonalBase : public EigenBase<Derived>
|
||||
MaxRowsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
|
||||
MaxColsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
|
||||
IsVectorAtCompileTime = 0,
|
||||
Flags = 0
|
||||
Flags = NoPreferredStorageOrderBit
|
||||
};
|
||||
|
||||
typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, 0, MaxRowsAtCompileTime, MaxColsAtCompileTime> DenseMatrixType;
|
||||
typedef DenseMatrixType DenseType;
|
||||
typedef DiagonalMatrix<Scalar,DiagonalVectorType::SizeAtCompileTime,DiagonalVectorType::MaxSizeAtCompileTime> PlainObject;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Derived& derived() { return *static_cast<Derived*>(this); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
DenseMatrixType toDenseMatrix() const { return derived(); }
|
||||
template<typename DenseDerived>
|
||||
void evalTo(MatrixBase<DenseDerived> &other) const;
|
||||
template<typename DenseDerived>
|
||||
void addTo(MatrixBase<DenseDerived> &other) const
|
||||
{ other.diagonal() += diagonal(); }
|
||||
template<typename DenseDerived>
|
||||
void subTo(MatrixBase<DenseDerived> &other) const
|
||||
{ other.diagonal() -= diagonal(); }
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline DiagonalVectorType& diagonal() { return derived().diagonal(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index rows() const { return diagonal().size(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index cols() const { return diagonal().size(); }
|
||||
|
||||
/** \returns the diagonal matrix product of \c *this by the matrix \a matrix.
|
||||
*/
|
||||
template<typename MatrixDerived>
|
||||
const DiagonalProduct<MatrixDerived, Derived, OnTheLeft>
|
||||
EIGEN_DEVICE_FUNC
|
||||
const Product<Derived,MatrixDerived,LazyProduct>
|
||||
operator*(const MatrixBase<MatrixDerived> &matrix) const
|
||||
{
|
||||
return DiagonalProduct<MatrixDerived, Derived, OnTheLeft>(matrix.derived(), derived());
|
||||
return Product<Derived, MatrixDerived, LazyProduct>(derived(),matrix.derived());
|
||||
}
|
||||
|
||||
inline const DiagonalWrapper<const CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const DiagonalVectorType> >
|
||||
typedef DiagonalWrapper<const CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const DiagonalVectorType> > InverseReturnType;
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const InverseReturnType
|
||||
inverse() const
|
||||
{
|
||||
return diagonal().cwiseInverse();
|
||||
return InverseReturnType(diagonal().cwiseInverse());
|
||||
}
|
||||
|
||||
inline const DiagonalWrapper<const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DiagonalVectorType> >
|
||||
typedef DiagonalWrapper<const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DiagonalVectorType> > ScalarMultipleReturnType;
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const ScalarMultipleReturnType
|
||||
operator*(const Scalar& scalar) const
|
||||
{
|
||||
return diagonal() * scalar;
|
||||
return ScalarMultipleReturnType(diagonal() * scalar);
|
||||
}
|
||||
friend inline const DiagonalWrapper<const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DiagonalVectorType> >
|
||||
EIGEN_DEVICE_FUNC
|
||||
friend inline const ScalarMultipleReturnType
|
||||
operator*(const Scalar& scalar, const DiagonalBase& other)
|
||||
{
|
||||
return other.diagonal() * scalar;
|
||||
return ScalarMultipleReturnType(other.diagonal() * scalar);
|
||||
}
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
template<typename OtherDerived>
|
||||
bool isApprox(const DiagonalBase<OtherDerived>& other, typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) const
|
||||
{
|
||||
return diagonal().isApprox(other.diagonal(), precision);
|
||||
}
|
||||
template<typename OtherDerived>
|
||||
bool isApprox(const MatrixBase<OtherDerived>& other, typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) const
|
||||
{
|
||||
return toDenseMatrix().isApprox(other, precision);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
template<typename DenseDerived>
|
||||
void DiagonalBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
|
||||
{
|
||||
other.setZero();
|
||||
other.diagonal() = diagonal();
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \class DiagonalMatrix
|
||||
@@ -124,10 +107,9 @@ struct traits<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> >
|
||||
: traits<Matrix<_Scalar,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> >
|
||||
{
|
||||
typedef Matrix<_Scalar,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1> DiagonalVectorType;
|
||||
typedef Dense StorageKind;
|
||||
typedef DenseIndex Index;
|
||||
typedef DiagonalShape StorageKind;
|
||||
enum {
|
||||
Flags = LvalueBit
|
||||
Flags = LvalueBit | NoPreferredStorageOrderBit
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -141,7 +123,7 @@ class DiagonalMatrix
|
||||
typedef const DiagonalMatrix& Nested;
|
||||
typedef _Scalar Scalar;
|
||||
typedef typename internal::traits<DiagonalMatrix>::StorageKind StorageKind;
|
||||
typedef typename internal::traits<DiagonalMatrix>::Index Index;
|
||||
typedef typename internal::traits<DiagonalMatrix>::StorageIndex StorageIndex;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
@@ -151,24 +133,31 @@ class DiagonalMatrix
|
||||
public:
|
||||
|
||||
/** const version of diagonal(). */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const DiagonalVectorType& diagonal() const { return m_diagonal; }
|
||||
/** \returns a reference to the stored vector of diagonal coefficients. */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline DiagonalVectorType& diagonal() { return m_diagonal; }
|
||||
|
||||
/** Default constructor without initialization */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline DiagonalMatrix() {}
|
||||
|
||||
/** Constructs a diagonal matrix with given dimension */
|
||||
inline DiagonalMatrix(Index dim) : m_diagonal(dim) {}
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit inline DiagonalMatrix(Index dim) : m_diagonal(dim) {}
|
||||
|
||||
/** 2D constructor. */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline DiagonalMatrix(const Scalar& x, const Scalar& y) : m_diagonal(x,y) {}
|
||||
|
||||
/** 3D constructor. */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {}
|
||||
|
||||
/** Copy constructor. */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline DiagonalMatrix(const DiagonalBase<OtherDerived>& other) : m_diagonal(other.diagonal()) {}
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
@@ -178,11 +167,13 @@ class DiagonalMatrix
|
||||
|
||||
/** generic constructor from expression of the diagonal coefficients */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit inline DiagonalMatrix(const MatrixBase<OtherDerived>& other) : m_diagonal(other)
|
||||
{}
|
||||
|
||||
/** Copy operator. */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
DiagonalMatrix& operator=(const DiagonalBase<OtherDerived>& other)
|
||||
{
|
||||
m_diagonal = other.diagonal();
|
||||
@@ -193,6 +184,7 @@ class DiagonalMatrix
|
||||
/** This is a special case of the templated operator=. Its purpose is to
|
||||
* prevent a default operator= from hiding the templated operator=.
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
DiagonalMatrix& operator=(const DiagonalMatrix& other)
|
||||
{
|
||||
m_diagonal = other.diagonal();
|
||||
@@ -201,14 +193,19 @@ class DiagonalMatrix
|
||||
#endif
|
||||
|
||||
/** Resizes to given size. */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline void resize(Index size) { m_diagonal.resize(size); }
|
||||
/** Sets all coefficients to zero. */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline void setZero() { m_diagonal.setZero(); }
|
||||
/** Resizes and sets all coefficients to zero. */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline void setZero(Index size) { m_diagonal.setZero(size); }
|
||||
/** Sets this matrix to be the identity matrix of the current size. */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline void setIdentity() { m_diagonal.setOnes(); }
|
||||
/** Sets this matrix to be the identity matrix of the given size. */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline void setIdentity(Index size) { m_diagonal.setOnes(size); }
|
||||
};
|
||||
|
||||
@@ -232,14 +229,15 @@ struct traits<DiagonalWrapper<_DiagonalVectorType> >
|
||||
{
|
||||
typedef _DiagonalVectorType DiagonalVectorType;
|
||||
typedef typename DiagonalVectorType::Scalar Scalar;
|
||||
typedef typename DiagonalVectorType::Index Index;
|
||||
typedef typename DiagonalVectorType::StorageKind StorageKind;
|
||||
typedef typename DiagonalVectorType::StorageIndex StorageIndex;
|
||||
typedef DiagonalShape StorageKind;
|
||||
typedef typename traits<DiagonalVectorType>::XprKind XprKind;
|
||||
enum {
|
||||
RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
|
||||
ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
|
||||
MaxRowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
|
||||
MaxColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
|
||||
Flags = traits<DiagonalVectorType>::Flags & LvalueBit
|
||||
MaxRowsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
|
||||
MaxColsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
|
||||
Flags = (traits<DiagonalVectorType>::Flags & LvalueBit) | NoPreferredStorageOrderBit
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -255,9 +253,11 @@ class DiagonalWrapper
|
||||
#endif
|
||||
|
||||
/** Constructor from expression of diagonal coefficients to wrap. */
|
||||
inline DiagonalWrapper(DiagonalVectorType& a_diagonal) : m_diagonal(a_diagonal) {}
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit inline DiagonalWrapper(DiagonalVectorType& a_diagonal) : m_diagonal(a_diagonal) {}
|
||||
|
||||
/** \returns a const reference to the wrapped expression of diagonal coefficients. */
|
||||
EIGEN_DEVICE_FUNC
|
||||
const DiagonalVectorType& diagonal() const { return m_diagonal; }
|
||||
|
||||
protected:
|
||||
@@ -277,7 +277,7 @@ template<typename Derived>
|
||||
inline const DiagonalWrapper<const Derived>
|
||||
MatrixBase<Derived>::asDiagonal() const
|
||||
{
|
||||
return derived();
|
||||
return DiagonalWrapper<const Derived>(derived());
|
||||
}
|
||||
|
||||
/** \returns true if *this is approximately equal to a diagonal matrix,
|
||||
@@ -308,6 +308,33 @@ bool MatrixBase<Derived>::isDiagonal(const RealScalar& prec) const
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<> struct storage_kind_to_shape<DiagonalShape> { typedef DiagonalShape Shape; };
|
||||
|
||||
struct Diagonal2Dense {};
|
||||
|
||||
template<> struct AssignmentKind<DenseShape,DiagonalShape> { typedef Diagonal2Dense Kind; };
|
||||
|
||||
// Diagonal matrix to Dense assignment
|
||||
template< typename DstXprType, typename SrcXprType, typename Functor, typename Scalar>
|
||||
struct Assignment<DstXprType, SrcXprType, Functor, Diagonal2Dense, Scalar>
|
||||
{
|
||||
static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar> &/*func*/)
|
||||
{
|
||||
dst.setZero();
|
||||
dst.diagonal() = src.diagonal();
|
||||
}
|
||||
|
||||
static void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<typename DstXprType::Scalar> &/*func*/)
|
||||
{ dst.diagonal() += src.diagonal(); }
|
||||
|
||||
static void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<typename DstXprType::Scalar> &/*func*/)
|
||||
{ dst.diagonal() -= src.diagonal(); }
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_DIAGONALMATRIX_H
|
||||
|
||||
@@ -13,116 +13,14 @@
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
template<typename MatrixType, typename DiagonalType, int ProductOrder>
|
||||
struct traits<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> >
|
||||
: traits<MatrixType>
|
||||
{
|
||||
typedef typename scalar_product_traits<typename MatrixType::Scalar, typename DiagonalType::Scalar>::ReturnType Scalar;
|
||||
enum {
|
||||
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
|
||||
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
|
||||
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
|
||||
|
||||
_StorageOrder = MatrixType::Flags & RowMajorBit ? RowMajor : ColMajor,
|
||||
_ScalarAccessOnDiag = !((int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheLeft)
|
||||
||(int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheRight)),
|
||||
_SameTypes = is_same<typename MatrixType::Scalar, typename DiagonalType::Scalar>::value,
|
||||
// FIXME currently we need same types, but in the future the next rule should be the one
|
||||
//_Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagonalType::DiagonalVectorType::Flags)&PacketAccessBit))),
|
||||
_Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && _SameTypes && (_ScalarAccessOnDiag || (bool(int(DiagonalType::DiagonalVectorType::Flags)&PacketAccessBit))),
|
||||
_LinearAccessMask = (RowsAtCompileTime==1 || ColsAtCompileTime==1) ? LinearAccessBit : 0,
|
||||
|
||||
Flags = ((HereditaryBits|_LinearAccessMask) & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0) | AlignedBit,//(int(MatrixType::Flags)&int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit),
|
||||
CoeffReadCost = NumTraits<Scalar>::MulCost + MatrixType::CoeffReadCost + DiagonalType::DiagonalVectorType::CoeffReadCost
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
template<typename MatrixType, typename DiagonalType, int ProductOrder>
|
||||
class DiagonalProduct : internal::no_assignment_operator,
|
||||
public MatrixBase<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef MatrixBase<DiagonalProduct> Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(DiagonalProduct)
|
||||
|
||||
inline DiagonalProduct(const MatrixType& matrix, const DiagonalType& diagonal)
|
||||
: m_matrix(matrix), m_diagonal(diagonal)
|
||||
{
|
||||
eigen_assert(diagonal.diagonal().size() == (ProductOrder == OnTheLeft ? matrix.rows() : matrix.cols()));
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE Index rows() const { return m_matrix.rows(); }
|
||||
EIGEN_STRONG_INLINE Index cols() const { return m_matrix.cols(); }
|
||||
|
||||
EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const
|
||||
{
|
||||
return m_diagonal.diagonal().coeff(ProductOrder == OnTheLeft ? row : col) * m_matrix.coeff(row, col);
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE const Scalar coeff(Index idx) const
|
||||
{
|
||||
enum {
|
||||
StorageOrder = int(MatrixType::Flags) & RowMajorBit ? RowMajor : ColMajor
|
||||
};
|
||||
return coeff(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx);
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
|
||||
{
|
||||
enum {
|
||||
StorageOrder = Flags & RowMajorBit ? RowMajor : ColMajor
|
||||
};
|
||||
const Index indexInDiagonalVector = ProductOrder == OnTheLeft ? row : col;
|
||||
return packet_impl<LoadMode>(row,col,indexInDiagonalVector,typename internal::conditional<
|
||||
((int(StorageOrder) == RowMajor && int(ProductOrder) == OnTheLeft)
|
||||
||(int(StorageOrder) == ColMajor && int(ProductOrder) == OnTheRight)), internal::true_type, internal::false_type>::type());
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
EIGEN_STRONG_INLINE PacketScalar packet(Index idx) const
|
||||
{
|
||||
enum {
|
||||
StorageOrder = int(MatrixType::Flags) & RowMajorBit ? RowMajor : ColMajor
|
||||
};
|
||||
return packet<LoadMode>(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx);
|
||||
}
|
||||
|
||||
protected:
|
||||
template<int LoadMode>
|
||||
EIGEN_STRONG_INLINE PacketScalar packet_impl(Index row, Index col, Index id, internal::true_type) const
|
||||
{
|
||||
return internal::pmul(m_matrix.template packet<LoadMode>(row, col),
|
||||
internal::pset1<PacketScalar>(m_diagonal.diagonal().coeff(id)));
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
EIGEN_STRONG_INLINE PacketScalar packet_impl(Index row, Index col, Index id, internal::false_type) const
|
||||
{
|
||||
enum {
|
||||
InnerSize = (MatrixType::Flags & RowMajorBit) ? MatrixType::ColsAtCompileTime : MatrixType::RowsAtCompileTime,
|
||||
DiagonalVectorPacketLoadMode = (LoadMode == Aligned && (((InnerSize%16) == 0) || (int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit)==AlignedBit) ? Aligned : Unaligned)
|
||||
};
|
||||
return internal::pmul(m_matrix.template packet<LoadMode>(row, col),
|
||||
m_diagonal.diagonal().template packet<DiagonalVectorPacketLoadMode>(id));
|
||||
}
|
||||
|
||||
typename MatrixType::Nested m_matrix;
|
||||
typename DiagonalType::Nested m_diagonal;
|
||||
};
|
||||
|
||||
/** \returns the diagonal matrix product of \c *this by the diagonal matrix \a diagonal.
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename DiagonalDerived>
|
||||
inline const DiagonalProduct<Derived, DiagonalDerived, OnTheRight>
|
||||
inline const Product<Derived, DiagonalDerived, LazyProduct>
|
||||
MatrixBase<Derived>::operator*(const DiagonalBase<DiagonalDerived> &a_diagonal) const
|
||||
{
|
||||
return DiagonalProduct<Derived, DiagonalDerived, OnTheRight>(derived(), a_diagonal.derived());
|
||||
return Product<Derived, DiagonalDerived, LazyProduct>(derived(),a_diagonal.derived());
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -29,6 +29,7 @@ template<typename T, typename U,
|
||||
struct dot_nocheck
|
||||
{
|
||||
typedef typename scalar_product_traits<typename traits<T>::Scalar,typename traits<U>::Scalar>::ReturnType ResScalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
|
||||
{
|
||||
return a.template binaryExpr<scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> >(b).sum();
|
||||
@@ -39,6 +40,7 @@ template<typename T, typename U>
|
||||
struct dot_nocheck<T, U, true>
|
||||
{
|
||||
typedef typename scalar_product_traits<typename traits<T>::Scalar,typename traits<U>::Scalar>::ReturnType ResScalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
|
||||
{
|
||||
return a.transpose().template binaryExpr<scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> >(b).sum();
|
||||
@@ -59,6 +61,7 @@ struct dot_nocheck<T, U, true>
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename internal::scalar_product_traits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType
|
||||
MatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
|
||||
{
|
||||
@@ -73,34 +76,6 @@ MatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
|
||||
return internal::dot_nocheck<Derived,OtherDerived>::run(*this, other);
|
||||
}
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
/** \returns the dot product of *this with other, with the Eigen2 convention that the dot product is linear in the first variable
|
||||
* (conjugating the second variable). Of course this only makes a difference in the complex case.
|
||||
*
|
||||
* This method is only available in EIGEN2_SUPPORT mode.
|
||||
*
|
||||
* \only_for_vectors
|
||||
*
|
||||
* \sa dot()
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
typename internal::traits<Derived>::Scalar
|
||||
MatrixBase<Derived>::eigen2_dot(const MatrixBase<OtherDerived>& other) const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
||||
EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
|
||||
EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
|
||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||
|
||||
eigen_assert(size() == other.size());
|
||||
|
||||
return internal::dot_nocheck<OtherDerived,Derived>::run(other,*this);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//---------- implementation of L2 norm and related functions ----------
|
||||
|
||||
/** \returns, for vectors, the squared \em l2 norm of \c *this, and for matrices the Frobenius norm.
|
||||
@@ -124,7 +99,7 @@ EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scala
|
||||
template<typename Derived>
|
||||
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
|
||||
{
|
||||
using std::sqrt;
|
||||
EIGEN_USING_STD_MATH(sqrt)
|
||||
return sqrt(squaredNorm());
|
||||
}
|
||||
|
||||
@@ -138,8 +113,7 @@ template<typename Derived>
|
||||
inline const typename MatrixBase<Derived>::PlainObject
|
||||
MatrixBase<Derived>::normalized() const
|
||||
{
|
||||
typedef typename internal::nested<Derived>::type Nested;
|
||||
typedef typename internal::remove_reference<Nested>::type _Nested;
|
||||
typedef typename internal::nested_eval<Derived,2>::type _Nested;
|
||||
_Nested n(derived());
|
||||
return n / n.norm();
|
||||
}
|
||||
@@ -164,9 +138,10 @@ template<typename Derived, int p>
|
||||
struct lpNorm_selector
|
||||
{
|
||||
typedef typename NumTraits<typename traits<Derived>::Scalar>::Real RealScalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline RealScalar run(const MatrixBase<Derived>& m)
|
||||
{
|
||||
using std::pow;
|
||||
EIGEN_USING_STD_MATH(pow)
|
||||
return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p);
|
||||
}
|
||||
};
|
||||
@@ -174,6 +149,7 @@ struct lpNorm_selector
|
||||
template<typename Derived>
|
||||
struct lpNorm_selector<Derived, 1>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
|
||||
{
|
||||
return m.cwiseAbs().sum();
|
||||
@@ -183,6 +159,7 @@ struct lpNorm_selector<Derived, 1>
|
||||
template<typename Derived>
|
||||
struct lpNorm_selector<Derived, 2>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
|
||||
{
|
||||
return m.norm();
|
||||
@@ -192,6 +169,7 @@ struct lpNorm_selector<Derived, 2>
|
||||
template<typename Derived>
|
||||
struct lpNorm_selector<Derived, Infinity>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
|
||||
{
|
||||
return m.cwiseAbs().maxCoeff();
|
||||
@@ -227,8 +205,8 @@ template<typename OtherDerived>
|
||||
bool MatrixBase<Derived>::isOrthogonal
|
||||
(const MatrixBase<OtherDerived>& other, const RealScalar& prec) const
|
||||
{
|
||||
typename internal::nested<Derived,2>::type nested(derived());
|
||||
typename internal::nested<OtherDerived,2>::type otherNested(other.derived());
|
||||
typename internal::nested_eval<Derived,2>::type nested(derived());
|
||||
typename internal::nested_eval<OtherDerived,2>::type otherNested(other.derived());
|
||||
return numext::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm();
|
||||
}
|
||||
|
||||
@@ -246,13 +224,13 @@ bool MatrixBase<Derived>::isOrthogonal
|
||||
template<typename Derived>
|
||||
bool MatrixBase<Derived>::isUnitary(const RealScalar& prec) const
|
||||
{
|
||||
typename Derived::Nested nested(derived());
|
||||
typename internal::nested_eval<Derived,1>::type self(derived());
|
||||
for(Index i = 0; i < cols(); ++i)
|
||||
{
|
||||
if(!internal::isApprox(nested.col(i).squaredNorm(), static_cast<RealScalar>(1), prec))
|
||||
if(!internal::isApprox(self.col(i).squaredNorm(), static_cast<RealScalar>(1), prec))
|
||||
return false;
|
||||
for(Index j = 0; j < i; ++j)
|
||||
if(!internal::isMuchSmallerThan(nested.col(i).dot(nested.col(j)), static_cast<Scalar>(1), prec))
|
||||
if(!internal::isMuchSmallerThan(self.col(i).dot(self.col(j)), static_cast<Scalar>(1), prec))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
/** Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T).
|
||||
/** \class EigenBase
|
||||
*
|
||||
* Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T).
|
||||
*
|
||||
* In other words, an EigenBase object is an object that can be copied into a MatrixBase.
|
||||
*
|
||||
@@ -26,34 +28,52 @@ namespace Eigen {
|
||||
template<typename Derived> struct EigenBase
|
||||
{
|
||||
// typedef typename internal::plain_matrix_type<Derived>::type PlainObject;
|
||||
|
||||
/** \brief The interface type of indices
|
||||
* \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
|
||||
* \deprecated Since Eigen 3.3, its usage is deprecated. Use Eigen::Index instead.
|
||||
* \sa StorageIndex, \ref TopicPreprocessorDirectives.
|
||||
*/
|
||||
typedef Eigen::Index Index;
|
||||
|
||||
// FIXME is it needed?
|
||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||
typedef typename internal::traits<Derived>::Index Index;
|
||||
|
||||
/** \returns a reference to the derived object */
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& derived() { return *static_cast<Derived*>(this); }
|
||||
/** \returns a const reference to the derived object */
|
||||
EIGEN_DEVICE_FUNC
|
||||
const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Derived& const_cast_derived() const
|
||||
{ return *static_cast<Derived*>(const_cast<EigenBase*>(this)); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Derived& const_derived() const
|
||||
{ return *static_cast<const Derived*>(this); }
|
||||
|
||||
/** \returns the number of rows. \sa cols(), RowsAtCompileTime */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index rows() const { return derived().rows(); }
|
||||
/** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index cols() const { return derived().cols(); }
|
||||
/** \returns the number of coefficients, which is rows()*cols().
|
||||
* \sa rows(), cols(), SizeAtCompileTime. */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index size() const { return rows() * cols(); }
|
||||
|
||||
/** \internal Don't use it, but do the equivalent: \code dst = *this; \endcode */
|
||||
template<typename Dest> inline void evalTo(Dest& dst) const
|
||||
template<typename Dest>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline void evalTo(Dest& dst) const
|
||||
{ derived().evalTo(dst); }
|
||||
|
||||
/** \internal Don't use it, but do the equivalent: \code dst += *this; \endcode */
|
||||
template<typename Dest> inline void addTo(Dest& dst) const
|
||||
template<typename Dest>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline void addTo(Dest& dst) const
|
||||
{
|
||||
// This is the default implementation,
|
||||
// derived class can reimplement it in a more optimized way.
|
||||
@@ -63,7 +83,9 @@ template<typename Derived> struct EigenBase
|
||||
}
|
||||
|
||||
/** \internal Don't use it, but do the equivalent: \code dst -= *this; \endcode */
|
||||
template<typename Dest> inline void subTo(Dest& dst) const
|
||||
template<typename Dest>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline void subTo(Dest& dst) const
|
||||
{
|
||||
// This is the default implementation,
|
||||
// derived class can reimplement it in a more optimized way.
|
||||
@@ -73,7 +95,8 @@ template<typename Derived> struct EigenBase
|
||||
}
|
||||
|
||||
/** \internal Don't use it, but do the equivalent: \code dst.applyOnTheRight(*this); \endcode */
|
||||
template<typename Dest> inline void applyThisOnTheRight(Dest& dst) const
|
||||
template<typename Dest>
|
||||
EIGEN_DEVICE_FUNC inline void applyThisOnTheRight(Dest& dst) const
|
||||
{
|
||||
// This is the default implementation,
|
||||
// derived class can reimplement it in a more optimized way.
|
||||
@@ -81,7 +104,8 @@ template<typename Derived> struct EigenBase
|
||||
}
|
||||
|
||||
/** \internal Don't use it, but do the equivalent: \code dst.applyOnTheLeft(*this); \endcode */
|
||||
template<typename Dest> inline void applyThisOnTheLeft(Dest& dst) const
|
||||
template<typename Dest>
|
||||
EIGEN_DEVICE_FUNC inline void applyThisOnTheLeft(Dest& dst) const
|
||||
{
|
||||
// This is the default implementation,
|
||||
// derived class can reimplement it in a more optimized way.
|
||||
@@ -106,7 +130,7 @@ template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
Derived& DenseBase<Derived>::operator=(const EigenBase<OtherDerived> &other)
|
||||
{
|
||||
other.derived().evalTo(derived());
|
||||
call_assignment(derived(), other.derived());
|
||||
return derived();
|
||||
}
|
||||
|
||||
@@ -114,7 +138,7 @@ template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
Derived& DenseBase<Derived>::operator+=(const EigenBase<OtherDerived> &other)
|
||||
{
|
||||
other.derived().addTo(derived());
|
||||
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar>());
|
||||
return derived();
|
||||
}
|
||||
|
||||
@@ -122,40 +146,10 @@ template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
Derived& DenseBase<Derived>::operator-=(const EigenBase<OtherDerived> &other)
|
||||
{
|
||||
other.derived().subTo(derived());
|
||||
call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar>());
|
||||
return derived();
|
||||
}
|
||||
|
||||
/** replaces \c *this by \c *this * \a other.
|
||||
*
|
||||
* \returns a reference to \c *this
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
inline Derived&
|
||||
MatrixBase<Derived>::operator*=(const EigenBase<OtherDerived> &other)
|
||||
{
|
||||
other.derived().applyThisOnTheRight(derived());
|
||||
return derived();
|
||||
}
|
||||
|
||||
/** replaces \c *this by \c *this * \a other. It is equivalent to MatrixBase::operator*=().
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
inline void MatrixBase<Derived>::applyOnTheRight(const EigenBase<OtherDerived> &other)
|
||||
{
|
||||
other.derived().applyThisOnTheRight(derived());
|
||||
}
|
||||
|
||||
/** replaces \c *this by \c *this * \a other. */
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
inline void MatrixBase<Derived>::applyOnTheLeft(const EigenBase<OtherDerived> &other)
|
||||
{
|
||||
other.derived().applyThisOnTheLeft(derived());
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_EIGENBASE_H
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef EIGEN_FLAGGED_H
|
||||
#define EIGEN_FLAGGED_H
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
/** \class Flagged
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* \brief Expression with modified flags
|
||||
*
|
||||
* \param ExpressionType the type of the object of which we are modifying the flags
|
||||
* \param Added the flags added to the expression
|
||||
* \param Removed the flags removed from the expression (has priority over Added).
|
||||
*
|
||||
* This class represents an expression whose flags have been modified.
|
||||
* It is the return type of MatrixBase::flagged()
|
||||
* and most of the time this is the only way it is used.
|
||||
*
|
||||
* \sa MatrixBase::flagged()
|
||||
*/
|
||||
|
||||
namespace internal {
|
||||
template<typename ExpressionType, unsigned int Added, unsigned int Removed>
|
||||
struct traits<Flagged<ExpressionType, Added, Removed> > : traits<ExpressionType>
|
||||
{
|
||||
enum { Flags = (ExpressionType::Flags | Added) & ~Removed };
|
||||
};
|
||||
}
|
||||
|
||||
template<typename ExpressionType, unsigned int Added, unsigned int Removed> class Flagged
|
||||
: public MatrixBase<Flagged<ExpressionType, Added, Removed> >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef MatrixBase<Flagged> Base;
|
||||
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Flagged)
|
||||
typedef typename internal::conditional<internal::must_nest_by_value<ExpressionType>::ret,
|
||||
ExpressionType, const ExpressionType&>::type ExpressionTypeNested;
|
||||
typedef typename ExpressionType::InnerIterator InnerIterator;
|
||||
|
||||
inline Flagged(const ExpressionType& matrix) : m_matrix(matrix) {}
|
||||
|
||||
inline Index rows() const { return m_matrix.rows(); }
|
||||
inline Index cols() const { return m_matrix.cols(); }
|
||||
inline Index outerStride() const { return m_matrix.outerStride(); }
|
||||
inline Index innerStride() const { return m_matrix.innerStride(); }
|
||||
|
||||
inline CoeffReturnType coeff(Index row, Index col) const
|
||||
{
|
||||
return m_matrix.coeff(row, col);
|
||||
}
|
||||
|
||||
inline CoeffReturnType coeff(Index index) const
|
||||
{
|
||||
return m_matrix.coeff(index);
|
||||
}
|
||||
|
||||
inline const Scalar& coeffRef(Index row, Index col) const
|
||||
{
|
||||
return m_matrix.const_cast_derived().coeffRef(row, col);
|
||||
}
|
||||
|
||||
inline const Scalar& coeffRef(Index index) const
|
||||
{
|
||||
return m_matrix.const_cast_derived().coeffRef(index);
|
||||
}
|
||||
|
||||
inline Scalar& coeffRef(Index row, Index col)
|
||||
{
|
||||
return m_matrix.const_cast_derived().coeffRef(row, col);
|
||||
}
|
||||
|
||||
inline Scalar& coeffRef(Index index)
|
||||
{
|
||||
return m_matrix.const_cast_derived().coeffRef(index);
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
inline const PacketScalar packet(Index row, Index col) const
|
||||
{
|
||||
return m_matrix.template packet<LoadMode>(row, col);
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
inline void writePacket(Index row, Index col, const PacketScalar& x)
|
||||
{
|
||||
m_matrix.const_cast_derived().template writePacket<LoadMode>(row, col, x);
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
inline const PacketScalar packet(Index index) const
|
||||
{
|
||||
return m_matrix.template packet<LoadMode>(index);
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
inline void writePacket(Index index, const PacketScalar& x)
|
||||
{
|
||||
m_matrix.const_cast_derived().template writePacket<LoadMode>(index, x);
|
||||
}
|
||||
|
||||
const ExpressionType& _expression() const { return m_matrix; }
|
||||
|
||||
template<typename OtherDerived>
|
||||
typename ExpressionType::PlainObject solveTriangular(const MatrixBase<OtherDerived>& other) const;
|
||||
|
||||
template<typename OtherDerived>
|
||||
void solveTriangularInPlace(const MatrixBase<OtherDerived>& other) const;
|
||||
|
||||
protected:
|
||||
ExpressionTypeNested m_matrix;
|
||||
};
|
||||
|
||||
/** \returns an expression of *this with added and removed flags
|
||||
*
|
||||
* This is mostly for internal use.
|
||||
*
|
||||
* \sa class Flagged
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<unsigned int Added,unsigned int Removed>
|
||||
inline const Flagged<Derived, Added, Removed>
|
||||
DenseBase<Derived>::flagged() const
|
||||
{
|
||||
return derived();
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_FLAGGED_H
|
||||
@@ -39,29 +39,29 @@ template<typename ExpressionType> class ForceAlignedAccess
|
||||
typedef typename internal::dense_xpr_base<ForceAlignedAccess>::type Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(ForceAlignedAccess)
|
||||
|
||||
inline ForceAlignedAccess(const ExpressionType& matrix) : m_expression(matrix) {}
|
||||
EIGEN_DEVICE_FUNC explicit inline ForceAlignedAccess(const ExpressionType& matrix) : m_expression(matrix) {}
|
||||
|
||||
inline Index rows() const { return m_expression.rows(); }
|
||||
inline Index cols() const { return m_expression.cols(); }
|
||||
inline Index outerStride() const { return m_expression.outerStride(); }
|
||||
inline Index innerStride() const { return m_expression.innerStride(); }
|
||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_expression.rows(); }
|
||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_expression.cols(); }
|
||||
EIGEN_DEVICE_FUNC inline Index outerStride() const { return m_expression.outerStride(); }
|
||||
EIGEN_DEVICE_FUNC inline Index innerStride() const { return m_expression.innerStride(); }
|
||||
|
||||
inline const CoeffReturnType coeff(Index row, Index col) const
|
||||
EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index row, Index col) const
|
||||
{
|
||||
return m_expression.coeff(row, col);
|
||||
}
|
||||
|
||||
inline Scalar& coeffRef(Index row, Index col)
|
||||
EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index row, Index col)
|
||||
{
|
||||
return m_expression.const_cast_derived().coeffRef(row, col);
|
||||
}
|
||||
|
||||
inline const CoeffReturnType coeff(Index index) const
|
||||
EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index index) const
|
||||
{
|
||||
return m_expression.coeff(index);
|
||||
}
|
||||
|
||||
inline Scalar& coeffRef(Index index)
|
||||
EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index index)
|
||||
{
|
||||
return m_expression.const_cast_derived().coeffRef(index);
|
||||
}
|
||||
@@ -90,7 +90,7 @@ template<typename ExpressionType> class ForceAlignedAccess
|
||||
m_expression.const_cast_derived().template writePacket<Aligned>(index, x);
|
||||
}
|
||||
|
||||
operator const ExpressionType&() const { return m_expression; }
|
||||
EIGEN_DEVICE_FUNC operator const ExpressionType&() const { return m_expression; }
|
||||
|
||||
protected:
|
||||
const ExpressionType& m_expression;
|
||||
@@ -127,7 +127,7 @@ template<bool Enable>
|
||||
inline typename internal::add_const_on_value_type<typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type>::type
|
||||
MatrixBase<Derived>::forceAlignedAccessIf() const
|
||||
{
|
||||
return derived();
|
||||
return derived(); // FIXME This should not work but apparently is never used
|
||||
}
|
||||
|
||||
/** \returns an expression of *this with forced aligned access if \a Enable is true.
|
||||
@@ -138,7 +138,7 @@ template<bool Enable>
|
||||
inline typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type
|
||||
MatrixBase<Derived>::forceAlignedAccessIf()
|
||||
{
|
||||
return derived();
|
||||
return derived(); // FIXME This should not work but apparently is never used
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -1,985 +0,0 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef EIGEN_FUNCTORS_H
|
||||
#define EIGEN_FUNCTORS_H
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
// associative functors:
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the sum of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, MatrixBase::sum()
|
||||
*/
|
||||
template<typename Scalar> struct scalar_sum_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_sum_op)
|
||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; }
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return internal::padd(a,b); }
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const
|
||||
{ return internal::predux(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_sum_op<Scalar> > {
|
||||
enum {
|
||||
Cost = NumTraits<Scalar>::AddCost,
|
||||
PacketAccess = packet_traits<Scalar>::HasAdd
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the product of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux()
|
||||
*/
|
||||
template<typename LhsScalar,typename RhsScalar> struct scalar_product_op {
|
||||
enum {
|
||||
// TODO vectorize mixed product
|
||||
Vectorizable = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasMul && packet_traits<RhsScalar>::HasMul
|
||||
};
|
||||
typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type;
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_product_op)
|
||||
EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a * b; }
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return internal::pmul(a,b); }
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const
|
||||
{ return internal::predux_mul(a); }
|
||||
};
|
||||
template<typename LhsScalar,typename RhsScalar>
|
||||
struct functor_traits<scalar_product_op<LhsScalar,RhsScalar> > {
|
||||
enum {
|
||||
Cost = (NumTraits<LhsScalar>::MulCost + NumTraits<RhsScalar>::MulCost)/2, // rough estimate!
|
||||
PacketAccess = scalar_product_op<LhsScalar,RhsScalar>::Vectorizable
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the conjugate product of two scalars
|
||||
*
|
||||
* This is a short cut for conj(x) * y which is needed for optimization purpose; in Eigen2 support mode, this becomes x * conj(y)
|
||||
*/
|
||||
template<typename LhsScalar,typename RhsScalar> struct scalar_conj_product_op {
|
||||
|
||||
enum {
|
||||
Conj = NumTraits<LhsScalar>::IsComplex
|
||||
};
|
||||
|
||||
typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type;
|
||||
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_conj_product_op)
|
||||
EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const
|
||||
{ return conj_helper<LhsScalar,RhsScalar,Conj,false>().pmul(a,b); }
|
||||
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return conj_helper<Packet,Packet,Conj,false>().pmul(a,b); }
|
||||
};
|
||||
template<typename LhsScalar,typename RhsScalar>
|
||||
struct functor_traits<scalar_conj_product_op<LhsScalar,RhsScalar> > {
|
||||
enum {
|
||||
Cost = NumTraits<LhsScalar>::MulCost,
|
||||
PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMul
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the min of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff()
|
||||
*/
|
||||
template<typename Scalar> struct scalar_min_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_min_op)
|
||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { using std::min; return (min)(a, b); }
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return internal::pmin(a,b); }
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const
|
||||
{ return internal::predux_min(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_min_op<Scalar> > {
|
||||
enum {
|
||||
Cost = NumTraits<Scalar>::AddCost,
|
||||
PacketAccess = packet_traits<Scalar>::HasMin
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the max of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff()
|
||||
*/
|
||||
template<typename Scalar> struct scalar_max_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_max_op)
|
||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { using std::max; return (max)(a, b); }
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return internal::pmax(a,b); }
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const
|
||||
{ return internal::predux_max(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_max_op<Scalar> > {
|
||||
enum {
|
||||
Cost = NumTraits<Scalar>::AddCost,
|
||||
PacketAccess = packet_traits<Scalar>::HasMax
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the hypot of two scalars
|
||||
*
|
||||
* \sa MatrixBase::stableNorm(), class Redux
|
||||
*/
|
||||
template<typename Scalar> struct scalar_hypot_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_hypot_op)
|
||||
// typedef typename NumTraits<Scalar>::Real result_type;
|
||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const
|
||||
{
|
||||
using std::max;
|
||||
using std::min;
|
||||
using std::sqrt;
|
||||
Scalar p = (max)(_x, _y);
|
||||
Scalar q = (min)(_x, _y);
|
||||
Scalar qp = q/p;
|
||||
return p * sqrt(Scalar(1) + qp*qp);
|
||||
}
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_hypot_op<Scalar> > {
|
||||
enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess=0 };
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the pow of two scalars
|
||||
*/
|
||||
template<typename Scalar, typename OtherScalar> struct scalar_binary_pow_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_binary_pow_op)
|
||||
inline Scalar operator() (const Scalar& a, const OtherScalar& b) const { return numext::pow(a, b); }
|
||||
};
|
||||
template<typename Scalar, typename OtherScalar>
|
||||
struct functor_traits<scalar_binary_pow_op<Scalar,OtherScalar> > {
|
||||
enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false };
|
||||
};
|
||||
|
||||
// other binary functors:
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the difference of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::operator-
|
||||
*/
|
||||
template<typename Scalar> struct scalar_difference_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_difference_op)
|
||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; }
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return internal::psub(a,b); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_difference_op<Scalar> > {
|
||||
enum {
|
||||
Cost = NumTraits<Scalar>::AddCost,
|
||||
PacketAccess = packet_traits<Scalar>::HasSub
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the quotient of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, Cwise::operator/()
|
||||
*/
|
||||
template<typename LhsScalar,typename RhsScalar> struct scalar_quotient_op {
|
||||
enum {
|
||||
// TODO vectorize mixed product
|
||||
Vectorizable = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasDiv && packet_traits<RhsScalar>::HasDiv
|
||||
};
|
||||
typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type;
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_quotient_op)
|
||||
EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a / b; }
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return internal::pdiv(a,b); }
|
||||
};
|
||||
template<typename LhsScalar,typename RhsScalar>
|
||||
struct functor_traits<scalar_quotient_op<LhsScalar,RhsScalar> > {
|
||||
enum {
|
||||
Cost = (NumTraits<LhsScalar>::MulCost + NumTraits<RhsScalar>::MulCost), // rough estimate!
|
||||
PacketAccess = scalar_quotient_op<LhsScalar,RhsScalar>::Vectorizable
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the and of two booleans
|
||||
*
|
||||
* \sa class CwiseBinaryOp, ArrayBase::operator&&
|
||||
*/
|
||||
struct scalar_boolean_and_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_and_op)
|
||||
EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a && b; }
|
||||
};
|
||||
template<> struct functor_traits<scalar_boolean_and_op> {
|
||||
enum {
|
||||
Cost = NumTraits<bool>::AddCost,
|
||||
PacketAccess = false
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the or of two booleans
|
||||
*
|
||||
* \sa class CwiseBinaryOp, ArrayBase::operator||
|
||||
*/
|
||||
struct scalar_boolean_or_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_or_op)
|
||||
EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a || b; }
|
||||
};
|
||||
template<> struct functor_traits<scalar_boolean_or_op> {
|
||||
enum {
|
||||
Cost = NumTraits<bool>::AddCost,
|
||||
PacketAccess = false
|
||||
};
|
||||
};
|
||||
|
||||
// unary functors:
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the opposite of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::operator-
|
||||
*/
|
||||
template<typename Scalar> struct scalar_opposite_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_opposite_op)
|
||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; }
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
|
||||
{ return internal::pnegate(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_opposite_op<Scalar> >
|
||||
{ enum {
|
||||
Cost = NumTraits<Scalar>::AddCost,
|
||||
PacketAccess = packet_traits<Scalar>::HasNegate };
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the absolute value of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, Cwise::abs
|
||||
*/
|
||||
template<typename Scalar> struct scalar_abs_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_abs_op)
|
||||
typedef typename NumTraits<Scalar>::Real result_type;
|
||||
EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { using std::abs; return abs(a); }
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
|
||||
{ return internal::pabs(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_abs_op<Scalar> >
|
||||
{
|
||||
enum {
|
||||
Cost = NumTraits<Scalar>::AddCost,
|
||||
PacketAccess = packet_traits<Scalar>::HasAbs
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the squared absolute value of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, Cwise::abs2
|
||||
*/
|
||||
template<typename Scalar> struct scalar_abs2_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_abs2_op)
|
||||
typedef typename NumTraits<Scalar>::Real result_type;
|
||||
EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return numext::abs2(a); }
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
|
||||
{ return internal::pmul(a,a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_abs2_op<Scalar> >
|
||||
{ enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasAbs2 }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the conjugate of a complex value
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::conjugate()
|
||||
*/
|
||||
template<typename Scalar> struct scalar_conjugate_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_conjugate_op)
|
||||
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { using numext::conj; return conj(a); }
|
||||
template<typename Packet>
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pconj(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_conjugate_op<Scalar> >
|
||||
{
|
||||
enum {
|
||||
Cost = NumTraits<Scalar>::IsComplex ? NumTraits<Scalar>::AddCost : 0,
|
||||
PacketAccess = packet_traits<Scalar>::HasConj
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to cast a scalar to another type
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::cast()
|
||||
*/
|
||||
template<typename Scalar, typename NewType>
|
||||
struct scalar_cast_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_cast_op)
|
||||
typedef NewType result_type;
|
||||
EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return cast<Scalar, NewType>(a); }
|
||||
};
|
||||
template<typename Scalar, typename NewType>
|
||||
struct functor_traits<scalar_cast_op<Scalar,NewType> >
|
||||
{ enum { Cost = is_same<Scalar, NewType>::value ? 0 : NumTraits<NewType>::AddCost, PacketAccess = false }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to extract the real part of a complex
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::real()
|
||||
*/
|
||||
template<typename Scalar>
|
||||
struct scalar_real_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_real_op)
|
||||
typedef typename NumTraits<Scalar>::Real result_type;
|
||||
EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::real(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_real_op<Scalar> >
|
||||
{ enum { Cost = 0, PacketAccess = false }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to extract the imaginary part of a complex
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::imag()
|
||||
*/
|
||||
template<typename Scalar>
|
||||
struct scalar_imag_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_op)
|
||||
typedef typename NumTraits<Scalar>::Real result_type;
|
||||
EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::imag(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_imag_op<Scalar> >
|
||||
{ enum { Cost = 0, PacketAccess = false }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to extract the real part of a complex as a reference
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::real()
|
||||
*/
|
||||
template<typename Scalar>
|
||||
struct scalar_real_ref_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_real_ref_op)
|
||||
typedef typename NumTraits<Scalar>::Real result_type;
|
||||
EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::real_ref(*const_cast<Scalar*>(&a)); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_real_ref_op<Scalar> >
|
||||
{ enum { Cost = 0, PacketAccess = false }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to extract the imaginary part of a complex as a reference
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::imag()
|
||||
*/
|
||||
template<typename Scalar>
|
||||
struct scalar_imag_ref_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_ref_op)
|
||||
typedef typename NumTraits<Scalar>::Real result_type;
|
||||
EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::imag_ref(*const_cast<Scalar*>(&a)); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_imag_ref_op<Scalar> >
|
||||
{ enum { Cost = 0, PacketAccess = false }; };
|
||||
|
||||
/** \internal
|
||||
*
|
||||
* \brief Template functor to compute the exponential of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, Cwise::exp()
|
||||
*/
|
||||
template<typename Scalar> struct scalar_exp_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_exp_op)
|
||||
inline const Scalar operator() (const Scalar& a) const { using std::exp; return exp(a); }
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
inline Packet packetOp(const Packet& a) const { return internal::pexp(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_exp_op<Scalar> >
|
||||
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasExp }; };
|
||||
|
||||
/** \internal
|
||||
*
|
||||
* \brief Template functor to compute the logarithm of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, Cwise::log()
|
||||
*/
|
||||
template<typename Scalar> struct scalar_log_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_log_op)
|
||||
inline const Scalar operator() (const Scalar& a) const { using std::log; return log(a); }
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
inline Packet packetOp(const Packet& a) const { return internal::plog(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_log_op<Scalar> >
|
||||
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasLog }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to multiply a scalar by a fixed other one
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::operator*, MatrixBase::operator/
|
||||
*/
|
||||
/* NOTE why doing the pset1() in packetOp *is* an optimization ?
|
||||
* indeed it seems better to declare m_other as a Packet and do the pset1() once
|
||||
* in the constructor. However, in practice:
|
||||
* - GCC does not like m_other as a Packet and generate a load every time it needs it
|
||||
* - on the other hand GCC is able to moves the pset1() outside the loop :)
|
||||
* - simpler code ;)
|
||||
* (ICC and gcc 4.4 seems to perform well in both cases, the issue is visible with y = a*x + b*y)
|
||||
*/
|
||||
template<typename Scalar>
|
||||
struct scalar_multiple_op {
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
// FIXME default copy constructors seems bugged with std::complex<>
|
||||
EIGEN_STRONG_INLINE scalar_multiple_op(const scalar_multiple_op& other) : m_other(other.m_other) { }
|
||||
EIGEN_STRONG_INLINE scalar_multiple_op(const Scalar& other) : m_other(other) { }
|
||||
EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; }
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
|
||||
{ return internal::pmul(a, pset1<Packet>(m_other)); }
|
||||
typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other;
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_multiple_op<Scalar> >
|
||||
{ enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
|
||||
|
||||
template<typename Scalar1, typename Scalar2>
|
||||
struct scalar_multiple2_op {
|
||||
typedef typename scalar_product_traits<Scalar1,Scalar2>::ReturnType result_type;
|
||||
EIGEN_STRONG_INLINE scalar_multiple2_op(const scalar_multiple2_op& other) : m_other(other.m_other) { }
|
||||
EIGEN_STRONG_INLINE scalar_multiple2_op(const Scalar2& other) : m_other(other) { }
|
||||
EIGEN_STRONG_INLINE result_type operator() (const Scalar1& a) const { return a * m_other; }
|
||||
typename add_const_on_value_type<typename NumTraits<Scalar2>::Nested>::type m_other;
|
||||
};
|
||||
template<typename Scalar1,typename Scalar2>
|
||||
struct functor_traits<scalar_multiple2_op<Scalar1,Scalar2> >
|
||||
{ enum { Cost = NumTraits<Scalar1>::MulCost, PacketAccess = false }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to divide a scalar by a fixed other one
|
||||
*
|
||||
* This functor is used to implement the quotient of a matrix by
|
||||
* a scalar where the scalar type is not necessarily a floating point type.
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::operator/
|
||||
*/
|
||||
template<typename Scalar>
|
||||
struct scalar_quotient1_op {
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
// FIXME default copy constructors seems bugged with std::complex<>
|
||||
EIGEN_STRONG_INLINE scalar_quotient1_op(const scalar_quotient1_op& other) : m_other(other.m_other) { }
|
||||
EIGEN_STRONG_INLINE scalar_quotient1_op(const Scalar& other) : m_other(other) {}
|
||||
EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a / m_other; }
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
|
||||
{ return internal::pdiv(a, pset1<Packet>(m_other)); }
|
||||
typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other;
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_quotient1_op<Scalar> >
|
||||
{ enum { Cost = 2 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasDiv }; };
|
||||
|
||||
// nullary functors
|
||||
|
||||
template<typename Scalar>
|
||||
struct scalar_constant_op {
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
EIGEN_STRONG_INLINE scalar_constant_op(const scalar_constant_op& other) : m_other(other.m_other) { }
|
||||
EIGEN_STRONG_INLINE scalar_constant_op(const Scalar& other) : m_other(other) { }
|
||||
template<typename Index>
|
||||
EIGEN_STRONG_INLINE const Scalar operator() (Index, Index = 0) const { return m_other; }
|
||||
template<typename Index>
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(Index, Index = 0) const { return internal::pset1<Packet>(m_other); }
|
||||
const Scalar m_other;
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_constant_op<Scalar> >
|
||||
// FIXME replace this packet test by a safe one
|
||||
{ enum { Cost = 1, PacketAccess = packet_traits<Scalar>::Vectorizable, IsRepeatable = true }; };
|
||||
|
||||
template<typename Scalar> struct scalar_identity_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_identity_op)
|
||||
template<typename Index>
|
||||
EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const { return row==col ? Scalar(1) : Scalar(0); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_identity_op<Scalar> >
|
||||
{ enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true }; };
|
||||
|
||||
template <typename Scalar, bool RandomAccess> struct linspaced_op_impl;
|
||||
|
||||
// linear access for packet ops:
|
||||
// 1) initialization
|
||||
// base = [low, ..., low] + ([step, ..., step] * [-size, ..., 0])
|
||||
// 2) each step (where size is 1 for coeff access or PacketSize for packet access)
|
||||
// base += [size*step, ..., size*step]
|
||||
//
|
||||
// TODO: Perhaps it's better to initialize lazily (so not in the constructor but in packetOp)
|
||||
// in order to avoid the padd() in operator() ?
|
||||
template <typename Scalar>
|
||||
struct linspaced_op_impl<Scalar,false>
|
||||
{
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
|
||||
linspaced_op_impl(const Scalar& low, const Scalar& step) :
|
||||
m_low(low), m_step(step),
|
||||
m_packetStep(pset1<Packet>(packet_traits<Scalar>::size*step)),
|
||||
m_base(padd(pset1<Packet>(low), pmul(pset1<Packet>(step),plset<Scalar>(-packet_traits<Scalar>::size)))) {}
|
||||
|
||||
template<typename Index>
|
||||
EIGEN_STRONG_INLINE const Scalar operator() (Index i) const
|
||||
{
|
||||
m_base = padd(m_base, pset1<Packet>(m_step));
|
||||
return m_low+Scalar(i)*m_step;
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(Index) const { return m_base = padd(m_base,m_packetStep); }
|
||||
|
||||
const Scalar m_low;
|
||||
const Scalar m_step;
|
||||
const Packet m_packetStep;
|
||||
mutable Packet m_base;
|
||||
};
|
||||
|
||||
// random access for packet ops:
|
||||
// 1) each step
|
||||
// [low, ..., low] + ( [step, ..., step] * ( [i, ..., i] + [0, ..., size] ) )
|
||||
template <typename Scalar>
|
||||
struct linspaced_op_impl<Scalar,true>
|
||||
{
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
|
||||
linspaced_op_impl(const Scalar& low, const Scalar& step) :
|
||||
m_low(low), m_step(step),
|
||||
m_lowPacket(pset1<Packet>(m_low)), m_stepPacket(pset1<Packet>(m_step)), m_interPacket(plset<Scalar>(0)) {}
|
||||
|
||||
template<typename Index>
|
||||
EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return m_low+i*m_step; }
|
||||
|
||||
template<typename Index>
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(Index i) const
|
||||
{ return internal::padd(m_lowPacket, pmul(m_stepPacket, padd(pset1<Packet>(i),m_interPacket))); }
|
||||
|
||||
const Scalar m_low;
|
||||
const Scalar m_step;
|
||||
const Packet m_lowPacket;
|
||||
const Packet m_stepPacket;
|
||||
const Packet m_interPacket;
|
||||
};
|
||||
|
||||
// ----- Linspace functor ----------------------------------------------------------------
|
||||
|
||||
// Forward declaration (we default to random access which does not really give
|
||||
// us a speed gain when using packet access but it allows to use the functor in
|
||||
// nested expressions).
|
||||
template <typename Scalar, bool RandomAccess = true> struct linspaced_op;
|
||||
template <typename Scalar, bool RandomAccess> struct functor_traits< linspaced_op<Scalar,RandomAccess> >
|
||||
{ enum { Cost = 1, PacketAccess = packet_traits<Scalar>::HasSetLinear, IsRepeatable = true }; };
|
||||
template <typename Scalar, bool RandomAccess> struct linspaced_op
|
||||
{
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
linspaced_op(const Scalar& low, const Scalar& high, DenseIndex num_steps) : impl((num_steps==1 ? high : low), (num_steps==1 ? Scalar() : (high-low)/(num_steps-1))) {}
|
||||
|
||||
template<typename Index>
|
||||
EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return impl(i); }
|
||||
|
||||
// We need this function when assigning e.g. a RowVectorXd to a MatrixXd since
|
||||
// there row==0 and col is used for the actual iteration.
|
||||
template<typename Index>
|
||||
EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const
|
||||
{
|
||||
eigen_assert(col==0 || row==0);
|
||||
return impl(col + row);
|
||||
}
|
||||
|
||||
template<typename Index>
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(Index i) const { return impl.packetOp(i); }
|
||||
|
||||
// We need this function when assigning e.g. a RowVectorXd to a MatrixXd since
|
||||
// there row==0 and col is used for the actual iteration.
|
||||
template<typename Index>
|
||||
EIGEN_STRONG_INLINE const Packet packetOp(Index row, Index col) const
|
||||
{
|
||||
eigen_assert(col==0 || row==0);
|
||||
return impl.packetOp(col + row);
|
||||
}
|
||||
|
||||
// This proxy object handles the actual required temporaries, the different
|
||||
// implementations (random vs. sequential access) as well as the
|
||||
// correct piping to size 2/4 packet operations.
|
||||
const linspaced_op_impl<Scalar,RandomAccess> impl;
|
||||
};
|
||||
|
||||
// all functors allow linear access, except scalar_identity_op. So we fix here a quick meta
|
||||
// to indicate whether a functor allows linear access, just always answering 'yes' except for
|
||||
// scalar_identity_op.
|
||||
// FIXME move this to functor_traits adding a functor_default
|
||||
template<typename Functor> struct functor_has_linear_access { enum { ret = 1 }; };
|
||||
template<typename Scalar> struct functor_has_linear_access<scalar_identity_op<Scalar> > { enum { ret = 0 }; };
|
||||
|
||||
// In Eigen, any binary op (Product, CwiseBinaryOp) require the Lhs and Rhs to have the same scalar type, except for multiplication
|
||||
// where the mixing of different types is handled by scalar_product_traits
|
||||
// In particular, real * complex<real> is allowed.
|
||||
// FIXME move this to functor_traits adding a functor_default
|
||||
template<typename Functor> struct functor_is_product_like { enum { ret = 0 }; };
|
||||
template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
|
||||
template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_conj_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
|
||||
template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_quotient_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
|
||||
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to add a scalar to a fixed other one
|
||||
* \sa class CwiseUnaryOp, Array::operator+
|
||||
*/
|
||||
/* If you wonder why doing the pset1() in packetOp() is an optimization check scalar_multiple_op */
|
||||
template<typename Scalar>
|
||||
struct scalar_add_op {
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
// FIXME default copy constructors seems bugged with std::complex<>
|
||||
inline scalar_add_op(const scalar_add_op& other) : m_other(other.m_other) { }
|
||||
inline scalar_add_op(const Scalar& other) : m_other(other) { }
|
||||
inline Scalar operator() (const Scalar& a) const { return a + m_other; }
|
||||
inline const Packet packetOp(const Packet& a) const
|
||||
{ return internal::padd(a, pset1<Packet>(m_other)); }
|
||||
const Scalar m_other;
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_add_op<Scalar> >
|
||||
{ enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasAdd }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the square root of a scalar
|
||||
* \sa class CwiseUnaryOp, Cwise::sqrt()
|
||||
*/
|
||||
template<typename Scalar> struct scalar_sqrt_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op)
|
||||
inline const Scalar operator() (const Scalar& a) const { using std::sqrt; return sqrt(a); }
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
inline Packet packetOp(const Packet& a) const { return internal::psqrt(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_sqrt_op<Scalar> >
|
||||
{ enum {
|
||||
Cost = 5 * NumTraits<Scalar>::MulCost,
|
||||
PacketAccess = packet_traits<Scalar>::HasSqrt
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the cosine of a scalar
|
||||
* \sa class CwiseUnaryOp, ArrayBase::cos()
|
||||
*/
|
||||
template<typename Scalar> struct scalar_cos_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op)
|
||||
inline Scalar operator() (const Scalar& a) const { using std::cos; return cos(a); }
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
inline Packet packetOp(const Packet& a) const { return internal::pcos(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_cos_op<Scalar> >
|
||||
{
|
||||
enum {
|
||||
Cost = 5 * NumTraits<Scalar>::MulCost,
|
||||
PacketAccess = packet_traits<Scalar>::HasCos
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the sine of a scalar
|
||||
* \sa class CwiseUnaryOp, ArrayBase::sin()
|
||||
*/
|
||||
template<typename Scalar> struct scalar_sin_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op)
|
||||
inline const Scalar operator() (const Scalar& a) const { using std::sin; return sin(a); }
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
inline Packet packetOp(const Packet& a) const { return internal::psin(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_sin_op<Scalar> >
|
||||
{
|
||||
enum {
|
||||
Cost = 5 * NumTraits<Scalar>::MulCost,
|
||||
PacketAccess = packet_traits<Scalar>::HasSin
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the tan of a scalar
|
||||
* \sa class CwiseUnaryOp, ArrayBase::tan()
|
||||
*/
|
||||
template<typename Scalar> struct scalar_tan_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op)
|
||||
inline const Scalar operator() (const Scalar& a) const { using std::tan; return tan(a); }
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
inline Packet packetOp(const Packet& a) const { return internal::ptan(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_tan_op<Scalar> >
|
||||
{
|
||||
enum {
|
||||
Cost = 5 * NumTraits<Scalar>::MulCost,
|
||||
PacketAccess = packet_traits<Scalar>::HasTan
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the arc cosine of a scalar
|
||||
* \sa class CwiseUnaryOp, ArrayBase::acos()
|
||||
*/
|
||||
template<typename Scalar> struct scalar_acos_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op)
|
||||
inline const Scalar operator() (const Scalar& a) const { using std::acos; return acos(a); }
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
inline Packet packetOp(const Packet& a) const { return internal::pacos(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_acos_op<Scalar> >
|
||||
{
|
||||
enum {
|
||||
Cost = 5 * NumTraits<Scalar>::MulCost,
|
||||
PacketAccess = packet_traits<Scalar>::HasACos
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the arc sine of a scalar
|
||||
* \sa class CwiseUnaryOp, ArrayBase::asin()
|
||||
*/
|
||||
template<typename Scalar> struct scalar_asin_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op)
|
||||
inline const Scalar operator() (const Scalar& a) const { using std::asin; return asin(a); }
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
inline Packet packetOp(const Packet& a) const { return internal::pasin(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_asin_op<Scalar> >
|
||||
{
|
||||
enum {
|
||||
Cost = 5 * NumTraits<Scalar>::MulCost,
|
||||
PacketAccess = packet_traits<Scalar>::HasASin
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to raise a scalar to a power
|
||||
* \sa class CwiseUnaryOp, Cwise::pow
|
||||
*/
|
||||
template<typename Scalar>
|
||||
struct scalar_pow_op {
|
||||
// FIXME default copy constructors seems bugged with std::complex<>
|
||||
inline scalar_pow_op(const scalar_pow_op& other) : m_exponent(other.m_exponent) { }
|
||||
inline scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {}
|
||||
inline Scalar operator() (const Scalar& a) const { return numext::pow(a, m_exponent); }
|
||||
const Scalar m_exponent;
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_pow_op<Scalar> >
|
||||
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the quotient between a scalar and array entries.
|
||||
* \sa class CwiseUnaryOp, Cwise::inverse()
|
||||
*/
|
||||
template<typename Scalar>
|
||||
struct scalar_inverse_mult_op {
|
||||
scalar_inverse_mult_op(const Scalar& other) : m_other(other) {}
|
||||
inline Scalar operator() (const Scalar& a) const { return m_other / a; }
|
||||
template<typename Packet>
|
||||
inline const Packet packetOp(const Packet& a) const
|
||||
{ return internal::pdiv(pset1<Packet>(m_other),a); }
|
||||
Scalar m_other;
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the inverse of a scalar
|
||||
* \sa class CwiseUnaryOp, Cwise::inverse()
|
||||
*/
|
||||
template<typename Scalar>
|
||||
struct scalar_inverse_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_inverse_op)
|
||||
inline Scalar operator() (const Scalar& a) const { return Scalar(1)/a; }
|
||||
template<typename Packet>
|
||||
inline const Packet packetOp(const Packet& a) const
|
||||
{ return internal::pdiv(pset1<Packet>(Scalar(1)),a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_inverse_op<Scalar> >
|
||||
{ enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasDiv }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the square of a scalar
|
||||
* \sa class CwiseUnaryOp, Cwise::square()
|
||||
*/
|
||||
template<typename Scalar>
|
||||
struct scalar_square_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_square_op)
|
||||
inline Scalar operator() (const Scalar& a) const { return a*a; }
|
||||
template<typename Packet>
|
||||
inline const Packet packetOp(const Packet& a) const
|
||||
{ return internal::pmul(a,a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_square_op<Scalar> >
|
||||
{ enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the cube of a scalar
|
||||
* \sa class CwiseUnaryOp, Cwise::cube()
|
||||
*/
|
||||
template<typename Scalar>
|
||||
struct scalar_cube_op {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_cube_op)
|
||||
inline Scalar operator() (const Scalar& a) const { return a*a*a; }
|
||||
template<typename Packet>
|
||||
inline const Packet packetOp(const Packet& a) const
|
||||
{ return internal::pmul(a,pmul(a,a)); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_cube_op<Scalar> >
|
||||
{ enum { Cost = 2*NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
|
||||
|
||||
// default functor traits for STL functors:
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::multiplies<T> >
|
||||
{ enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::divides<T> >
|
||||
{ enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::plus<T> >
|
||||
{ enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::minus<T> >
|
||||
{ enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::negate<T> >
|
||||
{ enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::logical_or<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::logical_and<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::logical_not<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::greater<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::less<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::greater_equal<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::less_equal<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::equal_to<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::not_equal_to<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::binder2nd<T> >
|
||||
{ enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::binder1st<T> >
|
||||
{ enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::unary_negate<T> >
|
||||
{ enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::binary_negate<T> >
|
||||
{ enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; };
|
||||
|
||||
#ifdef EIGEN_STDEXT_SUPPORT
|
||||
|
||||
template<typename T0,typename T1>
|
||||
struct functor_traits<std::project1st<T0,T1> >
|
||||
{ enum { Cost = 0, PacketAccess = false }; };
|
||||
|
||||
template<typename T0,typename T1>
|
||||
struct functor_traits<std::project2nd<T0,T1> >
|
||||
{ enum { Cost = 0, PacketAccess = false }; };
|
||||
|
||||
template<typename T0,typename T1>
|
||||
struct functor_traits<std::select2nd<std::pair<T0,T1> > >
|
||||
{ enum { Cost = 0, PacketAccess = false }; };
|
||||
|
||||
template<typename T0,typename T1>
|
||||
struct functor_traits<std::select1st<std::pair<T0,T1> > >
|
||||
{ enum { Cost = 0, PacketAccess = false }; };
|
||||
|
||||
template<typename T0,typename T1>
|
||||
struct functor_traits<std::unary_compose<T0,T1> >
|
||||
{ enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost, PacketAccess = false }; };
|
||||
|
||||
template<typename T0,typename T1,typename T2>
|
||||
struct functor_traits<std::binary_compose<T0,T1,T2> >
|
||||
{ enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost + functor_traits<T2>::Cost, PacketAccess = false }; };
|
||||
|
||||
#endif // EIGEN_STDEXT_SUPPORT
|
||||
|
||||
// allow to add new functors and specializations of functor_traits from outside Eigen.
|
||||
// this macro is really needed because functor_traits must be specialized after it is declared but before it is used...
|
||||
#ifdef EIGEN_FUNCTORS_PLUGIN
|
||||
#include EIGEN_FUNCTORS_PLUGIN
|
||||
#endif
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_FUNCTORS_H
|
||||
@@ -19,18 +19,19 @@ namespace internal
|
||||
template<typename Derived, typename OtherDerived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger>
|
||||
struct isApprox_selector
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar& prec)
|
||||
{
|
||||
using std::min;
|
||||
typename internal::nested<Derived,2>::type nested(x);
|
||||
typename internal::nested<OtherDerived,2>::type otherNested(y);
|
||||
return (nested - otherNested).cwiseAbs2().sum() <= prec * prec * (min)(nested.cwiseAbs2().sum(), otherNested.cwiseAbs2().sum());
|
||||
typename internal::nested_eval<Derived,2>::type nested(x);
|
||||
typename internal::nested_eval<OtherDerived,2>::type otherNested(y);
|
||||
return (nested - otherNested).cwiseAbs2().sum() <= prec * prec * numext::mini(nested.cwiseAbs2().sum(), otherNested.cwiseAbs2().sum());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived, typename OtherDerived>
|
||||
struct isApprox_selector<Derived, OtherDerived, true>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar&)
|
||||
{
|
||||
return x.matrix() == y.matrix();
|
||||
@@ -40,6 +41,7 @@ struct isApprox_selector<Derived, OtherDerived, true>
|
||||
template<typename Derived, typename OtherDerived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger>
|
||||
struct isMuchSmallerThan_object_selector
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar& prec)
|
||||
{
|
||||
return x.cwiseAbs2().sum() <= numext::abs2(prec) * y.cwiseAbs2().sum();
|
||||
@@ -49,6 +51,7 @@ struct isMuchSmallerThan_object_selector
|
||||
template<typename Derived, typename OtherDerived>
|
||||
struct isMuchSmallerThan_object_selector<Derived, OtherDerived, true>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static bool run(const Derived& x, const OtherDerived&, const typename Derived::RealScalar&)
|
||||
{
|
||||
return x.matrix() == Derived::Zero(x.rows(), x.cols()).matrix();
|
||||
@@ -58,6 +61,7 @@ struct isMuchSmallerThan_object_selector<Derived, OtherDerived, true>
|
||||
template<typename Derived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger>
|
||||
struct isMuchSmallerThan_scalar_selector
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static bool run(const Derived& x, const typename Derived::RealScalar& y, const typename Derived::RealScalar& prec)
|
||||
{
|
||||
return x.cwiseAbs2().sum() <= numext::abs2(prec * y);
|
||||
@@ -67,6 +71,7 @@ struct isMuchSmallerThan_scalar_selector
|
||||
template<typename Derived>
|
||||
struct isMuchSmallerThan_scalar_selector<Derived, true>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static bool run(const Derived& x, const typename Derived::RealScalar&, const typename Derived::RealScalar&)
|
||||
{
|
||||
return x.matrix() == Derived::Zero(x.rows(), x.cols()).matrix();
|
||||
|
||||
@@ -11,29 +11,7 @@
|
||||
#ifndef EIGEN_GENERAL_PRODUCT_H
|
||||
#define EIGEN_GENERAL_PRODUCT_H
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
/** \class GeneralProduct
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* \brief Expression of the product of two general matrices or vectors
|
||||
*
|
||||
* \param LhsNested the type used to store the left-hand side
|
||||
* \param RhsNested the type used to store the right-hand side
|
||||
* \param ProductMode the type of the product
|
||||
*
|
||||
* This class represents an expression of the product of two general matrices.
|
||||
* We call a general matrix, a dense matrix with full storage. For instance,
|
||||
* This excludes triangular, selfadjoint, and sparse matrices.
|
||||
* It is the return type of the operator* between general matrices. Its template
|
||||
* arguments are determined automatically by ProductReturnType. Therefore,
|
||||
* GeneralProduct should never be used direclty. To determine the result type of a
|
||||
* function which involves a matrix product, use ProductReturnType::Type.
|
||||
*
|
||||
* \sa ProductReturnType, MatrixBase::operator*(const MatrixBase<OtherDerived>&)
|
||||
*/
|
||||
template<typename Lhs, typename Rhs, int ProductType = internal::product_type<Lhs,Rhs>::value>
|
||||
class GeneralProduct;
|
||||
namespace Eigen {
|
||||
|
||||
enum {
|
||||
Large = 2,
|
||||
@@ -59,15 +37,14 @@ template<typename Lhs, typename Rhs> struct product_type
|
||||
typedef typename remove_all<Lhs>::type _Lhs;
|
||||
typedef typename remove_all<Rhs>::type _Rhs;
|
||||
enum {
|
||||
MaxRows = _Lhs::MaxRowsAtCompileTime,
|
||||
Rows = _Lhs::RowsAtCompileTime,
|
||||
MaxCols = _Rhs::MaxColsAtCompileTime,
|
||||
Cols = _Rhs::ColsAtCompileTime,
|
||||
MaxDepth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::MaxColsAtCompileTime,
|
||||
_Rhs::MaxRowsAtCompileTime),
|
||||
Depth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::ColsAtCompileTime,
|
||||
_Rhs::RowsAtCompileTime),
|
||||
LargeThreshold = EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
|
||||
MaxRows = traits<_Lhs>::MaxRowsAtCompileTime,
|
||||
Rows = traits<_Lhs>::RowsAtCompileTime,
|
||||
MaxCols = traits<_Rhs>::MaxColsAtCompileTime,
|
||||
Cols = traits<_Rhs>::ColsAtCompileTime,
|
||||
MaxDepth = EIGEN_SIZE_MIN_PREFER_FIXED(traits<_Lhs>::MaxColsAtCompileTime,
|
||||
traits<_Rhs>::MaxRowsAtCompileTime),
|
||||
Depth = EIGEN_SIZE_MIN_PREFER_FIXED(traits<_Lhs>::ColsAtCompileTime,
|
||||
traits<_Rhs>::RowsAtCompileTime)
|
||||
};
|
||||
|
||||
// the splitting into different lines of code here, introducing the _select enums and the typedef below,
|
||||
@@ -82,7 +59,8 @@ private:
|
||||
|
||||
public:
|
||||
enum {
|
||||
value = selector::ret
|
||||
value = selector::ret,
|
||||
ret = selector::ret
|
||||
};
|
||||
#ifdef EIGEN_DEBUG_PRODUCT
|
||||
static void debug()
|
||||
@@ -98,6 +76,31 @@ public:
|
||||
#endif
|
||||
};
|
||||
|
||||
// template<typename Lhs, typename Rhs> struct product_tag
|
||||
// {
|
||||
// private:
|
||||
//
|
||||
// typedef typename remove_all<Lhs>::type _Lhs;
|
||||
// typedef typename remove_all<Rhs>::type _Rhs;
|
||||
// enum {
|
||||
// Rows = _Lhs::RowsAtCompileTime,
|
||||
// Cols = _Rhs::ColsAtCompileTime,
|
||||
// Depth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::ColsAtCompileTime, _Rhs::RowsAtCompileTime)
|
||||
// };
|
||||
//
|
||||
// enum {
|
||||
// rows_select = Rows==1 ? int(Rows) : int(Large),
|
||||
// cols_select = Cols==1 ? int(Cols) : int(Large),
|
||||
// depth_select = Depth==1 ? int(Depth) : int(Large)
|
||||
// };
|
||||
// typedef product_type_selector<rows_select, cols_select, depth_select> selector;
|
||||
//
|
||||
// public:
|
||||
// enum {
|
||||
// ret = selector::ret
|
||||
// };
|
||||
//
|
||||
// };
|
||||
|
||||
/* The following allows to select the kind of product at compile time
|
||||
* based on the three dimensions of the product.
|
||||
@@ -128,54 +131,6 @@ template<> struct product_type_selector<Large,Large,Small> { enum
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
/** \class ProductReturnType
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* \brief Helper class to get the correct and optimized returned type of operator*
|
||||
*
|
||||
* \param Lhs the type of the left-hand side
|
||||
* \param Rhs the type of the right-hand side
|
||||
* \param ProductMode the type of the product (determined automatically by internal::product_mode)
|
||||
*
|
||||
* This class defines the typename Type representing the optimized product expression
|
||||
* between two matrix expressions. In practice, using ProductReturnType<Lhs,Rhs>::Type
|
||||
* is the recommended way to define the result type of a function returning an expression
|
||||
* which involve a matrix product. The class Product should never be
|
||||
* used directly.
|
||||
*
|
||||
* \sa class Product, MatrixBase::operator*(const MatrixBase<OtherDerived>&)
|
||||
*/
|
||||
template<typename Lhs, typename Rhs, int ProductType>
|
||||
struct ProductReturnType
|
||||
{
|
||||
// TODO use the nested type to reduce instanciations ????
|
||||
// typedef typename internal::nested<Lhs,Rhs::ColsAtCompileTime>::type LhsNested;
|
||||
// typedef typename internal::nested<Rhs,Lhs::RowsAtCompileTime>::type RhsNested;
|
||||
|
||||
typedef GeneralProduct<Lhs/*Nested*/, Rhs/*Nested*/, ProductType> Type;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct ProductReturnType<Lhs,Rhs,CoeffBasedProductMode>
|
||||
{
|
||||
typedef typename internal::nested<Lhs, Rhs::ColsAtCompileTime, typename internal::plain_matrix_type<Lhs>::type >::type LhsNested;
|
||||
typedef typename internal::nested<Rhs, Lhs::RowsAtCompileTime, typename internal::plain_matrix_type<Rhs>::type >::type RhsNested;
|
||||
typedef CoeffBasedProduct<LhsNested, RhsNested, EvalBeforeAssigningBit | EvalBeforeNestingBit> Type;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct ProductReturnType<Lhs,Rhs,LazyCoeffBasedProductMode>
|
||||
{
|
||||
typedef typename internal::nested<Lhs, Rhs::ColsAtCompileTime, typename internal::plain_matrix_type<Lhs>::type >::type LhsNested;
|
||||
typedef typename internal::nested<Rhs, Lhs::RowsAtCompileTime, typename internal::plain_matrix_type<Rhs>::type >::type RhsNested;
|
||||
typedef CoeffBasedProduct<LhsNested, RhsNested, NestByRefBit> Type;
|
||||
};
|
||||
|
||||
// this is a workaround for sun CC
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct LazyProductReturnType : public ProductReturnType<Lhs,Rhs,LazyCoeffBasedProductMode>
|
||||
{};
|
||||
|
||||
/***********************************************************************
|
||||
* Implementation of Inner Vector Vector Product
|
||||
***********************************************************************/
|
||||
@@ -187,119 +142,10 @@ struct LazyProductReturnType : public ProductReturnType<Lhs,Rhs,LazyCoeffBasedPr
|
||||
// product ends up to a row-vector times col-vector product... To tackle this use
|
||||
// case, we could have a specialization for Block<MatrixType,1,1> with: operator=(Scalar x);
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct traits<GeneralProduct<Lhs,Rhs,InnerProduct> >
|
||||
: traits<Matrix<typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType,1,1> >
|
||||
{};
|
||||
|
||||
}
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
class GeneralProduct<Lhs, Rhs, InnerProduct>
|
||||
: internal::no_assignment_operator,
|
||||
public Matrix<typename internal::scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType,1,1>
|
||||
{
|
||||
typedef Matrix<typename internal::scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType,1,1> Base;
|
||||
public:
|
||||
GeneralProduct(const Lhs& lhs, const Rhs& rhs)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::RealScalar, typename Rhs::RealScalar>::value),
|
||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||
|
||||
Base::coeffRef(0,0) = (lhs.transpose().cwiseProduct(rhs)).sum();
|
||||
}
|
||||
|
||||
/** Convertion to scalar */
|
||||
operator const typename Base::Scalar() const {
|
||||
return Base::coeff(0,0);
|
||||
}
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* Implementation of Outer Vector Vector Product
|
||||
***********************************************************************/
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Column major
|
||||
template<typename ProductType, typename Dest, typename Func>
|
||||
EIGEN_DONT_INLINE void outer_product_selector_run(const ProductType& prod, Dest& dest, const Func& func, const false_type&)
|
||||
{
|
||||
typedef typename Dest::Index Index;
|
||||
// FIXME make sure lhs is sequentially stored
|
||||
// FIXME not very good if rhs is real and lhs complex while alpha is real too
|
||||
const Index cols = dest.cols();
|
||||
for (Index j=0; j<cols; ++j)
|
||||
func(dest.col(j), prod.rhs().coeff(j) * prod.lhs());
|
||||
}
|
||||
|
||||
// Row major
|
||||
template<typename ProductType, typename Dest, typename Func>
|
||||
EIGEN_DONT_INLINE void outer_product_selector_run(const ProductType& prod, Dest& dest, const Func& func, const true_type&) {
|
||||
typedef typename Dest::Index Index;
|
||||
// FIXME make sure rhs is sequentially stored
|
||||
// FIXME not very good if lhs is real and rhs complex while alpha is real too
|
||||
const Index rows = dest.rows();
|
||||
for (Index i=0; i<rows; ++i)
|
||||
func(dest.row(i), prod.lhs().coeff(i) * prod.rhs());
|
||||
}
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct traits<GeneralProduct<Lhs,Rhs,OuterProduct> >
|
||||
: traits<ProductBase<GeneralProduct<Lhs,Rhs,OuterProduct>, Lhs, Rhs> >
|
||||
{};
|
||||
|
||||
}
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
class GeneralProduct<Lhs, Rhs, OuterProduct>
|
||||
: public ProductBase<GeneralProduct<Lhs,Rhs,OuterProduct>, Lhs, Rhs>
|
||||
{
|
||||
template<typename T> struct IsRowMajor : internal::conditional<(int(T::Flags)&RowMajorBit), internal::true_type, internal::false_type>::type {};
|
||||
|
||||
public:
|
||||
EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct)
|
||||
|
||||
GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::RealScalar, typename Rhs::RealScalar>::value),
|
||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||
}
|
||||
|
||||
struct set { template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() = src; } };
|
||||
struct add { template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() += src; } };
|
||||
struct sub { template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() -= src; } };
|
||||
struct adds {
|
||||
Scalar m_scale;
|
||||
adds(const Scalar& s) : m_scale(s) {}
|
||||
template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const {
|
||||
dst.const_cast_derived() += m_scale * src;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Dest>
|
||||
inline void evalTo(Dest& dest) const {
|
||||
internal::outer_product_selector_run(*this, dest, set(), IsRowMajor<Dest>());
|
||||
}
|
||||
|
||||
template<typename Dest>
|
||||
inline void addTo(Dest& dest) const {
|
||||
internal::outer_product_selector_run(*this, dest, add(), IsRowMajor<Dest>());
|
||||
}
|
||||
|
||||
template<typename Dest>
|
||||
inline void subTo(Dest& dest) const {
|
||||
internal::outer_product_selector_run(*this, dest, sub(), IsRowMajor<Dest>());
|
||||
}
|
||||
|
||||
template<typename Dest> void scaleAndAddTo(Dest& dest, const Scalar& alpha) const
|
||||
{
|
||||
internal::outer_product_selector_run(*this, dest, adds(alpha), IsRowMajor<Dest>());
|
||||
}
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* Implementation of General Matrix Vector Product
|
||||
***********************************************************************/
|
||||
@@ -313,60 +159,13 @@ class GeneralProduct<Lhs, Rhs, OuterProduct>
|
||||
*/
|
||||
namespace internal {
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct traits<GeneralProduct<Lhs,Rhs,GemvProduct> >
|
||||
: traits<ProductBase<GeneralProduct<Lhs,Rhs,GemvProduct>, Lhs, Rhs> >
|
||||
{};
|
||||
|
||||
template<int Side, int StorageOrder, bool BlasCompatible>
|
||||
struct gemv_selector;
|
||||
struct gemv_dense_sense_selector;
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
class GeneralProduct<Lhs, Rhs, GemvProduct>
|
||||
: public ProductBase<GeneralProduct<Lhs,Rhs,GemvProduct>, Lhs, Rhs>
|
||||
{
|
||||
public:
|
||||
EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct)
|
||||
|
||||
typedef typename Lhs::Scalar LhsScalar;
|
||||
typedef typename Rhs::Scalar RhsScalar;
|
||||
|
||||
GeneralProduct(const Lhs& a_lhs, const Rhs& a_rhs) : Base(a_lhs,a_rhs)
|
||||
{
|
||||
// EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::Scalar, typename Rhs::Scalar>::value),
|
||||
// YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||
}
|
||||
|
||||
enum { Side = Lhs::IsVectorAtCompileTime ? OnTheLeft : OnTheRight };
|
||||
typedef typename internal::conditional<int(Side)==OnTheRight,_LhsNested,_RhsNested>::type MatrixType;
|
||||
|
||||
template<typename Dest> void scaleAndAddTo(Dest& dst, const Scalar& alpha) const
|
||||
{
|
||||
eigen_assert(m_lhs.rows() == dst.rows() && m_rhs.cols() == dst.cols());
|
||||
internal::gemv_selector<Side,(int(MatrixType::Flags)&RowMajorBit) ? RowMajor : ColMajor,
|
||||
bool(internal::blas_traits<MatrixType>::HasUsableDirectAccess)>::run(*this, dst, alpha);
|
||||
}
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
// The vector is on the left => transposition
|
||||
template<int StorageOrder, bool BlasCompatible>
|
||||
struct gemv_selector<OnTheLeft,StorageOrder,BlasCompatible>
|
||||
{
|
||||
template<typename ProductType, typename Dest>
|
||||
static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha)
|
||||
{
|
||||
Transpose<Dest> destT(dest);
|
||||
enum { OtherStorageOrder = StorageOrder == RowMajor ? ColMajor : RowMajor };
|
||||
gemv_selector<OnTheRight,OtherStorageOrder,BlasCompatible>
|
||||
::run(GeneralProduct<Transpose<const typename ProductType::_RhsNested>,Transpose<const typename ProductType::_LhsNested>, GemvProduct>
|
||||
(prod.rhs().transpose(), prod.lhs().transpose()), destT, alpha);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Scalar,int Size,int MaxSize,bool Cond> struct gemv_static_vector_if;
|
||||
|
||||
template<typename Scalar,int Size,int MaxSize>
|
||||
@@ -384,7 +183,7 @@ struct gemv_static_vector_if<Scalar,Size,Dynamic,true>
|
||||
template<typename Scalar,int Size,int MaxSize>
|
||||
struct gemv_static_vector_if<Scalar,Size,MaxSize,true>
|
||||
{
|
||||
#if EIGEN_ALIGN_STATICALLY
|
||||
#if EIGEN_MAX_STATIC_ALIGN_BYTES!=0
|
||||
internal::plain_array<Scalar,EIGEN_SIZE_MIN_PREFER_FIXED(Size,MaxSize),0> m_data;
|
||||
EIGEN_STRONG_INLINE Scalar* data() { return m_data.array; }
|
||||
#else
|
||||
@@ -397,33 +196,48 @@ struct gemv_static_vector_if<Scalar,Size,MaxSize,true>
|
||||
internal::plain_array<Scalar,EIGEN_SIZE_MIN_PREFER_FIXED(Size,MaxSize)+(ForceAlignment?PacketSize:0),0> m_data;
|
||||
EIGEN_STRONG_INLINE Scalar* data() {
|
||||
return ForceAlignment
|
||||
? reinterpret_cast<Scalar*>((reinterpret_cast<size_t>(m_data.array) & ~(size_t(15))) + 16)
|
||||
? reinterpret_cast<Scalar*>((reinterpret_cast<size_t>(m_data.array) & ~(size_t(EIGEN_MAX_ALIGN_BYTES-1))) + EIGEN_MAX_ALIGN_BYTES)
|
||||
: m_data.array;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template<> struct gemv_selector<OnTheRight,ColMajor,true>
|
||||
// The vector is on the left => transposition
|
||||
template<int StorageOrder, bool BlasCompatible>
|
||||
struct gemv_dense_sense_selector<OnTheLeft,StorageOrder,BlasCompatible>
|
||||
{
|
||||
template<typename ProductType, typename Dest>
|
||||
static inline void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha)
|
||||
template<typename Lhs, typename Rhs, typename Dest>
|
||||
static void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha)
|
||||
{
|
||||
typedef typename ProductType::Index Index;
|
||||
typedef typename ProductType::LhsScalar LhsScalar;
|
||||
typedef typename ProductType::RhsScalar RhsScalar;
|
||||
typedef typename ProductType::Scalar ResScalar;
|
||||
typedef typename ProductType::RealScalar RealScalar;
|
||||
typedef typename ProductType::ActualLhsType ActualLhsType;
|
||||
typedef typename ProductType::ActualRhsType ActualRhsType;
|
||||
typedef typename ProductType::LhsBlasTraits LhsBlasTraits;
|
||||
typedef typename ProductType::RhsBlasTraits RhsBlasTraits;
|
||||
Transpose<Dest> destT(dest);
|
||||
enum { OtherStorageOrder = StorageOrder == RowMajor ? ColMajor : RowMajor };
|
||||
gemv_dense_sense_selector<OnTheRight,OtherStorageOrder,BlasCompatible>
|
||||
::run(rhs.transpose(), lhs.transpose(), destT, alpha);
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct gemv_dense_sense_selector<OnTheRight,ColMajor,true>
|
||||
{
|
||||
template<typename Lhs, typename Rhs, typename Dest>
|
||||
static inline void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha)
|
||||
{
|
||||
typedef typename Lhs::Scalar LhsScalar;
|
||||
typedef typename Rhs::Scalar RhsScalar;
|
||||
typedef typename Dest::Scalar ResScalar;
|
||||
typedef typename Dest::RealScalar RealScalar;
|
||||
|
||||
typedef internal::blas_traits<Lhs> LhsBlasTraits;
|
||||
typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType;
|
||||
typedef internal::blas_traits<Rhs> RhsBlasTraits;
|
||||
typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType;
|
||||
|
||||
typedef Map<Matrix<ResScalar,Dynamic,1>, Aligned> MappedDest;
|
||||
|
||||
ActualLhsType actualLhs = LhsBlasTraits::extract(prod.lhs());
|
||||
ActualRhsType actualRhs = RhsBlasTraits::extract(prod.rhs());
|
||||
ActualLhsType actualLhs = LhsBlasTraits::extract(lhs);
|
||||
ActualRhsType actualRhs = RhsBlasTraits::extract(rhs);
|
||||
|
||||
ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs())
|
||||
* RhsBlasTraits::extractScalarFactor(prod.rhs());
|
||||
ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(lhs)
|
||||
* RhsBlasTraits::extractScalarFactor(rhs);
|
||||
|
||||
enum {
|
||||
// FIXME find a way to allow an inner stride on the result if packet_traits<Scalar>::size==1
|
||||
@@ -435,18 +249,18 @@ template<> struct gemv_selector<OnTheRight,ColMajor,true>
|
||||
|
||||
gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest;
|
||||
|
||||
bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0));
|
||||
bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
|
||||
|
||||
const bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0));
|
||||
const bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
|
||||
|
||||
RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
|
||||
|
||||
ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(),
|
||||
evalToDest ? dest.data() : static_dest.data());
|
||||
|
||||
|
||||
if(!evalToDest)
|
||||
{
|
||||
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||
int size = dest.size();
|
||||
Index size = dest.size();
|
||||
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||
#endif
|
||||
if(!alphaIsCompatible)
|
||||
@@ -458,11 +272,13 @@ template<> struct gemv_selector<OnTheRight,ColMajor,true>
|
||||
MappedDest(actualDestPtr, dest.size()) = dest;
|
||||
}
|
||||
|
||||
typedef const_blas_data_mapper<LhsScalar,Index,ColMajor> LhsMapper;
|
||||
typedef const_blas_data_mapper<RhsScalar,Index,RowMajor> RhsMapper;
|
||||
general_matrix_vector_product
|
||||
<Index,LhsScalar,ColMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsBlasTraits::NeedToConjugate>::run(
|
||||
<Index,LhsScalar,LhsMapper,ColMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsMapper,RhsBlasTraits::NeedToConjugate>::run(
|
||||
actualLhs.rows(), actualLhs.cols(),
|
||||
actualLhs.data(), actualLhs.outerStride(),
|
||||
actualRhs.data(), actualRhs.innerStride(),
|
||||
LhsMapper(actualLhs.data(), actualLhs.outerStride()),
|
||||
RhsMapper(actualRhs.data(), actualRhs.innerStride()),
|
||||
actualDestPtr, 1,
|
||||
compatibleAlpha);
|
||||
|
||||
@@ -476,34 +292,34 @@ template<> struct gemv_selector<OnTheRight,ColMajor,true>
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct gemv_selector<OnTheRight,RowMajor,true>
|
||||
template<> struct gemv_dense_sense_selector<OnTheRight,RowMajor,true>
|
||||
{
|
||||
template<typename ProductType, typename Dest>
|
||||
static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha)
|
||||
template<typename Lhs, typename Rhs, typename Dest>
|
||||
static void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha)
|
||||
{
|
||||
typedef typename ProductType::LhsScalar LhsScalar;
|
||||
typedef typename ProductType::RhsScalar RhsScalar;
|
||||
typedef typename ProductType::Scalar ResScalar;
|
||||
typedef typename ProductType::Index Index;
|
||||
typedef typename ProductType::ActualLhsType ActualLhsType;
|
||||
typedef typename ProductType::ActualRhsType ActualRhsType;
|
||||
typedef typename ProductType::_ActualRhsType _ActualRhsType;
|
||||
typedef typename ProductType::LhsBlasTraits LhsBlasTraits;
|
||||
typedef typename ProductType::RhsBlasTraits RhsBlasTraits;
|
||||
typedef typename Lhs::Scalar LhsScalar;
|
||||
typedef typename Rhs::Scalar RhsScalar;
|
||||
typedef typename Dest::Scalar ResScalar;
|
||||
|
||||
typedef internal::blas_traits<Lhs> LhsBlasTraits;
|
||||
typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType;
|
||||
typedef internal::blas_traits<Rhs> RhsBlasTraits;
|
||||
typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType;
|
||||
typedef typename internal::remove_all<ActualRhsType>::type ActualRhsTypeCleaned;
|
||||
|
||||
typename add_const<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(prod.lhs());
|
||||
typename add_const<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(prod.rhs());
|
||||
typename add_const<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(lhs);
|
||||
typename add_const<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(rhs);
|
||||
|
||||
ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs())
|
||||
* RhsBlasTraits::extractScalarFactor(prod.rhs());
|
||||
ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(lhs)
|
||||
* RhsBlasTraits::extractScalarFactor(rhs);
|
||||
|
||||
enum {
|
||||
// FIXME find a way to allow an inner stride on the result if packet_traits<Scalar>::size==1
|
||||
// on, the other hand it is good for the cache to pack the vector anyways...
|
||||
DirectlyUseRhs = _ActualRhsType::InnerStrideAtCompileTime==1
|
||||
DirectlyUseRhs = ActualRhsTypeCleaned::InnerStrideAtCompileTime==1
|
||||
};
|
||||
|
||||
gemv_static_vector_if<RhsScalar,_ActualRhsType::SizeAtCompileTime,_ActualRhsType::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs;
|
||||
gemv_static_vector_if<RhsScalar,ActualRhsTypeCleaned::SizeAtCompileTime,ActualRhsTypeCleaned::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs;
|
||||
|
||||
ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(),
|
||||
DirectlyUseRhs ? const_cast<RhsScalar*>(actualRhs.data()) : static_rhs.data());
|
||||
@@ -511,45 +327,45 @@ template<> struct gemv_selector<OnTheRight,RowMajor,true>
|
||||
if(!DirectlyUseRhs)
|
||||
{
|
||||
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||
int size = actualRhs.size();
|
||||
Index size = actualRhs.size();
|
||||
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
||||
#endif
|
||||
Map<typename _ActualRhsType::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs;
|
||||
Map<typename ActualRhsTypeCleaned::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs;
|
||||
}
|
||||
|
||||
typedef const_blas_data_mapper<LhsScalar,Index,RowMajor> LhsMapper;
|
||||
typedef const_blas_data_mapper<RhsScalar,Index,ColMajor> RhsMapper;
|
||||
general_matrix_vector_product
|
||||
<Index,LhsScalar,RowMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsBlasTraits::NeedToConjugate>::run(
|
||||
<Index,LhsScalar,LhsMapper,RowMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsMapper,RhsBlasTraits::NeedToConjugate>::run(
|
||||
actualLhs.rows(), actualLhs.cols(),
|
||||
actualLhs.data(), actualLhs.outerStride(),
|
||||
actualRhsPtr, 1,
|
||||
LhsMapper(actualLhs.data(), actualLhs.outerStride()),
|
||||
RhsMapper(actualRhsPtr, 1),
|
||||
dest.data(), dest.innerStride(),
|
||||
actualAlpha);
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct gemv_selector<OnTheRight,ColMajor,false>
|
||||
template<> struct gemv_dense_sense_selector<OnTheRight,ColMajor,false>
|
||||
{
|
||||
template<typename ProductType, typename Dest>
|
||||
static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha)
|
||||
template<typename Lhs, typename Rhs, typename Dest>
|
||||
static void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha)
|
||||
{
|
||||
typedef typename Dest::Index Index;
|
||||
// TODO makes sure dest is sequentially stored in memory, otherwise use a temp
|
||||
const Index size = prod.rhs().rows();
|
||||
const Index size = rhs.rows();
|
||||
for(Index k=0; k<size; ++k)
|
||||
dest += (alpha*prod.rhs().coeff(k)) * prod.lhs().col(k);
|
||||
dest += (alpha*rhs.coeff(k)) * lhs.col(k);
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct gemv_selector<OnTheRight,RowMajor,false>
|
||||
template<> struct gemv_dense_sense_selector<OnTheRight,RowMajor,false>
|
||||
{
|
||||
template<typename ProductType, typename Dest>
|
||||
static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha)
|
||||
template<typename Lhs, typename Rhs, typename Dest>
|
||||
static void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha)
|
||||
{
|
||||
typedef typename Dest::Index Index;
|
||||
// TODO makes sure rhs is sequentially stored in memory, otherwise use a temp
|
||||
const Index rows = prod.rows();
|
||||
const Index rows = dest.rows();
|
||||
for(Index i=0; i<rows; ++i)
|
||||
dest.coeffRef(i) += alpha * (prod.lhs().row(i).cwiseProduct(prod.rhs().transpose())).sum();
|
||||
dest.coeffRef(i) += alpha * (lhs.row(i).cwiseProduct(rhs.transpose())).sum();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -565,9 +381,11 @@ template<> struct gemv_selector<OnTheRight,RowMajor,false>
|
||||
*
|
||||
* \sa lazyProduct(), operator*=(const MatrixBase&), Cwise::operator*()
|
||||
*/
|
||||
#ifndef __CUDACC__
|
||||
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
inline const typename ProductReturnType<Derived, OtherDerived>::Type
|
||||
inline const Product<Derived, OtherDerived>
|
||||
MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
||||
{
|
||||
// A note regarding the function declaration: In MSVC, this function will sometimes
|
||||
@@ -592,9 +410,12 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
||||
#ifdef EIGEN_DEBUG_PRODUCT
|
||||
internal::product_type<Derived,OtherDerived>::debug();
|
||||
#endif
|
||||
return typename ProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
|
||||
|
||||
return Product<Derived, OtherDerived>(derived(), other.derived());
|
||||
}
|
||||
|
||||
#endif // __CUDACC__
|
||||
|
||||
/** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation.
|
||||
*
|
||||
* The returned product will behave like any other expressions: the coefficients of the product will be
|
||||
@@ -608,7 +429,7 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
const typename LazyProductReturnType<Derived,OtherDerived>::Type
|
||||
const Product<Derived,OtherDerived,LazyProduct>
|
||||
MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const
|
||||
{
|
||||
enum {
|
||||
@@ -627,7 +448,7 @@ MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const
|
||||
INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)
|
||||
EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)
|
||||
|
||||
return typename LazyProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
|
||||
return Product<Derived,OtherDerived,LazyProduct>(derived(), other.derived());
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -42,21 +42,27 @@ namespace internal {
|
||||
struct default_packet_traits
|
||||
{
|
||||
enum {
|
||||
HasHalfPacket = 0,
|
||||
|
||||
HasAdd = 1,
|
||||
HasSub = 1,
|
||||
HasMul = 1,
|
||||
HasNegate = 1,
|
||||
HasAbs = 1,
|
||||
HasArg = 0,
|
||||
HasAbs2 = 1,
|
||||
HasMin = 1,
|
||||
HasMax = 1,
|
||||
HasConj = 1,
|
||||
HasSetLinear = 1,
|
||||
HasBlend = 0,
|
||||
|
||||
HasDiv = 0,
|
||||
HasSqrt = 0,
|
||||
HasRsqrt = 0,
|
||||
HasExp = 0,
|
||||
HasLog = 0,
|
||||
HasLog10 = 0,
|
||||
HasPow = 0,
|
||||
|
||||
HasSin = 0,
|
||||
@@ -64,17 +70,26 @@ struct default_packet_traits
|
||||
HasTan = 0,
|
||||
HasASin = 0,
|
||||
HasACos = 0,
|
||||
HasATan = 0
|
||||
HasATan = 0,
|
||||
HasSinh = 0,
|
||||
HasCosh = 0,
|
||||
HasTanh = 0,
|
||||
|
||||
HasRound = 0,
|
||||
HasFloor = 0,
|
||||
HasCeil = 0
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T> struct packet_traits : default_packet_traits
|
||||
{
|
||||
typedef T type;
|
||||
typedef T half;
|
||||
enum {
|
||||
Vectorizable = 0,
|
||||
size = 1,
|
||||
AlignedOnScalar = 0
|
||||
AlignedOnScalar = 0,
|
||||
HasHalfPacket = 0
|
||||
};
|
||||
enum {
|
||||
HasAdd = 0,
|
||||
@@ -90,135 +105,250 @@ template<typename T> struct packet_traits : default_packet_traits
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T> struct packet_traits<const T> : packet_traits<T> { };
|
||||
|
||||
template <typename Src, typename Tgt> struct type_casting_traits {
|
||||
enum {
|
||||
VectorizedCast = 0,
|
||||
SrcCoeffRatio = 1,
|
||||
TgtCoeffRatio = 1
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/** \internal \returns static_cast<TgtType>(a) (coeff-wise) */
|
||||
template <typename SrcPacket, typename TgtPacket>
|
||||
EIGEN_DEVICE_FUNC inline TgtPacket
|
||||
pcast(const SrcPacket& a) {
|
||||
return static_cast<TgtPacket>(a);
|
||||
}
|
||||
template <typename SrcPacket, typename TgtPacket>
|
||||
EIGEN_DEVICE_FUNC inline TgtPacket
|
||||
pcast(const SrcPacket& a, const SrcPacket& /*b*/) {
|
||||
return static_cast<TgtPacket>(a);
|
||||
}
|
||||
|
||||
|
||||
/** \internal \returns a + b (coeff-wise) */
|
||||
template<typename Packet> inline Packet
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
padd(const Packet& a,
|
||||
const Packet& b) { return a+b; }
|
||||
|
||||
/** \internal \returns a - b (coeff-wise) */
|
||||
template<typename Packet> inline Packet
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
psub(const Packet& a,
|
||||
const Packet& b) { return a-b; }
|
||||
|
||||
/** \internal \returns -a (coeff-wise) */
|
||||
template<typename Packet> inline Packet
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
pnegate(const Packet& a) { return -a; }
|
||||
|
||||
/** \internal \returns conj(a) (coeff-wise) */
|
||||
template<typename Packet> inline Packet
|
||||
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
pconj(const Packet& a) { return numext::conj(a); }
|
||||
|
||||
/** \internal \returns a * b (coeff-wise) */
|
||||
template<typename Packet> inline Packet
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
pmul(const Packet& a,
|
||||
const Packet& b) { return a*b; }
|
||||
|
||||
/** \internal \returns a / b (coeff-wise) */
|
||||
template<typename Packet> inline Packet
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
pdiv(const Packet& a,
|
||||
const Packet& b) { return a/b; }
|
||||
|
||||
/** \internal \returns the min of \a a and \a b (coeff-wise) */
|
||||
template<typename Packet> inline Packet
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
pmin(const Packet& a,
|
||||
const Packet& b) { using std::min; return (min)(a, b); }
|
||||
const Packet& b) { return numext::mini(a, b); }
|
||||
|
||||
/** \internal \returns the max of \a a and \a b (coeff-wise) */
|
||||
template<typename Packet> inline Packet
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
pmax(const Packet& a,
|
||||
const Packet& b) { using std::max; return (max)(a, b); }
|
||||
const Packet& b) { return numext::maxi(a, b); }
|
||||
|
||||
/** \internal \returns the absolute value of \a a */
|
||||
template<typename Packet> inline Packet
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
pabs(const Packet& a) { using std::abs; return abs(a); }
|
||||
|
||||
/** \internal \returns the phase angle of \a a */
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
parg(const Packet& a) { using numext::arg; return arg(a); }
|
||||
|
||||
/** \internal \returns the bitwise and of \a a and \a b */
|
||||
template<typename Packet> inline Packet
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
pand(const Packet& a, const Packet& b) { return a & b; }
|
||||
|
||||
/** \internal \returns the bitwise or of \a a and \a b */
|
||||
template<typename Packet> inline Packet
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
por(const Packet& a, const Packet& b) { return a | b; }
|
||||
|
||||
/** \internal \returns the bitwise xor of \a a and \a b */
|
||||
template<typename Packet> inline Packet
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
pxor(const Packet& a, const Packet& b) { return a ^ b; }
|
||||
|
||||
/** \internal \returns the bitwise andnot of \a a and \a b */
|
||||
template<typename Packet> inline Packet
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
pandnot(const Packet& a, const Packet& b) { return a & (!b); }
|
||||
|
||||
/** \internal \returns a packet version of \a *from, from must be 16 bytes aligned */
|
||||
template<typename Packet> inline Packet
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
pload(const typename unpacket_traits<Packet>::type* from) { return *from; }
|
||||
|
||||
/** \internal \returns a packet version of \a *from, (un-aligned load) */
|
||||
template<typename Packet> inline Packet
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
ploadu(const typename unpacket_traits<Packet>::type* from) { return *from; }
|
||||
|
||||
/** \internal \returns a packet with elements of \a *from duplicated.
|
||||
* For instance, for a packet of 8 elements, 4 scalar will be read from \a *from and
|
||||
* duplicated to form: {from[0],from[0],from[1],from[1],,from[2],from[2],,from[3],from[3]}
|
||||
* Currently, this function is only used for scalar * complex products.
|
||||
*/
|
||||
template<typename Packet> inline Packet
|
||||
ploaddup(const typename unpacket_traits<Packet>::type* from) { return *from; }
|
||||
|
||||
/** \internal \returns a packet with constant coefficients \a a, e.g.: (a,a,a,a) */
|
||||
template<typename Packet> inline Packet
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
pset1(const typename unpacket_traits<Packet>::type& a) { return a; }
|
||||
|
||||
/** \internal \returns a packet with constant coefficients \a a[0], e.g.: (a[0],a[0],a[0],a[0]) */
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
pload1(const typename unpacket_traits<Packet>::type *a) { return pset1<Packet>(*a); }
|
||||
|
||||
/** \internal \returns a packet with elements of \a *from duplicated.
|
||||
* For instance, for a packet of 8 elements, 4 scalars will be read from \a *from and
|
||||
* duplicated to form: {from[0],from[0],from[1],from[1],from[2],from[2],from[3],from[3]}
|
||||
* Currently, this function is only used for scalar * complex products.
|
||||
*/
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
ploaddup(const typename unpacket_traits<Packet>::type* from) { return *from; }
|
||||
|
||||
/** \internal \returns a packet with elements of \a *from quadrupled.
|
||||
* For instance, for a packet of 8 elements, 2 scalars will be read from \a *from and
|
||||
* replicated to form: {from[0],from[0],from[0],from[0],from[1],from[1],from[1],from[1]}
|
||||
* Currently, this function is only used in matrix products.
|
||||
* For packet-size smaller or equal to 4, this function is equivalent to pload1
|
||||
*/
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
ploadquad(const typename unpacket_traits<Packet>::type* from)
|
||||
{ return pload1<Packet>(from); }
|
||||
|
||||
/** \internal equivalent to
|
||||
* \code
|
||||
* a0 = pload1(a+0);
|
||||
* a1 = pload1(a+1);
|
||||
* a2 = pload1(a+2);
|
||||
* a3 = pload1(a+3);
|
||||
* \endcode
|
||||
* \sa pset1, pload1, ploaddup, pbroadcast2
|
||||
*/
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC
|
||||
inline void pbroadcast4(const typename unpacket_traits<Packet>::type *a,
|
||||
Packet& a0, Packet& a1, Packet& a2, Packet& a3)
|
||||
{
|
||||
a0 = pload1<Packet>(a+0);
|
||||
a1 = pload1<Packet>(a+1);
|
||||
a2 = pload1<Packet>(a+2);
|
||||
a3 = pload1<Packet>(a+3);
|
||||
}
|
||||
|
||||
/** \internal equivalent to
|
||||
* \code
|
||||
* a0 = pload1(a+0);
|
||||
* a1 = pload1(a+1);
|
||||
* \endcode
|
||||
* \sa pset1, pload1, ploaddup, pbroadcast4
|
||||
*/
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC
|
||||
inline void pbroadcast2(const typename unpacket_traits<Packet>::type *a,
|
||||
Packet& a0, Packet& a1)
|
||||
{
|
||||
a0 = pload1<Packet>(a+0);
|
||||
a1 = pload1<Packet>(a+1);
|
||||
}
|
||||
|
||||
/** \internal \brief Returns a packet with coefficients (a,a+1,...,a+packet_size-1). */
|
||||
template<typename Scalar> inline typename packet_traits<Scalar>::type
|
||||
plset(const Scalar& a) { return a; }
|
||||
template<typename Packet> inline Packet
|
||||
plset(const typename unpacket_traits<Packet>::type& a) { return a; }
|
||||
|
||||
/** \internal copy the packet \a from to \a *to, \a to must be 16 bytes aligned */
|
||||
template<typename Scalar, typename Packet> inline void pstore(Scalar* to, const Packet& from)
|
||||
template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pstore(Scalar* to, const Packet& from)
|
||||
{ (*to) = from; }
|
||||
|
||||
/** \internal copy the packet \a from to \a *to, (un-aligned store) */
|
||||
template<typename Scalar, typename Packet> inline void pstoreu(Scalar* to, const Packet& from)
|
||||
{ (*to) = from; }
|
||||
template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pstoreu(Scalar* to, const Packet& from)
|
||||
{ (*to) = from; }
|
||||
|
||||
template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline Packet pgather(const Scalar* from, Index /*stride*/)
|
||||
{ return ploadu<Packet>(from); }
|
||||
|
||||
template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pscatter(Scalar* to, const Packet& from, Index /*stride*/)
|
||||
{ pstore(to, from); }
|
||||
|
||||
/** \internal tries to do cache prefetching of \a addr */
|
||||
template<typename Scalar> inline void prefetch(const Scalar* addr)
|
||||
{
|
||||
#if !defined(_MSC_VER)
|
||||
__builtin_prefetch(addr);
|
||||
#ifdef __CUDA_ARCH__
|
||||
#if defined(__LP64__)
|
||||
// 64-bit pointer operand constraint for inlined asm
|
||||
asm(" prefetch.L1 [ %1 ];" : "=l"(addr) : "l"(addr));
|
||||
#else
|
||||
// 32-bit pointer operand constraint for inlined asm
|
||||
asm(" prefetch.L1 [ %1 ];" : "=r"(addr) : "r"(addr));
|
||||
#endif
|
||||
#elif !EIGEN_COMP_MSVC
|
||||
__builtin_prefetch(addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \internal \returns the first element of a packet */
|
||||
template<typename Packet> inline typename unpacket_traits<Packet>::type pfirst(const Packet& a)
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type pfirst(const Packet& a)
|
||||
{ return a; }
|
||||
|
||||
/** \internal \returns a packet where the element i contains the sum of the packet of \a vec[i] */
|
||||
template<typename Packet> inline Packet
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
preduxp(const Packet* vecs) { return vecs[0]; }
|
||||
|
||||
/** \internal \returns the sum of the elements of \a a*/
|
||||
template<typename Packet> inline typename unpacket_traits<Packet>::type predux(const Packet& a)
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux(const Packet& a)
|
||||
{ return a; }
|
||||
|
||||
/** \internal \returns the sum of the elements of \a a by block of 4 elements.
|
||||
* For a packet {a0, a1, a2, a3, a4, a5, a6, a7}, it returns a half packet {a0+a4, a1+a5, a2+a6, a3+a7}
|
||||
* For packet-size smaller or equal to 4, this boils down to a noop.
|
||||
*/
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline
|
||||
typename conditional<(unpacket_traits<Packet>::size%8)==0,typename unpacket_traits<Packet>::half,Packet>::type
|
||||
predux4(const Packet& a)
|
||||
{ return a; }
|
||||
|
||||
/** \internal \returns the product of the elements of \a a*/
|
||||
template<typename Packet> inline typename unpacket_traits<Packet>::type predux_mul(const Packet& a)
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_mul(const Packet& a)
|
||||
{ return a; }
|
||||
|
||||
/** \internal \returns the min of the elements of \a a*/
|
||||
template<typename Packet> inline typename unpacket_traits<Packet>::type predux_min(const Packet& a)
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_min(const Packet& a)
|
||||
{ return a; }
|
||||
|
||||
/** \internal \returns the max of the elements of \a a*/
|
||||
template<typename Packet> inline typename unpacket_traits<Packet>::type predux_max(const Packet& a)
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_max(const Packet& a)
|
||||
{ return a; }
|
||||
|
||||
/** \internal \returns the reversed elements of \a a*/
|
||||
template<typename Packet> inline Packet preverse(const Packet& a)
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet preverse(const Packet& a)
|
||||
{ return a; }
|
||||
|
||||
template<size_t offset, typename Packet>
|
||||
struct protate_impl
|
||||
{
|
||||
// Empty so attempts to use this unimplemented path will fail to compile.
|
||||
// Only specializations of this template should be used.
|
||||
};
|
||||
|
||||
/** \internal \returns a packet with the coefficients rotated to the right in little-endian convention,
|
||||
* by the given offset, e.g. for offset == 1:
|
||||
* (packet[3], packet[2], packet[1], packet[0]) becomes (packet[0], packet[3], packet[2], packet[1])
|
||||
*/
|
||||
template<size_t offset, typename Packet> EIGEN_DEVICE_FUNC inline Packet protate(const Packet& a)
|
||||
{
|
||||
return offset ? protate_impl<offset, Packet>::run(a) : a;
|
||||
}
|
||||
|
||||
/** \internal \returns \a a with real and imaginary part flipped (for complex type only) */
|
||||
template<typename Packet> inline Packet pcplxflip(const Packet& a)
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet pcplxflip(const Packet& a)
|
||||
{
|
||||
// FIXME: uncomment the following in case we drop the internal imag and real functions.
|
||||
// using std::imag;
|
||||
@@ -250,6 +380,22 @@ Packet pasin(const Packet& a) { using std::asin; return asin(a); }
|
||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||
Packet pacos(const Packet& a) { using std::acos; return acos(a); }
|
||||
|
||||
/** \internal \returns the arc tangent of \a a (coeff-wise) */
|
||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||
Packet patan(const Packet& a) { using std::atan; return atan(a); }
|
||||
|
||||
/** \internal \returns the hyperbolic sine of \a a (coeff-wise) */
|
||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||
Packet psinh(const Packet& a) { using std::sinh; return sinh(a); }
|
||||
|
||||
/** \internal \returns the hyperbolic cosine of \a a (coeff-wise) */
|
||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||
Packet pcosh(const Packet& a) { using std::cosh; return cosh(a); }
|
||||
|
||||
/** \internal \returns the hyperbolic tan of \a a (coeff-wise) */
|
||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||
Packet ptanh(const Packet& a) { using std::tanh; return tanh(a); }
|
||||
|
||||
/** \internal \returns the exp of \a a (coeff-wise) */
|
||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||
Packet pexp(const Packet& a) { using std::exp; return exp(a); }
|
||||
@@ -258,10 +404,32 @@ Packet pexp(const Packet& a) { using std::exp; return exp(a); }
|
||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||
Packet plog(const Packet& a) { using std::log; return log(a); }
|
||||
|
||||
/** \internal \returns the log10 of \a a (coeff-wise) */
|
||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||
Packet plog10(const Packet& a) { using std::log10; return log10(a); }
|
||||
|
||||
/** \internal \returns the square-root of \a a (coeff-wise) */
|
||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||
Packet psqrt(const Packet& a) { using std::sqrt; return sqrt(a); }
|
||||
|
||||
/** \internal \returns the reciprocal square-root of \a a (coeff-wise) */
|
||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||
Packet prsqrt(const Packet& a) {
|
||||
return pdiv(pset1<Packet>(1), psqrt(a));
|
||||
}
|
||||
|
||||
/** \internal \returns the rounded value of \a a (coeff-wise) */
|
||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||
Packet pround(const Packet& a) { using numext::round; return round(a); }
|
||||
|
||||
/** \internal \returns the floor of \a a (coeff-wise) */
|
||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||
Packet pfloor(const Packet& a) { using numext::floor; return floor(a); }
|
||||
|
||||
/** \internal \returns the ceil of \a a (coeff-wise) */
|
||||
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||
Packet pceil(const Packet& a) { using numext::ceil; return ceil(a); }
|
||||
|
||||
/***************************************************************************
|
||||
* The following functions might not have to be overwritten for vectorized types
|
||||
***************************************************************************/
|
||||
@@ -275,34 +443,45 @@ inline void pstore1(typename unpacket_traits<Packet>::type* to, const typename u
|
||||
}
|
||||
|
||||
/** \internal \returns a * b + c (coeff-wise) */
|
||||
template<typename Packet> inline Packet
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
pmadd(const Packet& a,
|
||||
const Packet& b,
|
||||
const Packet& c)
|
||||
{ return padd(pmul(a, b),c); }
|
||||
|
||||
/** \internal \returns a packet version of \a *from.
|
||||
* If LoadMode equals #Aligned, \a from must be 16 bytes aligned */
|
||||
template<typename Packet, int LoadMode>
|
||||
inline Packet ploadt(const typename unpacket_traits<Packet>::type* from)
|
||||
* The pointer \a from must be aligned on a \a Alignment bytes boundary. */
|
||||
template<typename Packet, int Alignment>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt(const typename unpacket_traits<Packet>::type* from)
|
||||
{
|
||||
if(LoadMode == Aligned)
|
||||
if(Alignment >= unpacket_traits<Packet>::alignment)
|
||||
return pload<Packet>(from);
|
||||
else
|
||||
return ploadu<Packet>(from);
|
||||
}
|
||||
|
||||
/** \internal copy the packet \a from to \a *to.
|
||||
* If StoreMode equals #Aligned, \a to must be 16 bytes aligned */
|
||||
template<typename Scalar, typename Packet, int LoadMode>
|
||||
inline void pstoret(Scalar* to, const Packet& from)
|
||||
* The pointer \a from must be aligned on a \a Alignment bytes boundary. */
|
||||
template<typename Scalar, typename Packet, int Alignment>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void pstoret(Scalar* to, const Packet& from)
|
||||
{
|
||||
if(LoadMode == Aligned)
|
||||
if(Alignment >= unpacket_traits<Packet>::alignment)
|
||||
pstore(to, from);
|
||||
else
|
||||
pstoreu(to, from);
|
||||
}
|
||||
|
||||
/** \internal \returns a packet version of \a *from.
|
||||
* Unlike ploadt, ploadt_ro takes advantage of the read-only memory path on the
|
||||
* hardware if available to speedup the loading of data that won't be modified
|
||||
* by the current computation.
|
||||
*/
|
||||
template<typename Packet, int LoadMode>
|
||||
inline Packet ploadt_ro(const typename unpacket_traits<Packet>::type* from)
|
||||
{
|
||||
return ploadt<Packet, LoadMode>(from);
|
||||
}
|
||||
|
||||
/** \internal default implementation of palign() allowing partial specialization */
|
||||
template<int Offset,typename PacketType>
|
||||
struct palign_impl
|
||||
@@ -336,15 +515,46 @@ inline void palign(PacketType& first, const PacketType& second)
|
||||
* Fast complex products (GCC generates a function call which is very slow)
|
||||
***************************************************************************/
|
||||
|
||||
// Eigen+CUDA does not support complexes.
|
||||
#ifndef __CUDACC__
|
||||
|
||||
template<> inline std::complex<float> pmul(const std::complex<float>& a, const std::complex<float>& b)
|
||||
{ return std::complex<float>(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); }
|
||||
|
||||
template<> inline std::complex<double> pmul(const std::complex<double>& a, const std::complex<double>& b)
|
||||
{ return std::complex<double>(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* PacketBlock, that is a collection of N packets where the number of words
|
||||
* in the packet is a multiple of N.
|
||||
***************************************************************************/
|
||||
template <typename Packet,int N=unpacket_traits<Packet>::size> struct PacketBlock {
|
||||
Packet packet[N];
|
||||
};
|
||||
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline void
|
||||
ptranspose(PacketBlock<Packet,1>& /*kernel*/) {
|
||||
// Nothing to do in the scalar case, i.e. a 1x1 matrix.
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Selector, i.e. vector of N boolean values used to select (i.e. blend)
|
||||
* words from 2 packets.
|
||||
***************************************************************************/
|
||||
template <size_t N> struct Selector {
|
||||
bool select[N];
|
||||
};
|
||||
|
||||
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
|
||||
pblend(const Selector<unpacket_traits<Packet>::size>& ifPacket, const Packet& thenPacket, const Packet& elsePacket) {
|
||||
return ifPacket.select[0] ? thenPacket : elsePacket;
|
||||
}
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_GENERIC_PACKET_MATH_H
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
#define EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(NAME,FUNCTOR) \
|
||||
template<typename Derived> \
|
||||
inline const Eigen::CwiseUnaryOp<Eigen::internal::FUNCTOR<typename Derived::Scalar>, const Derived> \
|
||||
NAME(const Eigen::ArrayBase<Derived>& x) { \
|
||||
return x.derived(); \
|
||||
(NAME)(const Eigen::ArrayBase<Derived>& x) { \
|
||||
return Eigen::CwiseUnaryOp<Eigen::internal::FUNCTOR<typename Derived::Scalar>, const Derived>(x.derived()); \
|
||||
}
|
||||
|
||||
#define EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(NAME,FUNCTOR) \
|
||||
@@ -30,25 +30,40 @@
|
||||
{ \
|
||||
static inline typename NAME##_retval<ArrayBase<Derived> >::type run(const Eigen::ArrayBase<Derived>& x) \
|
||||
{ \
|
||||
return x.derived(); \
|
||||
return typename NAME##_retval<ArrayBase<Derived> >::type(x.derived()); \
|
||||
} \
|
||||
};
|
||||
|
||||
|
||||
namespace Eigen
|
||||
{
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(real,scalar_real_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(imag,scalar_imag_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(conj,scalar_conjugate_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(inverse,scalar_inverse_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sin,scalar_sin_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cos,scalar_cos_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(tan,scalar_tan_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(atan,scalar_atan_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(asin,scalar_asin_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(acos,scalar_acos_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(tan,scalar_tan_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sinh,scalar_sinh_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cosh,scalar_cosh_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(tanh,scalar_tanh_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(exp,scalar_exp_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log,scalar_log_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log10,scalar_log10_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs,scalar_abs_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs2,scalar_abs2_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(arg,scalar_arg_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sqrt,scalar_sqrt_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(square,scalar_square_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cube,scalar_cube_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(round,scalar_round_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(floor,scalar_floor_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(ceil,scalar_ceil_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(isnan,scalar_isnan_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(isinf,scalar_isinf_op)
|
||||
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(isfinite,scalar_isfinite_op)
|
||||
|
||||
template<typename Derived>
|
||||
inline const Eigen::CwiseUnaryOp<Eigen::internal::scalar_pow_op<typename Derived::Scalar>, const Derived>
|
||||
@@ -56,16 +71,46 @@ namespace Eigen
|
||||
return x.derived().pow(exponent);
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
inline const Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename Derived::Scalar>, const Derived, const Derived>
|
||||
pow(const Eigen::ArrayBase<Derived>& x, const Eigen::ArrayBase<Derived>& exponents)
|
||||
/** \returns an expression of the coefficient-wise power of \a x to the given array of \a exponents.
|
||||
*
|
||||
* This function computes the coefficient-wise power.
|
||||
*
|
||||
* Example: \include Cwise_array_power_array.cpp
|
||||
* Output: \verbinclude Cwise_array_power_array.out
|
||||
*
|
||||
* \sa ArrayBase::pow()
|
||||
*/
|
||||
template<typename Derived,typename ExponentDerived>
|
||||
inline const Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename ExponentDerived::Scalar>, const Derived, const ExponentDerived>
|
||||
pow(const Eigen::ArrayBase<Derived>& x, const Eigen::ArrayBase<ExponentDerived>& exponents)
|
||||
{
|
||||
return Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename Derived::Scalar>, const Derived, const Derived>(
|
||||
return Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename ExponentDerived::Scalar>, const Derived, const ExponentDerived>(
|
||||
x.derived(),
|
||||
exponents.derived()
|
||||
);
|
||||
}
|
||||
|
||||
/** \returns an expression of the coefficient-wise power of the scalar \a x to the given array of \a exponents.
|
||||
*
|
||||
* This function computes the coefficient-wise power between a scalar and an array of exponents.
|
||||
* Beaware that the scalar type of the input scalar \a x and the exponents \a exponents must be the same.
|
||||
*
|
||||
* Example: \include Cwise_scalar_power_array.cpp
|
||||
* Output: \verbinclude Cwise_scalar_power_array.out
|
||||
*
|
||||
* \sa ArrayBase::pow()
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline const Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename Derived::Scalar>, const typename Derived::ConstantReturnType, const Derived>
|
||||
pow(const typename Derived::Scalar& x, const Eigen::ArrayBase<Derived>& exponents)
|
||||
{
|
||||
typename Derived::ConstantReturnType constant_x(exponents.rows(), exponents.cols(), x);
|
||||
return Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename Derived::Scalar>, const typename Derived::ConstantReturnType, const Derived>(
|
||||
constant_x,
|
||||
exponents.derived()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Component-wise division of a scalar by array elements.
|
||||
**/
|
||||
|
||||
@@ -49,7 +49,7 @@ std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat&
|
||||
*/
|
||||
struct IOFormat
|
||||
{
|
||||
/** Default contructor, see class IOFormat for the meaning of the parameters */
|
||||
/** Default constructor, see class IOFormat for the meaning of the parameters */
|
||||
IOFormat(int _precision = StreamPrecision, int _flags = 0,
|
||||
const std::string& _coeffSeparator = " ",
|
||||
const std::string& _rowSeparator = "\n", const std::string& _rowPrefix="", const std::string& _rowSuffix="",
|
||||
@@ -57,6 +57,10 @@ struct IOFormat
|
||||
: matPrefix(_matPrefix), matSuffix(_matSuffix), rowPrefix(_rowPrefix), rowSuffix(_rowSuffix), rowSeparator(_rowSeparator),
|
||||
rowSpacer(""), coeffSeparator(_coeffSeparator), precision(_precision), flags(_flags)
|
||||
{
|
||||
// TODO check if rowPrefix, rowSuffix or rowSeparator contains a newline
|
||||
// don't add rowSpacer if columns are not to be aligned
|
||||
if((flags & DontAlignCols))
|
||||
return;
|
||||
int i = int(matSuffix.length())-1;
|
||||
while (i>=0 && matSuffix[i]!='\n')
|
||||
{
|
||||
@@ -160,7 +164,6 @@ std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat&
|
||||
|
||||
typename Derived::Nested m = _m;
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
typedef typename Derived::Index Index;
|
||||
|
||||
Index width = 0;
|
||||
|
||||
@@ -185,21 +188,22 @@ std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat&
|
||||
explicit_precision = fmt.precision;
|
||||
}
|
||||
|
||||
std::streamsize old_precision = 0;
|
||||
if(explicit_precision) old_precision = s.precision(explicit_precision);
|
||||
|
||||
bool align_cols = !(fmt.flags & DontAlignCols);
|
||||
if(align_cols)
|
||||
{
|
||||
// compute the largest width
|
||||
for(Index j = 1; j < m.cols(); ++j)
|
||||
for(Index j = 0; j < m.cols(); ++j)
|
||||
for(Index i = 0; i < m.rows(); ++i)
|
||||
{
|
||||
std::stringstream sstr;
|
||||
if(explicit_precision) sstr.precision(explicit_precision);
|
||||
sstr.copyfmt(s);
|
||||
sstr << m.coeff(i,j);
|
||||
width = std::max<Index>(width, Index(sstr.str().length()));
|
||||
}
|
||||
}
|
||||
std::streamsize old_precision = 0;
|
||||
if(explicit_precision) old_precision = s.precision(explicit_precision);
|
||||
s << fmt.matPrefix;
|
||||
for(Index i = 0; i < m.rows(); ++i)
|
||||
{
|
||||
|
||||
126
Eigen/src/Core/Inverse.h
Normal file
126
Eigen/src/Core/Inverse.h
Normal file
@@ -0,0 +1,126 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2014 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef EIGEN_INVERSE_H
|
||||
#define EIGEN_INVERSE_H
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
// TODO move the general declaration in Core, and rename this file DenseInverseImpl.h, or something like this...
|
||||
|
||||
template<typename XprType,typename StorageKind> class InverseImpl;
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename XprType>
|
||||
struct traits<Inverse<XprType> >
|
||||
: traits<typename XprType::PlainObject>
|
||||
{
|
||||
typedef typename XprType::PlainObject PlainObject;
|
||||
typedef traits<PlainObject> BaseTraits;
|
||||
enum {
|
||||
Flags = BaseTraits::Flags & RowMajorBit
|
||||
};
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
/** \class Inverse
|
||||
*
|
||||
* \brief Expression of the inverse of another expression
|
||||
*
|
||||
* \tparam XprType the type of the expression we are taking the inverse
|
||||
*
|
||||
* This class represents an abstract expression of A.inverse()
|
||||
* and most of the time this is the only way it is used.
|
||||
*
|
||||
*/
|
||||
template<typename XprType>
|
||||
class Inverse : public InverseImpl<XprType,typename internal::traits<XprType>::StorageKind>
|
||||
{
|
||||
public:
|
||||
typedef typename XprType::StorageIndex StorageIndex;
|
||||
typedef typename XprType::PlainObject PlainObject;
|
||||
typedef typename internal::ref_selector<XprType>::type XprTypeNested;
|
||||
typedef typename internal::remove_all<XprTypeNested>::type XprTypeNestedCleaned;
|
||||
|
||||
explicit Inverse(const XprType &xpr)
|
||||
: m_xpr(xpr)
|
||||
{}
|
||||
|
||||
EIGEN_DEVICE_FUNC Index rows() const { return m_xpr.rows(); }
|
||||
EIGEN_DEVICE_FUNC Index cols() const { return m_xpr.cols(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC const XprTypeNestedCleaned& nestedExpression() const { return m_xpr; }
|
||||
|
||||
protected:
|
||||
XprTypeNested m_xpr;
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* Specialization of the Inverse expression for dense expressions.
|
||||
* Direct access to the coefficients are discared.
|
||||
* FIXME this intermediate class is probably not needed anymore.
|
||||
*/
|
||||
template<typename XprType>
|
||||
class InverseImpl<XprType,Dense>
|
||||
: public MatrixBase<Inverse<XprType> >
|
||||
{
|
||||
typedef Inverse<XprType> Derived;
|
||||
|
||||
public:
|
||||
|
||||
typedef MatrixBase<Derived> Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
||||
typedef typename internal::remove_all<XprType>::type NestedExpression;
|
||||
|
||||
private:
|
||||
|
||||
Scalar coeff(Index row, Index col) const;
|
||||
Scalar coeff(Index i) const;
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
/** \internal
|
||||
* \brief Default evaluator for Inverse expression.
|
||||
*
|
||||
* This default evaluator for Inverse expression simply evaluate the inverse into a temporary
|
||||
* by a call to internal::call_assignment_no_alias.
|
||||
* Therefore, inverse implementers only have to specialize Assignment<Dst,Inverse<...>, ...> for
|
||||
* there own nested expression.
|
||||
*
|
||||
* \sa class Inverse
|
||||
*/
|
||||
template<typename ArgType>
|
||||
struct unary_evaluator<Inverse<ArgType> >
|
||||
: public evaluator<typename Inverse<ArgType>::PlainObject>
|
||||
{
|
||||
typedef Inverse<ArgType> InverseType;
|
||||
typedef typename InverseType::PlainObject PlainObject;
|
||||
typedef evaluator<PlainObject> Base;
|
||||
|
||||
enum { Flags = Base::Flags | EvalBeforeNestingBit };
|
||||
|
||||
unary_evaluator(const InverseType& inv_xpr)
|
||||
: m_result(inv_xpr.rows(), inv_xpr.cols())
|
||||
{
|
||||
::new (static_cast<Base*>(this)) Base(m_result);
|
||||
internal::call_assignment_no_alias(m_result, inv_xpr);
|
||||
}
|
||||
|
||||
protected:
|
||||
PlainObject m_result;
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_INVERSE_H
|
||||
@@ -19,7 +19,7 @@ namespace Eigen {
|
||||
* \brief A matrix or vector expression mapping an existing array of data.
|
||||
*
|
||||
* \tparam PlainObjectType the equivalent matrix type of the mapped data
|
||||
* \tparam MapOptions specifies whether the pointer is \c #Aligned, or \c #Unaligned.
|
||||
* \tparam MapOptions specifies the pointer alignment in bytes. It can be: \c #Aligned128, , \c #Aligned64, \c #Aligned32, \c #Aligned16, \c #Aligned8 or \c #Unaligned.
|
||||
* The default is \c #Unaligned.
|
||||
* \tparam StrideType optionally specifies strides. By default, Map assumes the memory layout
|
||||
* of an ordinary, contiguous array. This can be overridden by specifying strides.
|
||||
@@ -70,8 +70,6 @@ struct traits<Map<PlainObjectType, MapOptions, StrideType> >
|
||||
: public traits<PlainObjectType>
|
||||
{
|
||||
typedef traits<PlainObjectType> TraitsBase;
|
||||
typedef typename PlainObjectType::Index Index;
|
||||
typedef typename PlainObjectType::Scalar Scalar;
|
||||
enum {
|
||||
InnerStrideAtCompileTime = StrideType::InnerStrideAtCompileTime == 0
|
||||
? int(PlainObjectType::InnerStrideAtCompileTime)
|
||||
@@ -79,22 +77,9 @@ struct traits<Map<PlainObjectType, MapOptions, StrideType> >
|
||||
OuterStrideAtCompileTime = StrideType::OuterStrideAtCompileTime == 0
|
||||
? int(PlainObjectType::OuterStrideAtCompileTime)
|
||||
: int(StrideType::OuterStrideAtCompileTime),
|
||||
HasNoInnerStride = InnerStrideAtCompileTime == 1,
|
||||
HasNoOuterStride = StrideType::OuterStrideAtCompileTime == 0,
|
||||
HasNoStride = HasNoInnerStride && HasNoOuterStride,
|
||||
IsAligned = bool(EIGEN_ALIGN) && ((int(MapOptions)&Aligned)==Aligned),
|
||||
IsDynamicSize = PlainObjectType::SizeAtCompileTime==Dynamic,
|
||||
KeepsPacketAccess = bool(HasNoInnerStride)
|
||||
&& ( bool(IsDynamicSize)
|
||||
|| HasNoOuterStride
|
||||
|| ( OuterStrideAtCompileTime!=Dynamic
|
||||
&& ((static_cast<int>(sizeof(Scalar))*OuterStrideAtCompileTime)%16)==0 ) ),
|
||||
Alignment = int(MapOptions)&int(AlignedMask),
|
||||
Flags0 = TraitsBase::Flags & (~NestByRefBit),
|
||||
Flags1 = IsAligned ? (int(Flags0) | AlignedBit) : (int(Flags0) & ~AlignedBit),
|
||||
Flags2 = (bool(HasNoStride) || bool(PlainObjectType::IsVectorAtCompileTime))
|
||||
? int(Flags1) : int(Flags1 & ~LinearAccessBit),
|
||||
Flags3 = is_lvalue<PlainObjectType>::value ? int(Flags2) : (int(Flags2) & ~LvalueBit),
|
||||
Flags = KeepsPacketAccess ? int(Flags3) : (int(Flags3) & ~PacketAccessBit)
|
||||
Flags = is_lvalue<PlainObjectType>::value ? int(Flags0) : (int(Flags0) & ~LvalueBit)
|
||||
};
|
||||
private:
|
||||
enum { Options }; // Expressions don't have Options
|
||||
@@ -110,19 +95,17 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Map)
|
||||
|
||||
typedef typename Base::PointerType PointerType;
|
||||
#if EIGEN2_SUPPORT_STAGE <= STAGE30_FULL_EIGEN3_API
|
||||
typedef const Scalar* PointerArgType;
|
||||
inline PointerType cast_to_pointer_type(PointerArgType ptr) { return const_cast<PointerType>(ptr); }
|
||||
#else
|
||||
typedef PointerType PointerArgType;
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline PointerType cast_to_pointer_type(PointerArgType ptr) { return ptr; }
|
||||
#endif
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index innerStride() const
|
||||
{
|
||||
return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index outerStride() const
|
||||
{
|
||||
return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
|
||||
@@ -134,10 +117,11 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
|
||||
/** Constructor in the fixed-size case.
|
||||
*
|
||||
* \param dataPtr pointer to the array to map
|
||||
* \param a_stride optional Stride object, passing the strides.
|
||||
* \param stride optional Stride object, passing the strides.
|
||||
*/
|
||||
inline Map(PointerArgType dataPtr, const StrideType& a_stride = StrideType())
|
||||
: Base(cast_to_pointer_type(dataPtr)), m_stride(a_stride)
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit inline Map(PointerArgType dataPtr, const StrideType& stride = StrideType())
|
||||
: Base(cast_to_pointer_type(dataPtr)), m_stride(stride)
|
||||
{
|
||||
PlainObjectType::Base::_check_template_params();
|
||||
}
|
||||
@@ -145,11 +129,12 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
|
||||
/** Constructor in the dynamic-size vector case.
|
||||
*
|
||||
* \param dataPtr pointer to the array to map
|
||||
* \param a_size the size of the vector expression
|
||||
* \param a_stride optional Stride object, passing the strides.
|
||||
* \param size the size of the vector expression
|
||||
* \param stride optional Stride object, passing the strides.
|
||||
*/
|
||||
inline Map(PointerArgType dataPtr, Index a_size, const StrideType& a_stride = StrideType())
|
||||
: Base(cast_to_pointer_type(dataPtr), a_size), m_stride(a_stride)
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Map(PointerArgType dataPtr, Index size, const StrideType& stride = StrideType())
|
||||
: Base(cast_to_pointer_type(dataPtr), size), m_stride(stride)
|
||||
{
|
||||
PlainObjectType::Base::_check_template_params();
|
||||
}
|
||||
@@ -157,12 +142,13 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
|
||||
/** Constructor in the dynamic-size matrix case.
|
||||
*
|
||||
* \param dataPtr pointer to the array to map
|
||||
* \param nbRows the number of rows of the matrix expression
|
||||
* \param nbCols the number of columns of the matrix expression
|
||||
* \param a_stride optional Stride object, passing the strides.
|
||||
* \param rows the number of rows of the matrix expression
|
||||
* \param cols the number of columns of the matrix expression
|
||||
* \param stride optional Stride object, passing the strides.
|
||||
*/
|
||||
inline Map(PointerArgType dataPtr, Index nbRows, Index nbCols, const StrideType& a_stride = StrideType())
|
||||
: Base(cast_to_pointer_type(dataPtr), nbRows, nbCols), m_stride(a_stride)
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Map(PointerArgType dataPtr, Index rows, Index cols, const StrideType& stride = StrideType())
|
||||
: Base(cast_to_pointer_type(dataPtr), rows, cols), m_stride(stride)
|
||||
{
|
||||
PlainObjectType::Base::_check_template_params();
|
||||
}
|
||||
@@ -173,19 +159,6 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
|
||||
StrideType m_stride;
|
||||
};
|
||||
|
||||
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
||||
inline Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>
|
||||
::Array(const Scalar *data)
|
||||
{
|
||||
this->_set_noalias(Eigen::Map<const Array>(data));
|
||||
}
|
||||
|
||||
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
||||
inline Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>
|
||||
::Matrix(const Scalar *data)
|
||||
{
|
||||
this->_set_noalias(Eigen::Map<const Matrix>(data));
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#define EIGEN_MAPBASE_H
|
||||
|
||||
#define EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) \
|
||||
EIGEN_STATIC_ASSERT((int(internal::traits<Derived>::Flags) & LinearAccessBit) || Derived::IsVectorAtCompileTime, \
|
||||
EIGEN_STATIC_ASSERT((int(internal::evaluator<Derived>::Flags) & LinearAccessBit) || Derived::IsVectorAtCompileTime, \
|
||||
YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT)
|
||||
|
||||
namespace Eigen {
|
||||
@@ -37,7 +37,6 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
||||
};
|
||||
|
||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||
typedef typename internal::traits<Derived>::Index Index;
|
||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
@@ -76,8 +75,8 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
||||
|
||||
typedef typename Base::CoeffReturnType CoeffReturnType;
|
||||
|
||||
inline Index rows() const { return m_rows.value(); }
|
||||
inline Index cols() const { return m_cols.value(); }
|
||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_rows.value(); }
|
||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_cols.value(); }
|
||||
|
||||
/** Returns a pointer to the first coefficient of the matrix or vector.
|
||||
*
|
||||
@@ -85,24 +84,28 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
||||
*
|
||||
* \sa innerStride(), outerStride()
|
||||
*/
|
||||
inline const Scalar* data() const { return m_data; }
|
||||
EIGEN_DEVICE_FUNC inline const Scalar* data() const { return m_data; }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar& coeff(Index rowId, Index colId) const
|
||||
{
|
||||
return m_data[colId * colStride() + rowId * rowStride()];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar& coeff(Index index) const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
|
||||
return m_data[index * innerStride()];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar& coeffRef(Index rowId, Index colId) const
|
||||
{
|
||||
return this->m_data[colId * colStride() + rowId * rowStride()];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar& coeffRef(Index index) const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
|
||||
@@ -123,12 +126,14 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
||||
return internal::ploadt<PacketScalar, LoadMode>(m_data + index * innerStride());
|
||||
}
|
||||
|
||||
inline MapBase(PointerType dataPtr) : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit inline MapBase(PointerType dataPtr) : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
||||
checkSanity();
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline MapBase(PointerType dataPtr, Index vecSize)
|
||||
: m_data(dataPtr),
|
||||
m_rows(RowsAtCompileTime == Dynamic ? vecSize : Index(RowsAtCompileTime)),
|
||||
@@ -140,24 +145,24 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
||||
checkSanity();
|
||||
}
|
||||
|
||||
inline MapBase(PointerType dataPtr, Index nbRows, Index nbCols)
|
||||
: m_data(dataPtr), m_rows(nbRows), m_cols(nbCols)
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline MapBase(PointerType dataPtr, Index rows, Index cols)
|
||||
: m_data(dataPtr), m_rows(rows), m_cols(cols)
|
||||
{
|
||||
eigen_assert( (dataPtr == 0)
|
||||
|| ( nbRows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == nbRows)
|
||||
&& nbCols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == nbCols)));
|
||||
|| ( rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
|
||||
&& cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
|
||||
checkSanity();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
void checkSanity() const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(internal::traits<Derived>::Flags&PacketAccessBit,
|
||||
internal::inner_stride_at_compile_time<Derived>::ret==1),
|
||||
PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1);
|
||||
eigen_assert(EIGEN_IMPLIES(internal::traits<Derived>::Flags&AlignedBit, (size_t(m_data) % 16) == 0)
|
||||
&& "data is not aligned");
|
||||
#if EIGEN_MAX_ALIGN_BYTES>0
|
||||
eigen_assert(((size_t(m_data) % EIGEN_PLAIN_ENUM_MAX(1,internal::traits<Derived>::Alignment)) == 0) && "data is not aligned");
|
||||
#endif
|
||||
}
|
||||
|
||||
PointerType m_data;
|
||||
@@ -168,13 +173,14 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
||||
template<typename Derived> class MapBase<Derived, WriteAccessors>
|
||||
: public MapBase<Derived, ReadOnlyAccessors>
|
||||
{
|
||||
typedef MapBase<Derived, ReadOnlyAccessors> ReadOnlyMapBase;
|
||||
public:
|
||||
|
||||
typedef MapBase<Derived, ReadOnlyAccessors> Base;
|
||||
|
||||
typedef typename Base::Scalar Scalar;
|
||||
typedef typename Base::PacketScalar PacketScalar;
|
||||
typedef typename Base::Index Index;
|
||||
typedef typename Base::StorageIndex StorageIndex;
|
||||
typedef typename Base::PointerType PointerType;
|
||||
|
||||
using Base::derived;
|
||||
@@ -195,14 +201,18 @@ template<typename Derived> class MapBase<Derived, WriteAccessors>
|
||||
const Scalar
|
||||
>::type ScalarWithConstIfNotLvalue;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar* data() const { return this->m_data; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline ScalarWithConstIfNotLvalue* data() { return this->m_data; } // no const-cast here so non-const-correct code will give a compile error
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline ScalarWithConstIfNotLvalue& coeffRef(Index row, Index col)
|
||||
{
|
||||
return this->m_data[col * colStride() + row * rowStride()];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline ScalarWithConstIfNotLvalue& coeffRef(Index index)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
|
||||
@@ -224,19 +234,24 @@ template<typename Derived> class MapBase<Derived, WriteAccessors>
|
||||
(this->m_data + index * innerStride(), val);
|
||||
}
|
||||
|
||||
explicit inline MapBase(PointerType dataPtr) : Base(dataPtr) {}
|
||||
inline MapBase(PointerType dataPtr, Index vecSize) : Base(dataPtr, vecSize) {}
|
||||
inline MapBase(PointerType dataPtr, Index nbRows, Index nbCols) : Base(dataPtr, nbRows, nbCols) {}
|
||||
EIGEN_DEVICE_FUNC explicit inline MapBase(PointerType dataPtr) : Base(dataPtr) {}
|
||||
EIGEN_DEVICE_FUNC inline MapBase(PointerType dataPtr, Index vecSize) : Base(dataPtr, vecSize) {}
|
||||
EIGEN_DEVICE_FUNC inline MapBase(PointerType dataPtr, Index rows, Index cols) : Base(dataPtr, rows, cols) {}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator=(const MapBase& other)
|
||||
{
|
||||
Base::Base::operator=(other);
|
||||
ReadOnlyMapBase::Base::operator=(other);
|
||||
return derived();
|
||||
}
|
||||
|
||||
using Base::Base::operator=;
|
||||
// In theory we could simply refer to Base:Base::operator=, but MSVC does not like Base::Base,
|
||||
// see bugs 821 and 920.
|
||||
using ReadOnlyMapBase::Base::operator=;
|
||||
};
|
||||
|
||||
#undef EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_MAPBASE_H
|
||||
|
||||
@@ -10,8 +10,20 @@
|
||||
#ifndef EIGEN_MATHFUNCTIONS_H
|
||||
#define EIGEN_MATHFUNCTIONS_H
|
||||
|
||||
// source: http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html
|
||||
#define EIGEN_PI 3.141592653589793238462643383279502884197169399375105820974944592307816406
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
// On WINCE, std::abs is defined for int only, so let's defined our own overloads:
|
||||
// This issue has been confirmed with MSVC 2008 only, but the issue might exist for more recent versions too.
|
||||
#if EIGEN_OS_WINCE && EIGEN_COMP_MSVC && EIGEN_COMP_MSVC<=1500
|
||||
long abs(long x) { return (labs(x)); }
|
||||
double abs(double x) { return (fabs(x)); }
|
||||
float abs(float x) { return (fabsf(x)); }
|
||||
long double abs(long double x) { return (fabsl(x)); }
|
||||
#endif
|
||||
|
||||
namespace internal {
|
||||
|
||||
/** \internal \struct global_math_functions_filtering_base
|
||||
@@ -62,6 +74,7 @@ template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
|
||||
struct real_default_impl
|
||||
{
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline RealScalar run(const Scalar& x)
|
||||
{
|
||||
return x;
|
||||
@@ -72,6 +85,7 @@ template<typename Scalar>
|
||||
struct real_default_impl<Scalar,true>
|
||||
{
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline RealScalar run(const Scalar& x)
|
||||
{
|
||||
using std::real;
|
||||
@@ -87,7 +101,6 @@ struct real_retval
|
||||
typedef typename NumTraits<Scalar>::Real type;
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Implementation of imag *
|
||||
****************************************************************************/
|
||||
@@ -96,6 +109,7 @@ template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
|
||||
struct imag_default_impl
|
||||
{
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline RealScalar run(const Scalar&)
|
||||
{
|
||||
return RealScalar(0);
|
||||
@@ -106,6 +120,7 @@ template<typename Scalar>
|
||||
struct imag_default_impl<Scalar,true>
|
||||
{
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline RealScalar run(const Scalar& x)
|
||||
{
|
||||
using std::imag;
|
||||
@@ -129,10 +144,12 @@ template<typename Scalar>
|
||||
struct real_ref_impl
|
||||
{
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline RealScalar& run(Scalar& x)
|
||||
{
|
||||
return reinterpret_cast<RealScalar*>(&x)[0];
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline const RealScalar& run(const Scalar& x)
|
||||
{
|
||||
return reinterpret_cast<const RealScalar*>(&x)[0];
|
||||
@@ -153,10 +170,12 @@ template<typename Scalar, bool IsComplex>
|
||||
struct imag_ref_default_impl
|
||||
{
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline RealScalar& run(Scalar& x)
|
||||
{
|
||||
return reinterpret_cast<RealScalar*>(&x)[1];
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline const RealScalar& run(const Scalar& x)
|
||||
{
|
||||
return reinterpret_cast<RealScalar*>(&x)[1];
|
||||
@@ -166,10 +185,12 @@ struct imag_ref_default_impl
|
||||
template<typename Scalar>
|
||||
struct imag_ref_default_impl<Scalar, false>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline Scalar run(Scalar&)
|
||||
{
|
||||
return Scalar(0);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline const Scalar run(const Scalar&)
|
||||
{
|
||||
return Scalar(0);
|
||||
@@ -192,6 +213,7 @@ struct imag_ref_retval
|
||||
template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
|
||||
struct conj_impl
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline Scalar run(const Scalar& x)
|
||||
{
|
||||
return x;
|
||||
@@ -201,6 +223,7 @@ struct conj_impl
|
||||
template<typename Scalar>
|
||||
struct conj_impl<Scalar,true>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline Scalar run(const Scalar& x)
|
||||
{
|
||||
using std::conj;
|
||||
@@ -222,6 +245,7 @@ template<typename Scalar>
|
||||
struct abs2_impl
|
||||
{
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline RealScalar run(const Scalar& x)
|
||||
{
|
||||
return x*x;
|
||||
@@ -231,6 +255,7 @@ struct abs2_impl
|
||||
template<typename RealScalar>
|
||||
struct abs2_impl<std::complex<RealScalar> >
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline RealScalar run(const std::complex<RealScalar>& x)
|
||||
{
|
||||
return real(x)*real(x) + imag(x)*imag(x);
|
||||
@@ -251,9 +276,10 @@ template<typename Scalar, bool IsComplex>
|
||||
struct norm1_default_impl
|
||||
{
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline RealScalar run(const Scalar& x)
|
||||
{
|
||||
using std::abs;
|
||||
EIGEN_USING_STD_MATH(abs);
|
||||
return abs(real(x)) + abs(imag(x));
|
||||
}
|
||||
};
|
||||
@@ -261,9 +287,10 @@ struct norm1_default_impl
|
||||
template<typename Scalar>
|
||||
struct norm1_default_impl<Scalar, false>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline Scalar run(const Scalar& x)
|
||||
{
|
||||
using std::abs;
|
||||
EIGEN_USING_STD_MATH(abs);
|
||||
return abs(x);
|
||||
}
|
||||
};
|
||||
@@ -287,16 +314,24 @@ struct hypot_impl
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
static inline RealScalar run(const Scalar& x, const Scalar& y)
|
||||
{
|
||||
using std::max;
|
||||
using std::min;
|
||||
using std::abs;
|
||||
using std::sqrt;
|
||||
EIGEN_USING_STD_MATH(max);
|
||||
EIGEN_USING_STD_MATH(min);
|
||||
EIGEN_USING_STD_MATH(abs);
|
||||
EIGEN_USING_STD_MATH(sqrt);
|
||||
RealScalar _x = abs(x);
|
||||
RealScalar _y = abs(y);
|
||||
RealScalar p = (max)(_x, _y);
|
||||
if(p==RealScalar(0)) return 0;
|
||||
RealScalar q = (min)(_x, _y);
|
||||
RealScalar qp = q/p;
|
||||
Scalar p, qp;
|
||||
if(_x>_y)
|
||||
{
|
||||
p = _x;
|
||||
qp = _y / p;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = _y;
|
||||
qp = _x / p;
|
||||
}
|
||||
if(p==RealScalar(0)) return RealScalar(0);
|
||||
return p * sqrt(RealScalar(1) + qp*qp);
|
||||
}
|
||||
};
|
||||
@@ -314,6 +349,7 @@ struct hypot_retval
|
||||
template<typename OldType, typename NewType>
|
||||
struct cast_impl
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline NewType run(const OldType& x)
|
||||
{
|
||||
return static_cast<NewType>(x);
|
||||
@@ -323,48 +359,121 @@ struct cast_impl
|
||||
// here, for once, we're plainly returning NewType: we don't want cast to do weird things.
|
||||
|
||||
template<typename OldType, typename NewType>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline NewType cast(const OldType& x)
|
||||
{
|
||||
return cast_impl<OldType, NewType>::run(x);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Implementation of atanh2 *
|
||||
* Implementation of round *
|
||||
****************************************************************************/
|
||||
|
||||
template<typename Scalar, bool IsInteger>
|
||||
struct atanh2_default_impl
|
||||
{
|
||||
typedef Scalar retval;
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
static inline Scalar run(const Scalar& x, const Scalar& y)
|
||||
#if EIGEN_HAS_CXX11_MATH
|
||||
template<typename Scalar>
|
||||
struct round_impl {
|
||||
static inline Scalar run(const Scalar& x)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
|
||||
using std::round;
|
||||
return round(x);
|
||||
}
|
||||
};
|
||||
#else
|
||||
template<typename Scalar>
|
||||
struct round_impl
|
||||
{
|
||||
using std::abs;
|
||||
using std::log;
|
||||
using std::sqrt;
|
||||
Scalar z = x / y;
|
||||
if (y == Scalar(0) || abs(z) > sqrt(NumTraits<RealScalar>::epsilon()))
|
||||
return RealScalar(0.5) * log((y + x) / (y - x));
|
||||
else
|
||||
return z + z*z*z / RealScalar(3);
|
||||
}
|
||||
};
|
||||
static inline Scalar run(const Scalar& x)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
|
||||
EIGEN_USING_STD_MATH(floor);
|
||||
EIGEN_USING_STD_MATH(ceil);
|
||||
return (x > Scalar(0)) ? floor(x + Scalar(0.5)) : ceil(x - Scalar(0.5));
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
template<typename Scalar>
|
||||
struct atanh2_default_impl<Scalar, true>
|
||||
struct round_retval
|
||||
{
|
||||
static inline Scalar run(const Scalar&, const Scalar&)
|
||||
typedef Scalar type;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Implementation of arg *
|
||||
****************************************************************************/
|
||||
|
||||
#if EIGEN_HAS_CXX11_MATH
|
||||
template<typename Scalar>
|
||||
struct arg_impl {
|
||||
static inline Scalar run(const Scalar& x)
|
||||
{
|
||||
EIGEN_USING_STD_MATH(arg);
|
||||
return arg(x);
|
||||
}
|
||||
};
|
||||
#else
|
||||
template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
|
||||
struct arg_default_impl
|
||||
{
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline RealScalar run(const Scalar& x)
|
||||
{
|
||||
return (x < Scalar(0)) ? Scalar(EIGEN_PI) : Scalar(0); }
|
||||
};
|
||||
|
||||
template<typename Scalar>
|
||||
struct arg_default_impl<Scalar,true>
|
||||
{
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline RealScalar run(const Scalar& x)
|
||||
{
|
||||
EIGEN_USING_STD_MATH(arg);
|
||||
return arg(x);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Scalar> struct arg_impl : arg_default_impl<Scalar> {};
|
||||
#endif
|
||||
|
||||
template<typename Scalar>
|
||||
struct arg_retval
|
||||
{
|
||||
typedef typename NumTraits<Scalar>::Real type;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Implementation of log1p *
|
||||
****************************************************************************/
|
||||
template<typename Scalar, bool isComplex = NumTraits<Scalar>::IsComplex >
|
||||
struct log1p_impl
|
||||
{
|
||||
static inline Scalar run(const Scalar& x)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
|
||||
return Scalar(0);
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
EIGEN_USING_STD_MATH(log);
|
||||
Scalar x1p = RealScalar(1) + x;
|
||||
return ( x1p == Scalar(1) ) ? x : x * ( log(x1p) / (x1p - RealScalar(1)) );
|
||||
}
|
||||
};
|
||||
|
||||
#if EIGEN_HAS_CXX11_MATH
|
||||
template<typename Scalar>
|
||||
struct atanh2_impl : atanh2_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
|
||||
struct log1p_impl<Scalar, false> {
|
||||
static inline Scalar run(const Scalar& x)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
|
||||
using std::log1p;
|
||||
return log1p(x);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
template<typename Scalar>
|
||||
struct atanh2_retval
|
||||
struct log1p_retval
|
||||
{
|
||||
typedef Scalar type;
|
||||
};
|
||||
@@ -379,7 +488,7 @@ struct pow_default_impl
|
||||
typedef Scalar retval;
|
||||
static inline Scalar run(const Scalar& x, const Scalar& y)
|
||||
{
|
||||
using std::pow;
|
||||
EIGEN_USING_STD_MATH(pow);
|
||||
return pow(x, y);
|
||||
}
|
||||
};
|
||||
@@ -447,48 +556,48 @@ struct random_default_impl<Scalar, false, false>
|
||||
};
|
||||
|
||||
enum {
|
||||
floor_log2_terminate,
|
||||
floor_log2_move_up,
|
||||
floor_log2_move_down,
|
||||
floor_log2_bogus
|
||||
meta_floor_log2_terminate,
|
||||
meta_floor_log2_move_up,
|
||||
meta_floor_log2_move_down,
|
||||
meta_floor_log2_bogus
|
||||
};
|
||||
|
||||
template<unsigned int n, int lower, int upper> struct floor_log2_selector
|
||||
template<unsigned int n, int lower, int upper> struct meta_floor_log2_selector
|
||||
{
|
||||
enum { middle = (lower + upper) / 2,
|
||||
value = (upper <= lower + 1) ? int(floor_log2_terminate)
|
||||
: (n < (1 << middle)) ? int(floor_log2_move_down)
|
||||
: (n==0) ? int(floor_log2_bogus)
|
||||
: int(floor_log2_move_up)
|
||||
value = (upper <= lower + 1) ? int(meta_floor_log2_terminate)
|
||||
: (n < (1 << middle)) ? int(meta_floor_log2_move_down)
|
||||
: (n==0) ? int(meta_floor_log2_bogus)
|
||||
: int(meta_floor_log2_move_up)
|
||||
};
|
||||
};
|
||||
|
||||
template<unsigned int n,
|
||||
int lower = 0,
|
||||
int upper = sizeof(unsigned int) * CHAR_BIT - 1,
|
||||
int selector = floor_log2_selector<n, lower, upper>::value>
|
||||
struct floor_log2 {};
|
||||
int selector = meta_floor_log2_selector<n, lower, upper>::value>
|
||||
struct meta_floor_log2 {};
|
||||
|
||||
template<unsigned int n, int lower, int upper>
|
||||
struct floor_log2<n, lower, upper, floor_log2_move_down>
|
||||
struct meta_floor_log2<n, lower, upper, meta_floor_log2_move_down>
|
||||
{
|
||||
enum { value = floor_log2<n, lower, floor_log2_selector<n, lower, upper>::middle>::value };
|
||||
enum { value = meta_floor_log2<n, lower, meta_floor_log2_selector<n, lower, upper>::middle>::value };
|
||||
};
|
||||
|
||||
template<unsigned int n, int lower, int upper>
|
||||
struct floor_log2<n, lower, upper, floor_log2_move_up>
|
||||
struct meta_floor_log2<n, lower, upper, meta_floor_log2_move_up>
|
||||
{
|
||||
enum { value = floor_log2<n, floor_log2_selector<n, lower, upper>::middle, upper>::value };
|
||||
enum { value = meta_floor_log2<n, meta_floor_log2_selector<n, lower, upper>::middle, upper>::value };
|
||||
};
|
||||
|
||||
template<unsigned int n, int lower, int upper>
|
||||
struct floor_log2<n, lower, upper, floor_log2_terminate>
|
||||
struct meta_floor_log2<n, lower, upper, meta_floor_log2_terminate>
|
||||
{
|
||||
enum { value = (n >= ((unsigned int)(1) << (lower+1))) ? lower+1 : lower };
|
||||
};
|
||||
|
||||
template<unsigned int n, int lower, int upper>
|
||||
struct floor_log2<n, lower, upper, floor_log2_bogus>
|
||||
struct meta_floor_log2<n, lower, upper, meta_floor_log2_bogus>
|
||||
{
|
||||
// no value, error at compile time
|
||||
};
|
||||
@@ -496,11 +605,24 @@ struct floor_log2<n, lower, upper, floor_log2_bogus>
|
||||
template<typename Scalar>
|
||||
struct random_default_impl<Scalar, false, true>
|
||||
{
|
||||
typedef typename NumTraits<Scalar>::NonInteger NonInteger;
|
||||
|
||||
static inline Scalar run(const Scalar& x, const Scalar& y)
|
||||
{
|
||||
return x + Scalar((NonInteger(y)-x+1) * std::rand() / (RAND_MAX + NonInteger(1)));
|
||||
{
|
||||
using std::max;
|
||||
using std::min;
|
||||
typedef typename conditional<NumTraits<Scalar>::IsSigned,std::ptrdiff_t,std::size_t>::type ScalarX;
|
||||
if(y<x)
|
||||
return x;
|
||||
std::size_t range = ScalarX(y)-ScalarX(x);
|
||||
std::size_t offset = 0;
|
||||
// rejection sampling
|
||||
std::size_t divisor = (range+RAND_MAX-1)/(range+1);
|
||||
std::size_t multiplier = (range+RAND_MAX-1)/std::size_t(RAND_MAX);
|
||||
|
||||
do {
|
||||
offset = ( (std::size_t(std::rand()) * multiplier) / divisor );
|
||||
} while (offset > range);
|
||||
|
||||
return Scalar(ScalarX(x) + offset);
|
||||
}
|
||||
|
||||
static inline Scalar run()
|
||||
@@ -508,7 +630,7 @@ struct random_default_impl<Scalar, false, true>
|
||||
#ifdef EIGEN_MAKING_DOCS
|
||||
return run(Scalar(NumTraits<Scalar>::IsSigned ? -10 : 0), Scalar(10));
|
||||
#else
|
||||
enum { rand_bits = floor_log2<(unsigned int)(RAND_MAX)+1>::value,
|
||||
enum { rand_bits = meta_floor_log2<(unsigned int)(RAND_MAX)+1>::value,
|
||||
scalar_bits = sizeof(Scalar) * CHAR_BIT,
|
||||
shift = EIGEN_PLAIN_ENUM_MAX(0, int(rand_bits) - int(scalar_bits)),
|
||||
offset = NumTraits<Scalar>::IsSigned ? (1 << (EIGEN_PLAIN_ENUM_MIN(rand_bits,scalar_bits)-1)) : 0
|
||||
@@ -548,88 +670,236 @@ inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
|
||||
} // end namespace internal
|
||||
|
||||
/****************************************************************************
|
||||
* Generic math function *
|
||||
* Generic math functions *
|
||||
****************************************************************************/
|
||||
|
||||
namespace numext {
|
||||
|
||||
#ifndef __CUDA_ARCH__
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_ALWAYS_INLINE T mini(const T& x, const T& y)
|
||||
{
|
||||
EIGEN_USING_STD_MATH(min);
|
||||
return min EIGEN_NOT_A_MACRO (x,y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_ALWAYS_INLINE T maxi(const T& x, const T& y)
|
||||
{
|
||||
EIGEN_USING_STD_MATH(max);
|
||||
return max EIGEN_NOT_A_MACRO (x,y);
|
||||
}
|
||||
#else
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_ALWAYS_INLINE T mini(const T& x, const T& y)
|
||||
{
|
||||
return y < x ? y : x;
|
||||
}
|
||||
template<>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_ALWAYS_INLINE float mini(const float& x, const float& y)
|
||||
{
|
||||
return fmin(x, y);
|
||||
}
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_ALWAYS_INLINE T maxi(const T& x, const T& y)
|
||||
{
|
||||
return x < y ? y : x;
|
||||
}
|
||||
template<>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_ALWAYS_INLINE float maxi(const float& x, const float& y)
|
||||
{
|
||||
return fmax(x, y);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
template<typename Scalar>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(const Scalar& x)
|
||||
{
|
||||
return internal::real_ref_impl<Scalar>::run(x);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline EIGEN_MATHFUNC_RETVAL(arg, Scalar) arg(const Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(arg, Scalar)::run(x);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x)
|
||||
{
|
||||
return internal::imag_ref_impl<Scalar>::run(x);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
inline EIGEN_MATHFUNC_RETVAL(atanh2, Scalar) atanh2(const Scalar& x, const Scalar& y)
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline EIGEN_MATHFUNC_RETVAL(log1p, Scalar) log1p(const Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(atanh2, Scalar)::run(x, y);
|
||||
return EIGEN_MATHFUNC_IMPL(log1p, Scalar)::run(x);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y);
|
||||
}
|
||||
|
||||
// std::isfinite is non standard, so let's define our own version,
|
||||
// even though it is not very efficient.
|
||||
template<typename T> bool (isfinite)(const T& x)
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
bool (isfinite)(const T& x)
|
||||
{
|
||||
return x<NumTraits<T>::highest() && x>NumTraits<T>::lowest();
|
||||
#if EIGEN_HAS_CXX11_MATH
|
||||
using std::isfinite;
|
||||
return isfinite EIGEN_NOT_A_MACRO (x);
|
||||
#else
|
||||
return x<NumTraits<T>::highest() && x>NumTraits<T>::lowest();
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
bool (isnan)(const T& x)
|
||||
{
|
||||
#if EIGEN_HAS_CXX11_MATH
|
||||
using std::isnan;
|
||||
return isnan EIGEN_NOT_A_MACRO (x);
|
||||
#else
|
||||
return x != x;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
bool (isinf)(const T& x)
|
||||
{
|
||||
#if EIGEN_HAS_CXX11_MATH
|
||||
using std::isinf;
|
||||
return isinf EIGEN_NOT_A_MACRO (x);
|
||||
#else
|
||||
return x>NumTraits<T>::highest() || x<NumTraits<T>::lowest();
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool (isfinite)(const std::complex<T>& x)
|
||||
{
|
||||
return (numext::isfinite)(numext::real(x)) && (numext::isfinite)(numext::imag(x));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool (isnan)(const std::complex<T>& x)
|
||||
{
|
||||
return (numext::isnan)(numext::real(x)) || (numext::isnan)(numext::imag(x));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool (isinf)(const std::complex<T>& x)
|
||||
{
|
||||
return ((numext::isinf)(numext::real(x)) || (numext::isinf)(numext::imag(x))) && (!(numext::isnan)(x));
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline EIGEN_MATHFUNC_RETVAL(round, Scalar) round(const Scalar& x)
|
||||
{
|
||||
return EIGEN_MATHFUNC_IMPL(round, Scalar)::run(x);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
T (floor)(const T& x)
|
||||
{
|
||||
EIGEN_USING_STD_MATH(floor);
|
||||
return floor(x);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
T (ceil)(const T& x)
|
||||
{
|
||||
EIGEN_USING_STD_MATH(ceil);
|
||||
return ceil(x);
|
||||
}
|
||||
|
||||
// Log base 2 for 32 bits positive integers.
|
||||
// Conveniently returns 0 for x==0.
|
||||
inline int log2(int x)
|
||||
{
|
||||
eigen_assert(x>=0);
|
||||
unsigned int v(x);
|
||||
static const int table[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
return table[(v * 0x07C4ACDDU) >> 27];
|
||||
}
|
||||
|
||||
} // end namespace numext
|
||||
@@ -649,18 +919,20 @@ template<typename Scalar>
|
||||
struct scalar_fuzzy_default_impl<Scalar, false, false>
|
||||
{
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
template<typename OtherScalar>
|
||||
template<typename OtherScalar> EIGEN_DEVICE_FUNC
|
||||
static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
|
||||
{
|
||||
using std::abs;
|
||||
EIGEN_USING_STD_MATH(abs);
|
||||
return abs(x) <= abs(y) * prec;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
|
||||
{
|
||||
using std::min;
|
||||
using std::abs;
|
||||
EIGEN_USING_STD_MATH(min);
|
||||
EIGEN_USING_STD_MATH(abs);
|
||||
return abs(x - y) <= (min)(abs(x), abs(y)) * prec;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar& prec)
|
||||
{
|
||||
return x <= y || isApprox(x, y, prec);
|
||||
@@ -671,15 +943,17 @@ template<typename Scalar>
|
||||
struct scalar_fuzzy_default_impl<Scalar, false, true>
|
||||
{
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
template<typename OtherScalar>
|
||||
template<typename OtherScalar> EIGEN_DEVICE_FUNC
|
||||
static inline bool isMuchSmallerThan(const Scalar& x, const Scalar&, const RealScalar&)
|
||||
{
|
||||
return x == Scalar(0);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar&)
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar&)
|
||||
{
|
||||
return x <= y;
|
||||
@@ -697,7 +971,7 @@ struct scalar_fuzzy_default_impl<Scalar, true, false>
|
||||
}
|
||||
static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
|
||||
{
|
||||
using std::min;
|
||||
EIGEN_USING_STD_MATH(min);
|
||||
return numext::abs2(x - y) <= (min)(numext::abs2(x), numext::abs2(y)) * prec * prec;
|
||||
}
|
||||
};
|
||||
@@ -705,21 +979,21 @@ struct scalar_fuzzy_default_impl<Scalar, true, false>
|
||||
template<typename Scalar>
|
||||
struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
|
||||
|
||||
template<typename Scalar, typename OtherScalar>
|
||||
template<typename Scalar, typename OtherScalar> EIGEN_DEVICE_FUNC
|
||||
inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y,
|
||||
typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
|
||||
{
|
||||
return scalar_fuzzy_impl<Scalar>::template isMuchSmallerThan<OtherScalar>(x, y, precision);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
template<typename Scalar> EIGEN_DEVICE_FUNC
|
||||
inline bool isApprox(const Scalar& x, const Scalar& y,
|
||||
typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
|
||||
{
|
||||
return scalar_fuzzy_impl<Scalar>::isApprox(x, y, precision);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
template<typename Scalar> EIGEN_DEVICE_FUNC
|
||||
inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y,
|
||||
typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
|
||||
{
|
||||
@@ -742,17 +1016,19 @@ template<> struct scalar_fuzzy_impl<bool>
|
||||
{
|
||||
typedef bool RealScalar;
|
||||
|
||||
template<typename OtherScalar>
|
||||
template<typename OtherScalar> EIGEN_DEVICE_FUNC
|
||||
static inline bool isMuchSmallerThan(const bool& x, const bool&, const bool&)
|
||||
{
|
||||
return !x;
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline bool isApprox(bool x, bool y, bool)
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline bool isApproxOrLessThan(const bool& x, const bool& y, const bool&)
|
||||
{
|
||||
return (!x) || y;
|
||||
|
||||
@@ -24,13 +24,13 @@ namespace Eigen {
|
||||
* The %Matrix class encompasses \em both fixed-size and dynamic-size objects (\ref fixedsize "note").
|
||||
*
|
||||
* The first three template parameters are required:
|
||||
* \tparam _Scalar \anchor matrix_tparam_scalar Numeric type, e.g. float, double, int or std::complex<float>.
|
||||
* User defined sclar types are supported as well (see \ref user_defined_scalars "here").
|
||||
* \tparam _Scalar Numeric type, e.g. float, double, int or std::complex<float>.
|
||||
* User defined scalar types are supported as well (see \ref user_defined_scalars "here").
|
||||
* \tparam _Rows Number of rows, or \b Dynamic
|
||||
* \tparam _Cols Number of columns, or \b Dynamic
|
||||
*
|
||||
* The remaining template parameters are optional -- in most cases you don't have to worry about them.
|
||||
* \tparam _Options \anchor matrix_tparam_options A combination of either \b #RowMajor or \b #ColMajor, and of either
|
||||
* \tparam _Options A combination of either \b #RowMajor or \b #ColMajor, and of either
|
||||
* \b #AutoAlign or \b #DontAlign.
|
||||
* The former controls \ref TopicStorageOrders "storage order", and defaults to column-major. The latter controls alignment, which is required
|
||||
* for vectorization. It defaults to aligning matrices except for fixed sizes that aren't a multiple of the packet size.
|
||||
@@ -97,6 +97,40 @@ namespace Eigen {
|
||||
* are the dimensions of the original matrix, while _Rows and _Cols are Dynamic.</dd>
|
||||
* </dl>
|
||||
*
|
||||
* <i><b>ABI and storage layout</b></i>
|
||||
*
|
||||
* The table below summarizes the ABI of some possible Matrix instances which is fixed thorough the lifetime of Eigen 3.
|
||||
* <table class="manual">
|
||||
* <tr><th>Matrix type</th><th>Equivalent C structure</th></tr>
|
||||
* <tr><td>\code Matrix<T,Dynamic,Dynamic> \endcode</td><td>\code
|
||||
* struct {
|
||||
* T *data; // with (size_t(data)%EIGEN_MAX_ALIGN_BYTES)==0
|
||||
* Eigen::Index rows, cols;
|
||||
* };
|
||||
* \endcode</td></tr>
|
||||
* <tr class="alt"><td>\code
|
||||
* Matrix<T,Dynamic,1>
|
||||
* Matrix<T,1,Dynamic> \endcode</td><td>\code
|
||||
* struct {
|
||||
* T *data; // with (size_t(data)%EIGEN_MAX_ALIGN_BYTES)==0
|
||||
* Eigen::Index size;
|
||||
* };
|
||||
* \endcode</td></tr>
|
||||
* <tr><td>\code Matrix<T,Rows,Cols> \endcode</td><td>\code
|
||||
* struct {
|
||||
* T data[Rows*Cols]; // with (size_t(data)%A(Rows*Cols*sizeof(T)))==0
|
||||
* };
|
||||
* \endcode</td></tr>
|
||||
* <tr class="alt"><td>\code Matrix<T,Dynamic,Dynamic,0,MaxRows,MaxCols> \endcode</td><td>\code
|
||||
* struct {
|
||||
* T data[MaxRows*MaxCols]; // with (size_t(data)%A(MaxRows*MaxCols*sizeof(T)))==0
|
||||
* Eigen::Index rows, cols;
|
||||
* };
|
||||
* \endcode</td></tr>
|
||||
* </table>
|
||||
* Note that in this table Rows, Cols, MaxRows and MaxCols are all positive integers. A(S) is defined to the largest possible power-of-two
|
||||
* smaller to EIGEN_MAX_STATIC_ALIGN_BYTES.
|
||||
*
|
||||
* \see MatrixBase for the majority of the API methods for matrices, \ref TopicClassHierarchy,
|
||||
* \ref TopicStorageOrders
|
||||
*/
|
||||
@@ -105,9 +139,23 @@ namespace internal {
|
||||
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
||||
struct traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
|
||||
{
|
||||
private:
|
||||
enum { size = internal::size_at_compile_time<_Rows,_Cols>::ret };
|
||||
typedef typename find_best_packet<_Scalar,size>::type PacketScalar;
|
||||
enum {
|
||||
row_major_bit = _Options&RowMajor ? RowMajorBit : 0,
|
||||
is_dynamic_size_storage = _MaxRows==Dynamic || _MaxCols==Dynamic,
|
||||
max_size = is_dynamic_size_storage ? Dynamic : _MaxRows*_MaxCols,
|
||||
default_alignment = compute_default_alignment<_Scalar,max_size>::value,
|
||||
actual_alignment = ((_Options&DontAlign)==0) ? default_alignment : 0,
|
||||
required_alignment = unpacket_traits<PacketScalar>::alignment,
|
||||
packet_access_bit = packet_traits<_Scalar>::Vectorizable && (actual_alignment>=required_alignment) ? PacketAccessBit : 0
|
||||
};
|
||||
|
||||
public:
|
||||
typedef _Scalar Scalar;
|
||||
typedef Dense StorageKind;
|
||||
typedef DenseIndex Index;
|
||||
typedef Eigen::Index StorageIndex;
|
||||
typedef MatrixXpr XprKind;
|
||||
enum {
|
||||
RowsAtCompileTime = _Rows,
|
||||
@@ -115,10 +163,13 @@ struct traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
|
||||
MaxRowsAtCompileTime = _MaxRows,
|
||||
MaxColsAtCompileTime = _MaxCols,
|
||||
Flags = compute_matrix_flags<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ret,
|
||||
CoeffReadCost = NumTraits<Scalar>::ReadCost,
|
||||
Options = _Options,
|
||||
InnerStrideAtCompileTime = 1,
|
||||
OuterStrideAtCompileTime = (Options&RowMajor) ? ColsAtCompileTime : RowsAtCompileTime
|
||||
OuterStrideAtCompileTime = (Options&RowMajor) ? ColsAtCompileTime : RowsAtCompileTime,
|
||||
|
||||
// FIXME, the following flag in only used to define NeedsToAlign in PlainObjectBase
|
||||
EvaluatorFlags = LinearAccessBit | DirectAccessBit | packet_access_bit | row_major_bit,
|
||||
Alignment = actual_alignment
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -151,6 +202,7 @@ class Matrix
|
||||
*
|
||||
* \callgraph
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Matrix& operator=(const Matrix& other)
|
||||
{
|
||||
return Base::_set(other);
|
||||
@@ -167,7 +219,8 @@ class Matrix
|
||||
* remain row-vectors and vectors remain vectors.
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE Matrix& operator=(const MatrixBase<OtherDerived>& other)
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Matrix& operator=(const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
return Base::_set(other);
|
||||
}
|
||||
@@ -179,12 +232,14 @@ class Matrix
|
||||
* \copydetails DenseBase::operator=(const EigenBase<OtherDerived> &other)
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Matrix& operator=(const EigenBase<OtherDerived> &other)
|
||||
{
|
||||
return Base::operator=(other);
|
||||
}
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Matrix& operator=(const ReturnByValue<OtherDerived>& func)
|
||||
{
|
||||
return Base::operator=(func);
|
||||
@@ -200,6 +255,7 @@ class Matrix
|
||||
*
|
||||
* \sa resize(Index,Index)
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Matrix() : Base()
|
||||
{
|
||||
Base::_check_template_params();
|
||||
@@ -207,45 +263,87 @@ class Matrix
|
||||
}
|
||||
|
||||
// FIXME is it still needed
|
||||
Matrix(internal::constructor_without_unaligned_array_assert)
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit Matrix(internal::constructor_without_unaligned_array_assert)
|
||||
: Base(internal::constructor_without_unaligned_array_assert())
|
||||
{ Base::_check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED }
|
||||
|
||||
/** \brief Constructs a vector or row-vector with given dimension. \only_for_vectors
|
||||
*
|
||||
* Note that this is only useful for dynamic-size vectors. For fixed-size vectors,
|
||||
* it is redundant to pass the dimension here, so it makes more sense to use the default
|
||||
* constructor Matrix() instead.
|
||||
*/
|
||||
EIGEN_STRONG_INLINE explicit Matrix(Index dim)
|
||||
: Base(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim)
|
||||
#ifdef EIGEN_HAVE_RVALUE_REFERENCES
|
||||
EIGEN_DEVICE_FUNC
|
||||
Matrix(Matrix&& other)
|
||||
: Base(std::move(other))
|
||||
{
|
||||
Base::_check_template_params();
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix)
|
||||
eigen_assert(dim >= 0);
|
||||
eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim);
|
||||
EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
||||
if (RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic)
|
||||
Base::_set_noalias(other);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
Matrix& operator=(Matrix&& other)
|
||||
{
|
||||
other.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
// This constructor is for both 1x1 matrices and dynamic vectors
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE explicit Matrix(const T& x)
|
||||
{
|
||||
Base::_check_template_params();
|
||||
Base::template _init1<T>(x);
|
||||
}
|
||||
|
||||
template<typename T0, typename T1>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Matrix(const T0& x, const T1& y)
|
||||
{
|
||||
Base::_check_template_params();
|
||||
Base::template _init2<T0,T1>(x, y);
|
||||
}
|
||||
#else
|
||||
/** \brief Constructs a fixed-sized matrix initialized with coefficients starting at \a data */
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit Matrix(const Scalar *data);
|
||||
|
||||
/** \brief Constructs a vector or row-vector with given dimension. \only_for_vectors
|
||||
*
|
||||
* This is useful for dynamic-size vectors. For fixed-size vectors,
|
||||
* it is redundant to pass these parameters, so one should use the default constructor
|
||||
* Matrix() instead.
|
||||
*
|
||||
* \warning This constructor is disabled for fixed-size \c 1x1 matrices. For instance,
|
||||
* calling Matrix<double,1,1>(1) will call the initialization constructor: Matrix(const Scalar&).
|
||||
* For fixed-size \c 1x1 matrices it is therefore recommended to use the default
|
||||
* constructor Matrix() instead, especially when using one of the non standard
|
||||
* \c EIGEN_INITIALIZE_MATRICES_BY_{ZERO,\c NAN} macros (see \ref TopicPreprocessorDirectives).
|
||||
*/
|
||||
EIGEN_STRONG_INLINE explicit Matrix(Index dim);
|
||||
/** \brief Constructs an initialized 1x1 matrix with the given coefficient */
|
||||
Matrix(const Scalar& x);
|
||||
/** \brief Constructs an uninitialized matrix with \a rows rows and \a cols columns.
|
||||
*
|
||||
* This is useful for dynamic-size matrices. For fixed-size matrices,
|
||||
* it is redundant to pass these parameters, so one should use the default constructor
|
||||
* Matrix() instead. */
|
||||
* Matrix() instead.
|
||||
*
|
||||
* \warning This constructor is disabled for fixed-size \c 1x2 and \c 2x1 vectors. For instance,
|
||||
* calling Matrix2f(2,1) will call the initialization constructor: Matrix(const Scalar& x, const Scalar& y).
|
||||
* For fixed-size \c 1x2 or \c 2x1 vectors it is therefore recommended to use the default
|
||||
* constructor Matrix() instead, especially when using one of the non standard
|
||||
* \c EIGEN_INITIALIZE_MATRICES_BY_{ZERO,\c NAN} macros (see \ref TopicPreprocessorDirectives).
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
Matrix(Index rows, Index cols);
|
||||
|
||||
/** \brief Constructs an initialized 2D vector with given coefficients */
|
||||
Matrix(const Scalar& x, const Scalar& y);
|
||||
#endif
|
||||
|
||||
/** \brief Constructs an initialized 3D vector with given coefficients */
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z)
|
||||
{
|
||||
Base::_check_template_params();
|
||||
@@ -255,6 +353,7 @@ class Matrix
|
||||
m_storage.data()[2] = z;
|
||||
}
|
||||
/** \brief Constructs an initialized 4D vector with given coefficients */
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w)
|
||||
{
|
||||
Base::_check_template_params();
|
||||
@@ -265,76 +364,33 @@ class Matrix
|
||||
m_storage.data()[3] = w;
|
||||
}
|
||||
|
||||
explicit Matrix(const Scalar *data);
|
||||
|
||||
/** \brief Constructor copying the value of the expression \a other */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE Matrix(const MatrixBase<OtherDerived>& other)
|
||||
: Base(other.rows() * other.cols(), other.rows(), other.cols())
|
||||
{
|
||||
// This test resides here, to bring the error messages closer to the user. Normally, these checks
|
||||
// are performed deeply within the library, thus causing long and scary error traces.
|
||||
EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
|
||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||
|
||||
Base::_check_template_params();
|
||||
Base::_set_noalias(other);
|
||||
}
|
||||
/** \brief Copy constructor */
|
||||
EIGEN_STRONG_INLINE Matrix(const Matrix& other)
|
||||
: Base(other.rows() * other.cols(), other.rows(), other.cols())
|
||||
{
|
||||
Base::_check_template_params();
|
||||
Base::_set_noalias(other);
|
||||
}
|
||||
/** \brief Copy constructor with in-place evaluation */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE Matrix(const ReturnByValue<OtherDerived>& other)
|
||||
{
|
||||
Base::_check_template_params();
|
||||
Base::resize(other.rows(), other.cols());
|
||||
other.evalTo(*this);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Matrix(const Matrix& other) : Base(other)
|
||||
{ }
|
||||
|
||||
/** \brief Copy constructor for generic expressions.
|
||||
* \sa MatrixBase::operator=(const EigenBase<OtherDerived>&)
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Matrix(const EigenBase<OtherDerived> &other)
|
||||
: Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
|
||||
{
|
||||
Base::_check_template_params();
|
||||
Base::resize(other.rows(), other.cols());
|
||||
// FIXME/CHECK: isn't *this = other.derived() more efficient. it allows to
|
||||
// go for pure _set() implementations, right?
|
||||
*this = other;
|
||||
}
|
||||
: Base(other.derived())
|
||||
{ }
|
||||
|
||||
/** \internal
|
||||
* \brief Override MatrixBase::swap() since for dynamic-sized matrices
|
||||
* of same type it is enough to swap the data pointers.
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
void swap(MatrixBase<OtherDerived> const & other)
|
||||
{ this->_swap(other.derived()); }
|
||||
|
||||
inline Index innerStride() const { return 1; }
|
||||
inline Index outerStride() const { return this->innerSize(); }
|
||||
EIGEN_DEVICE_FUNC inline Index innerStride() const { return 1; }
|
||||
EIGEN_DEVICE_FUNC inline Index outerStride() const { return this->innerSize(); }
|
||||
|
||||
/////////// Geometry module ///////////
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit Matrix(const RotationBase<OtherDerived,ColsAtCompileTime>& r);
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Matrix& operator=(const RotationBase<OtherDerived,ColsAtCompileTime>& r);
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
template<typename OtherDerived>
|
||||
explicit Matrix(const eigen2_RotationBase<OtherDerived,ColsAtCompileTime>& r);
|
||||
template<typename OtherDerived>
|
||||
Matrix& operator=(const eigen2_RotationBase<OtherDerived,ColsAtCompileTime>& r);
|
||||
#endif
|
||||
|
||||
// allow to extend Matrix outside Eigen
|
||||
#ifdef EIGEN_MATRIX_PLUGIN
|
||||
#include EIGEN_MATRIX_PLUGIN
|
||||
|
||||
@@ -52,7 +52,7 @@ template<typename Derived> class MatrixBase
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
typedef MatrixBase StorageBaseType;
|
||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||
typedef typename internal::traits<Derived>::Index Index;
|
||||
typedef typename internal::traits<Derived>::StorageIndex StorageIndex;
|
||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
@@ -66,8 +66,7 @@ template<typename Derived> class MatrixBase
|
||||
using Base::MaxSizeAtCompileTime;
|
||||
using Base::IsVectorAtCompileTime;
|
||||
using Base::Flags;
|
||||
using Base::CoeffReadCost;
|
||||
|
||||
|
||||
using Base::derived;
|
||||
using Base::const_cast_derived;
|
||||
using Base::rows;
|
||||
@@ -81,6 +80,8 @@ template<typename Derived> class MatrixBase
|
||||
using Base::operator-=;
|
||||
using Base::operator*=;
|
||||
using Base::operator/=;
|
||||
using Base::operator*;
|
||||
using Base::operator/;
|
||||
|
||||
typedef typename Base::CoeffReturnType CoeffReturnType;
|
||||
typedef typename Base::ConstTransposeReturnType ConstTransposeReturnType;
|
||||
@@ -98,25 +99,14 @@ template<typename Derived> class MatrixBase
|
||||
|
||||
/** \returns the size of the main diagonal, which is min(rows(),cols()).
|
||||
* \sa rows(), cols(), SizeAtCompileTime. */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index diagonalSize() const { return (std::min)(rows(),cols()); }
|
||||
|
||||
/** \brief The plain matrix type corresponding to this expression.
|
||||
*
|
||||
* This is not necessarily exactly the return type of eval(). In the case of plain matrices,
|
||||
* the return type of eval() is a const reference to a matrix, not a matrix! It is however guaranteed
|
||||
* that the return type of eval() is either PlainObject or const PlainObject&.
|
||||
*/
|
||||
typedef Matrix<typename internal::traits<Derived>::Scalar,
|
||||
internal::traits<Derived>::RowsAtCompileTime,
|
||||
internal::traits<Derived>::ColsAtCompileTime,
|
||||
AutoAlign | (internal::traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor),
|
||||
internal::traits<Derived>::MaxRowsAtCompileTime,
|
||||
internal::traits<Derived>::MaxColsAtCompileTime
|
||||
> PlainObject;
|
||||
typedef typename Base::PlainObject PlainObject;
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
/** \internal Represents a matrix with all coefficients equal to one another*/
|
||||
typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Derived> ConstantReturnType;
|
||||
typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,PlainObject> ConstantReturnType;
|
||||
/** \internal the return type of MatrixBase::adjoint() */
|
||||
typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
|
||||
CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, ConstTransposeReturnType>,
|
||||
@@ -125,7 +115,7 @@ template<typename Derived> class MatrixBase
|
||||
/** \internal Return type of eigenvalues() */
|
||||
typedef Matrix<std::complex<RealScalar>, internal::traits<Derived>::ColsAtCompileTime, 1, ColMajor> EigenvaluesReturnType;
|
||||
/** \internal the return type of identity */
|
||||
typedef CwiseNullaryOp<internal::scalar_identity_op<Scalar>,Derived> IdentityReturnType;
|
||||
typedef CwiseNullaryOp<internal::scalar_identity_op<Scalar>,PlainObject> IdentityReturnType;
|
||||
/** \internal the return type of unit vectors */
|
||||
typedef Block<const CwiseNullaryOp<internal::scalar_identity_op<Scalar>, SquareMatrixType>,
|
||||
internal::traits<Derived>::RowsAtCompileTime,
|
||||
@@ -145,39 +135,48 @@ template<typename Derived> class MatrixBase
|
||||
/** Special case of the template operator=, in order to prevent the compiler
|
||||
* from generating a default operator= (issue hit with g++ 4.1)
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator=(const MatrixBase& other);
|
||||
|
||||
// We cannot inherit here via Base::operator= since it is causing
|
||||
// trouble with MSVC.
|
||||
|
||||
template <typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator=(const DenseBase<OtherDerived>& other);
|
||||
|
||||
template <typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator=(const EigenBase<OtherDerived>& other);
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator=(const ReturnByValue<OtherDerived>& other);
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
template<typename ProductDerived, typename Lhs, typename Rhs>
|
||||
Derived& lazyAssign(const ProductBase<ProductDerived, Lhs,Rhs>& other);
|
||||
|
||||
template<typename MatrixPower, typename Lhs, typename Rhs>
|
||||
Derived& lazyAssign(const MatrixPowerProduct<MatrixPower, Lhs,Rhs>& other);
|
||||
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator+=(const MatrixBase<OtherDerived>& other);
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator-=(const MatrixBase<OtherDerived>& other);
|
||||
|
||||
#ifdef __CUDACC__
|
||||
template<typename OtherDerived>
|
||||
const typename ProductReturnType<Derived,OtherDerived>::Type
|
||||
operator*(const MatrixBase<OtherDerived> &other) const;
|
||||
EIGEN_DEVICE_FUNC
|
||||
const Product<Derived,OtherDerived,LazyProduct>
|
||||
operator*(const MatrixBase<OtherDerived> &other) const
|
||||
{ return this->lazyProduct(other); }
|
||||
#else
|
||||
|
||||
template<typename OtherDerived>
|
||||
const typename LazyProductReturnType<Derived,OtherDerived>::Type
|
||||
const Product<Derived,OtherDerived>
|
||||
operator*(const MatrixBase<OtherDerived> &other) const;
|
||||
|
||||
#endif
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
const Product<Derived,OtherDerived,LazyProduct>
|
||||
lazyProduct(const MatrixBase<OtherDerived> &other) const;
|
||||
|
||||
template<typename OtherDerived>
|
||||
@@ -190,88 +189,91 @@ template<typename Derived> class MatrixBase
|
||||
void applyOnTheRight(const EigenBase<OtherDerived>& other);
|
||||
|
||||
template<typename DiagonalDerived>
|
||||
const DiagonalProduct<Derived, DiagonalDerived, OnTheRight>
|
||||
EIGEN_DEVICE_FUNC
|
||||
const Product<Derived, DiagonalDerived, LazyProduct>
|
||||
operator*(const DiagonalBase<DiagonalDerived> &diagonal) const;
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename internal::scalar_product_traits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType
|
||||
dot(const MatrixBase<OtherDerived>& other) const;
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
template<typename OtherDerived>
|
||||
Scalar eigen2_dot(const MatrixBase<OtherDerived>& other) const;
|
||||
#endif
|
||||
|
||||
RealScalar squaredNorm() const;
|
||||
RealScalar norm() const;
|
||||
EIGEN_DEVICE_FUNC RealScalar squaredNorm() const;
|
||||
EIGEN_DEVICE_FUNC RealScalar norm() const;
|
||||
RealScalar stableNorm() const;
|
||||
RealScalar blueNorm() const;
|
||||
RealScalar hypotNorm() const;
|
||||
const PlainObject normalized() const;
|
||||
void normalize();
|
||||
EIGEN_DEVICE_FUNC const PlainObject normalized() const;
|
||||
EIGEN_DEVICE_FUNC void normalize();
|
||||
|
||||
const AdjointReturnType adjoint() const;
|
||||
void adjointInPlace();
|
||||
EIGEN_DEVICE_FUNC const AdjointReturnType adjoint() const;
|
||||
EIGEN_DEVICE_FUNC void adjointInPlace();
|
||||
|
||||
typedef Diagonal<Derived> DiagonalReturnType;
|
||||
EIGEN_DEVICE_FUNC
|
||||
DiagonalReturnType diagonal();
|
||||
typedef typename internal::add_const<Diagonal<const Derived> >::type ConstDiagonalReturnType;
|
||||
|
||||
typedef typename internal::add_const<Diagonal<const Derived> >::type ConstDiagonalReturnType;
|
||||
EIGEN_DEVICE_FUNC
|
||||
ConstDiagonalReturnType diagonal() const;
|
||||
|
||||
template<int Index> struct DiagonalIndexReturnType { typedef Diagonal<Derived,Index> Type; };
|
||||
template<int Index> struct ConstDiagonalIndexReturnType { typedef const Diagonal<const Derived,Index> Type; };
|
||||
|
||||
template<int Index> typename DiagonalIndexReturnType<Index>::Type diagonal();
|
||||
template<int Index> typename ConstDiagonalIndexReturnType<Index>::Type diagonal() const;
|
||||
template<int Index>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename DiagonalIndexReturnType<Index>::Type diagonal();
|
||||
|
||||
// Note: The "MatrixBase::" prefixes are added to help MSVC9 to match these declarations with the later implementations.
|
||||
// On the other hand they confuse MSVC8...
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1500) // 2008 or later
|
||||
typename MatrixBase::template DiagonalIndexReturnType<DynamicIndex>::Type diagonal(Index index);
|
||||
typename MatrixBase::template ConstDiagonalIndexReturnType<DynamicIndex>::Type diagonal(Index index) const;
|
||||
#else
|
||||
typename DiagonalIndexReturnType<DynamicIndex>::Type diagonal(Index index);
|
||||
typename ConstDiagonalIndexReturnType<DynamicIndex>::Type diagonal(Index index) const;
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
template<unsigned int Mode> typename internal::eigen2_part_return_type<Derived, Mode>::type part();
|
||||
template<unsigned int Mode> const typename internal::eigen2_part_return_type<Derived, Mode>::type part() const;
|
||||
template<int Index>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename ConstDiagonalIndexReturnType<Index>::Type diagonal() const;
|
||||
|
||||
// huuuge hack. make Eigen2's matrix.part<Diagonal>() work in eigen3. Problem: Diagonal is now a class template instead
|
||||
// of an integer constant. Solution: overload the part() method template wrt template parameters list.
|
||||
template<template<typename T, int N> class U>
|
||||
const DiagonalWrapper<ConstDiagonalReturnType> part() const
|
||||
{ return diagonal().asDiagonal(); }
|
||||
#endif // EIGEN2_SUPPORT
|
||||
typedef Diagonal<Derived,DynamicIndex> DiagonalDynamicIndexReturnType;
|
||||
typedef typename internal::add_const<Diagonal<const Derived,DynamicIndex> >::type ConstDiagonalDynamicIndexReturnType;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
DiagonalDynamicIndexReturnType diagonal(Index index);
|
||||
EIGEN_DEVICE_FUNC
|
||||
ConstDiagonalDynamicIndexReturnType diagonal(Index index) const;
|
||||
|
||||
template<unsigned int Mode> struct TriangularViewReturnType { typedef TriangularView<Derived, Mode> Type; };
|
||||
template<unsigned int Mode> struct ConstTriangularViewReturnType { typedef const TriangularView<const Derived, Mode> Type; };
|
||||
|
||||
template<unsigned int Mode> typename TriangularViewReturnType<Mode>::Type triangularView();
|
||||
template<unsigned int Mode> typename ConstTriangularViewReturnType<Mode>::Type triangularView() const;
|
||||
template<unsigned int Mode>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename TriangularViewReturnType<Mode>::Type triangularView();
|
||||
template<unsigned int Mode>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename ConstTriangularViewReturnType<Mode>::Type triangularView() const;
|
||||
|
||||
template<unsigned int UpLo> struct SelfAdjointViewReturnType { typedef SelfAdjointView<Derived, UpLo> Type; };
|
||||
template<unsigned int UpLo> struct ConstSelfAdjointViewReturnType { typedef const SelfAdjointView<const Derived, UpLo> Type; };
|
||||
|
||||
template<unsigned int UpLo> typename SelfAdjointViewReturnType<UpLo>::Type selfadjointView();
|
||||
template<unsigned int UpLo> typename ConstSelfAdjointViewReturnType<UpLo>::Type selfadjointView() const;
|
||||
template<unsigned int UpLo>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename SelfAdjointViewReturnType<UpLo>::Type selfadjointView();
|
||||
template<unsigned int UpLo>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename ConstSelfAdjointViewReturnType<UpLo>::Type selfadjointView() const;
|
||||
|
||||
const SparseView<Derived> sparseView(const Scalar& m_reference = Scalar(0),
|
||||
const typename NumTraits<Scalar>::Real& m_epsilon = NumTraits<Scalar>::dummy_precision()) const;
|
||||
static const IdentityReturnType Identity();
|
||||
static const IdentityReturnType Identity(Index rows, Index cols);
|
||||
static const BasisReturnType Unit(Index size, Index i);
|
||||
static const BasisReturnType Unit(Index i);
|
||||
static const BasisReturnType UnitX();
|
||||
static const BasisReturnType UnitY();
|
||||
static const BasisReturnType UnitZ();
|
||||
static const BasisReturnType UnitW();
|
||||
EIGEN_DEVICE_FUNC static const IdentityReturnType Identity();
|
||||
EIGEN_DEVICE_FUNC static const IdentityReturnType Identity(Index rows, Index cols);
|
||||
EIGEN_DEVICE_FUNC static const BasisReturnType Unit(Index size, Index i);
|
||||
EIGEN_DEVICE_FUNC static const BasisReturnType Unit(Index i);
|
||||
EIGEN_DEVICE_FUNC static const BasisReturnType UnitX();
|
||||
EIGEN_DEVICE_FUNC static const BasisReturnType UnitY();
|
||||
EIGEN_DEVICE_FUNC static const BasisReturnType UnitZ();
|
||||
EIGEN_DEVICE_FUNC static const BasisReturnType UnitW();
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
const DiagonalWrapper<const Derived> asDiagonal() const;
|
||||
const PermutationWrapper<const Derived> asPermutation() const;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& setIdentity();
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& setIdentity(Index rows, Index cols);
|
||||
|
||||
bool isIdentity(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
|
||||
@@ -303,50 +305,37 @@ template<typename Derived> class MatrixBase
|
||||
|
||||
NoAlias<Derived,Eigen::MatrixBase > noalias();
|
||||
|
||||
inline const ForceAlignedAccess<Derived> forceAlignedAccess() const;
|
||||
inline ForceAlignedAccess<Derived> forceAlignedAccess();
|
||||
template<bool Enable> inline typename internal::add_const_on_value_type<typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type>::type forceAlignedAccessIf() const;
|
||||
template<bool Enable> inline typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf();
|
||||
// TODO forceAlignedAccess is temporarily disabled
|
||||
// Need to find a nicer workaround.
|
||||
inline const Derived& forceAlignedAccess() const { return derived(); }
|
||||
inline Derived& forceAlignedAccess() { return derived(); }
|
||||
template<bool Enable> inline const Derived& forceAlignedAccessIf() const { return derived(); }
|
||||
template<bool Enable> inline Derived& forceAlignedAccessIf() { return derived(); }
|
||||
|
||||
Scalar trace() const;
|
||||
EIGEN_DEVICE_FUNC Scalar trace() const;
|
||||
|
||||
/////////// Array module ///////////
|
||||
template<int p> EIGEN_DEVICE_FUNC RealScalar lpNorm() const;
|
||||
|
||||
template<int p> RealScalar lpNorm() const;
|
||||
|
||||
MatrixBase<Derived>& matrix() { return *this; }
|
||||
const MatrixBase<Derived>& matrix() const { return *this; }
|
||||
EIGEN_DEVICE_FUNC MatrixBase<Derived>& matrix() { return *this; }
|
||||
EIGEN_DEVICE_FUNC const MatrixBase<Derived>& matrix() const { return *this; }
|
||||
|
||||
/** \returns an \link Eigen::ArrayBase Array \endlink expression of this matrix
|
||||
* \sa ArrayBase::matrix() */
|
||||
ArrayWrapper<Derived> array() { return derived(); }
|
||||
const ArrayWrapper<const Derived> array() const { return derived(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ArrayWrapper<Derived> array() { return ArrayWrapper<Derived>(derived()); }
|
||||
/** \returns a const \link Eigen::ArrayBase Array \endlink expression of this matrix
|
||||
* \sa ArrayBase::matrix() */
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const ArrayWrapper<const Derived> array() const { return ArrayWrapper<const Derived>(derived()); }
|
||||
|
||||
/////////// LU module ///////////
|
||||
|
||||
const FullPivLU<PlainObject> fullPivLu() const;
|
||||
const PartialPivLU<PlainObject> partialPivLu() const;
|
||||
EIGEN_DEVICE_FUNC const FullPivLU<PlainObject> fullPivLu() const;
|
||||
EIGEN_DEVICE_FUNC const PartialPivLU<PlainObject> partialPivLu() const;
|
||||
|
||||
#if EIGEN2_SUPPORT_STAGE < STAGE20_RESOLVE_API_CONFLICTS
|
||||
const LU<PlainObject> lu() const;
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
const LU<PlainObject> eigen2_lu() const;
|
||||
#endif
|
||||
|
||||
#if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS
|
||||
const PartialPivLU<PlainObject> lu() const;
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
template<typename ResultType>
|
||||
void computeInverse(MatrixBase<ResultType> *result) const {
|
||||
*result = this->inverse();
|
||||
}
|
||||
#endif
|
||||
|
||||
const internal::inverse_impl<Derived> inverse() const;
|
||||
EIGEN_DEVICE_FUNC
|
||||
const Inverse<Derived> inverse() const;
|
||||
|
||||
template<typename ResultType>
|
||||
void computeInverseAndDetWithCheck(
|
||||
ResultType& inverse,
|
||||
@@ -372,10 +361,6 @@ template<typename Derived> class MatrixBase
|
||||
const HouseholderQR<PlainObject> householderQr() const;
|
||||
const ColPivHouseholderQR<PlainObject> colPivHouseholderQr() const;
|
||||
const FullPivHouseholderQR<PlainObject> fullPivHouseholderQr() const;
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
const QR<PlainObject> qr() const;
|
||||
#endif
|
||||
|
||||
EigenvaluesReturnType eigenvalues() const;
|
||||
RealScalar operatorNorm() const;
|
||||
@@ -383,10 +368,7 @@ template<typename Derived> class MatrixBase
|
||||
/////////// SVD module ///////////
|
||||
|
||||
JacobiSVD<PlainObject> jacobiSvd(unsigned int computationOptions = 0) const;
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
SVD<PlainObject> svd() const;
|
||||
#endif
|
||||
BDCSVD<PlainObject> bdcSvd(unsigned int computationOptions = 0) const;
|
||||
|
||||
/////////// Geometry module ///////////
|
||||
|
||||
@@ -398,20 +380,25 @@ template<typename Derived> class MatrixBase
|
||||
};
|
||||
#endif // EIGEN_PARSED_BY_DOXYGEN
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename cross_product_return_type<OtherDerived>::type
|
||||
cross(const MatrixBase<OtherDerived>& other) const;
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
PlainObject cross3(const MatrixBase<OtherDerived>& other) const;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
PlainObject unitOrthogonal(void) const;
|
||||
|
||||
Matrix<Scalar,3,1> eulerAngles(Index a0, Index a1, Index a2) const;
|
||||
|
||||
#if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS
|
||||
ScalarMultipleReturnType operator*(const UniformScaling<Scalar>& s) const;
|
||||
// put this as separate enum value to work around possible GCC 4.3 bug (?)
|
||||
enum { HomogeneousReturnTypeDirection = ColsAtCompileTime==1?Vertical:Horizontal };
|
||||
enum { HomogeneousReturnTypeDirection = ColsAtCompileTime==1&&RowsAtCompileTime==1 ? ((internal::traits<Derived>::Flags&RowMajorBit)==RowMajorBit ? Horizontal : Vertical)
|
||||
: ColsAtCompileTime==1 ? Vertical : Horizontal };
|
||||
typedef Homogeneous<Derived, HomogeneousReturnTypeDirection> HomogeneousReturnType;
|
||||
HomogeneousReturnType homogeneous() const;
|
||||
#endif
|
||||
|
||||
enum {
|
||||
SizeMinusOne = SizeAtCompileTime==Dynamic ? Dynamic : SizeAtCompileTime-1
|
||||
@@ -458,49 +445,15 @@ template<typename Derived> class MatrixBase
|
||||
const MatrixSquareRootReturnValue<Derived> sqrt() const;
|
||||
const MatrixLogarithmReturnValue<Derived> log() const;
|
||||
const MatrixPowerReturnValue<Derived> pow(const RealScalar& p) const;
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
template<typename ProductDerived, typename Lhs, typename Rhs>
|
||||
Derived& operator+=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0,
|
||||
EvalBeforeAssigningBit>& other);
|
||||
|
||||
template<typename ProductDerived, typename Lhs, typename Rhs>
|
||||
Derived& operator-=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0,
|
||||
EvalBeforeAssigningBit>& other);
|
||||
|
||||
/** \deprecated because .lazy() is deprecated
|
||||
* Overloaded for cache friendly product evaluation */
|
||||
template<typename OtherDerived>
|
||||
Derived& lazyAssign(const Flagged<OtherDerived, 0, EvalBeforeAssigningBit>& other)
|
||||
{ return lazyAssign(other._expression()); }
|
||||
|
||||
template<unsigned int Added>
|
||||
const Flagged<Derived, Added, 0> marked() const;
|
||||
const Flagged<Derived, 0, EvalBeforeAssigningBit> lazy() const;
|
||||
|
||||
inline const Cwise<Derived> cwise() const;
|
||||
inline Cwise<Derived> cwise();
|
||||
|
||||
VectorBlock<Derived> start(Index size);
|
||||
const VectorBlock<const Derived> start(Index size) const;
|
||||
VectorBlock<Derived> end(Index size);
|
||||
const VectorBlock<const Derived> end(Index size) const;
|
||||
template<int Size> VectorBlock<Derived,Size> start();
|
||||
template<int Size> const VectorBlock<const Derived,Size> start() const;
|
||||
template<int Size> VectorBlock<Derived,Size> end();
|
||||
template<int Size> const VectorBlock<const Derived,Size> end() const;
|
||||
|
||||
Minor<Derived> minor(Index row, Index col);
|
||||
const Minor<Derived> minor(Index row, Index col) const;
|
||||
#endif
|
||||
const MatrixComplexPowerReturnValue<Derived> pow(const std::complex<RealScalar>& p) const;
|
||||
|
||||
protected:
|
||||
MatrixBase() : Base() {}
|
||||
EIGEN_DEVICE_FUNC MatrixBase() : Base() {}
|
||||
|
||||
private:
|
||||
explicit MatrixBase(int);
|
||||
MatrixBase(int,int);
|
||||
template<typename OtherDerived> explicit MatrixBase(const MatrixBase<OtherDerived>&);
|
||||
EIGEN_DEVICE_FUNC explicit MatrixBase(int);
|
||||
EIGEN_DEVICE_FUNC MatrixBase(int,int);
|
||||
template<typename OtherDerived> EIGEN_DEVICE_FUNC explicit MatrixBase(const MatrixBase<OtherDerived>&);
|
||||
protected:
|
||||
// mixing arrays and matrices is not legal
|
||||
template<typename OtherDerived> Derived& operator+=(const ArrayBase<OtherDerived>& )
|
||||
@@ -510,6 +463,51 @@ template<typename Derived> class MatrixBase
|
||||
{EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;}
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Implementation of matrix base methods
|
||||
***************************************************************************/
|
||||
|
||||
/** replaces \c *this by \c *this * \a other.
|
||||
*
|
||||
* \returns a reference to \c *this
|
||||
*
|
||||
* Example: \include MatrixBase_applyOnTheRight.cpp
|
||||
* Output: \verbinclude MatrixBase_applyOnTheRight.out
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
inline Derived&
|
||||
MatrixBase<Derived>::operator*=(const EigenBase<OtherDerived> &other)
|
||||
{
|
||||
other.derived().applyThisOnTheRight(derived());
|
||||
return derived();
|
||||
}
|
||||
|
||||
/** replaces \c *this by \c *this * \a other. It is equivalent to MatrixBase::operator*=().
|
||||
*
|
||||
* Example: \include MatrixBase_applyOnTheRight.cpp
|
||||
* Output: \verbinclude MatrixBase_applyOnTheRight.out
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
inline void MatrixBase<Derived>::applyOnTheRight(const EigenBase<OtherDerived> &other)
|
||||
{
|
||||
other.derived().applyThisOnTheRight(derived());
|
||||
}
|
||||
|
||||
/** replaces \c *this by \a other * \c *this.
|
||||
*
|
||||
* Example: \include MatrixBase_applyOnTheLeft.cpp
|
||||
* Output: \verbinclude MatrixBase_applyOnTheLeft.out
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
inline void MatrixBase<Derived>::applyOnTheLeft(const EigenBase<OtherDerived> &other)
|
||||
{
|
||||
other.derived().applyThisOnTheLeft(derived());
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_MATRIXBASE_H
|
||||
|
||||
@@ -40,29 +40,29 @@ template<typename ExpressionType> class NestByValue
|
||||
typedef typename internal::dense_xpr_base<NestByValue>::type Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(NestByValue)
|
||||
|
||||
inline NestByValue(const ExpressionType& matrix) : m_expression(matrix) {}
|
||||
EIGEN_DEVICE_FUNC explicit inline NestByValue(const ExpressionType& matrix) : m_expression(matrix) {}
|
||||
|
||||
inline Index rows() const { return m_expression.rows(); }
|
||||
inline Index cols() const { return m_expression.cols(); }
|
||||
inline Index outerStride() const { return m_expression.outerStride(); }
|
||||
inline Index innerStride() const { return m_expression.innerStride(); }
|
||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_expression.rows(); }
|
||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_expression.cols(); }
|
||||
EIGEN_DEVICE_FUNC inline Index outerStride() const { return m_expression.outerStride(); }
|
||||
EIGEN_DEVICE_FUNC inline Index innerStride() const { return m_expression.innerStride(); }
|
||||
|
||||
inline const CoeffReturnType coeff(Index row, Index col) const
|
||||
EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index row, Index col) const
|
||||
{
|
||||
return m_expression.coeff(row, col);
|
||||
}
|
||||
|
||||
inline Scalar& coeffRef(Index row, Index col)
|
||||
EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index row, Index col)
|
||||
{
|
||||
return m_expression.const_cast_derived().coeffRef(row, col);
|
||||
}
|
||||
|
||||
inline const CoeffReturnType coeff(Index index) const
|
||||
EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index index) const
|
||||
{
|
||||
return m_expression.coeff(index);
|
||||
}
|
||||
|
||||
inline Scalar& coeffRef(Index index)
|
||||
EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index index)
|
||||
{
|
||||
return m_expression.const_cast_derived().coeffRef(index);
|
||||
}
|
||||
@@ -91,7 +91,7 @@ template<typename ExpressionType> class NestByValue
|
||||
m_expression.const_cast_derived().template writePacket<LoadMode>(index, x);
|
||||
}
|
||||
|
||||
operator const ExpressionType&() const { return m_expression; }
|
||||
EIGEN_DEVICE_FUNC operator const ExpressionType&() const { return m_expression; }
|
||||
|
||||
protected:
|
||||
const ExpressionType m_expression;
|
||||
|
||||
@@ -30,62 +30,36 @@ namespace Eigen {
|
||||
template<typename ExpressionType, template <typename> class StorageBase>
|
||||
class NoAlias
|
||||
{
|
||||
typedef typename ExpressionType::Scalar Scalar;
|
||||
public:
|
||||
NoAlias(ExpressionType& expression) : m_expression(expression) {}
|
||||
|
||||
/** Behaves like MatrixBase::lazyAssign(other)
|
||||
* \sa MatrixBase::lazyAssign() */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other)
|
||||
{ return internal::assign_selector<ExpressionType,OtherDerived,false>::run(m_expression,other.derived()); }
|
||||
|
||||
/** \sa MatrixBase::operator+= */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase<OtherDerived>& other)
|
||||
{
|
||||
typedef SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, ExpressionType, OtherDerived> SelfAdder;
|
||||
SelfAdder tmp(m_expression);
|
||||
typedef typename internal::nested<OtherDerived>::type OtherDerivedNested;
|
||||
typedef typename internal::remove_all<OtherDerivedNested>::type _OtherDerivedNested;
|
||||
internal::assign_selector<SelfAdder,_OtherDerivedNested,false>::run(tmp,OtherDerivedNested(other.derived()));
|
||||
return m_expression;
|
||||
}
|
||||
|
||||
/** \sa MatrixBase::operator-= */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE ExpressionType& operator-=(const StorageBase<OtherDerived>& other)
|
||||
{
|
||||
typedef SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, ExpressionType, OtherDerived> SelfAdder;
|
||||
SelfAdder tmp(m_expression);
|
||||
typedef typename internal::nested<OtherDerived>::type OtherDerivedNested;
|
||||
typedef typename internal::remove_all<OtherDerivedNested>::type _OtherDerivedNested;
|
||||
internal::assign_selector<SelfAdder,_OtherDerivedNested,false>::run(tmp,OtherDerivedNested(other.derived()));
|
||||
return m_expression;
|
||||
}
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
template<typename ProductDerived, typename Lhs, typename Rhs>
|
||||
EIGEN_STRONG_INLINE ExpressionType& operator+=(const ProductBase<ProductDerived, Lhs,Rhs>& other)
|
||||
{ other.derived().addTo(m_expression); return m_expression; }
|
||||
|
||||
template<typename ProductDerived, typename Lhs, typename Rhs>
|
||||
EIGEN_STRONG_INLINE ExpressionType& operator-=(const ProductBase<ProductDerived, Lhs,Rhs>& other)
|
||||
{ other.derived().subTo(m_expression); return m_expression; }
|
||||
|
||||
template<typename Lhs, typename Rhs, int NestingFlags>
|
||||
EIGEN_STRONG_INLINE ExpressionType& operator+=(const CoeffBasedProduct<Lhs,Rhs,NestingFlags>& other)
|
||||
{ return m_expression.derived() += CoeffBasedProduct<Lhs,Rhs,NestByRefBit>(other.lhs(), other.rhs()); }
|
||||
|
||||
template<typename Lhs, typename Rhs, int NestingFlags>
|
||||
EIGEN_STRONG_INLINE ExpressionType& operator-=(const CoeffBasedProduct<Lhs,Rhs,NestingFlags>& other)
|
||||
{ return m_expression.derived() -= CoeffBasedProduct<Lhs,Rhs,NestByRefBit>(other.lhs(), other.rhs()); }
|
||||
typedef typename ExpressionType::Scalar Scalar;
|
||||
|
||||
explicit NoAlias(ExpressionType& expression) : m_expression(expression) {}
|
||||
|
||||
template<typename OtherDerived>
|
||||
ExpressionType& operator=(const ReturnByValue<OtherDerived>& func)
|
||||
{ return m_expression = func; }
|
||||
#endif
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other)
|
||||
{
|
||||
call_assignment_no_alias(m_expression, other.derived(), internal::assign_op<Scalar>());
|
||||
return m_expression;
|
||||
}
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase<OtherDerived>& other)
|
||||
{
|
||||
call_assignment_no_alias(m_expression, other.derived(), internal::add_assign_op<Scalar>());
|
||||
return m_expression;
|
||||
}
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE ExpressionType& operator-=(const StorageBase<OtherDerived>& other)
|
||||
{
|
||||
call_assignment_no_alias(m_expression, other.derived(), internal::sub_assign_op<Scalar>());
|
||||
return m_expression;
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
ExpressionType& expression() const
|
||||
{
|
||||
return m_expression;
|
||||
@@ -126,7 +100,7 @@ class NoAlias
|
||||
template<typename Derived>
|
||||
NoAlias<Derived,MatrixBase> MatrixBase<Derived>::noalias()
|
||||
{
|
||||
return derived();
|
||||
return NoAlias<Derived, Eigen::MatrixBase >(derived());
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -68,21 +68,40 @@ template<typename T> struct GenericNumTraits
|
||||
>::type NonInteger;
|
||||
typedef T Nested;
|
||||
|
||||
static inline Real epsilon() { return std::numeric_limits<T>::epsilon(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline Real epsilon()
|
||||
{
|
||||
#if defined(__CUDA_ARCH__)
|
||||
return internal::device::numeric_limits<T>::epsilon();
|
||||
#else
|
||||
return std::numeric_limits<T>::epsilon();
|
||||
#endif
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline Real dummy_precision()
|
||||
{
|
||||
// make sure to override this for floating-point types
|
||||
return Real(0);
|
||||
}
|
||||
static inline T highest() { return (std::numeric_limits<T>::max)(); }
|
||||
static inline T lowest() { return IsInteger ? (std::numeric_limits<T>::min)() : (-(std::numeric_limits<T>::max)()); }
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
enum {
|
||||
HasFloatingPoint = !IsInteger
|
||||
};
|
||||
typedef NonInteger FloatingPoint;
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline T highest() {
|
||||
#if defined(__CUDA_ARCH__)
|
||||
return (internal::device::numeric_limits<T>::max)();
|
||||
#else
|
||||
return (std::numeric_limits<T>::max)();
|
||||
#endif
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline T lowest() {
|
||||
#if defined(__CUDA_ARCH__)
|
||||
return IsInteger ? (internal::device::numeric_limits<T>::min)() : (-(internal::device::numeric_limits<T>::max)());
|
||||
#else
|
||||
return IsInteger ? (std::numeric_limits<T>::min)() : (-(std::numeric_limits<T>::max)());
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct NumTraits : GenericNumTraits<T>
|
||||
@@ -91,11 +110,13 @@ template<typename T> struct NumTraits : GenericNumTraits<T>
|
||||
template<> struct NumTraits<float>
|
||||
: GenericNumTraits<float>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline float dummy_precision() { return 1e-5f; }
|
||||
};
|
||||
|
||||
template<> struct NumTraits<double> : GenericNumTraits<double>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline double dummy_precision() { return 1e-12; }
|
||||
};
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
template<int RowCol,typename IndicesType,typename MatrixType, typename StorageKind> class PermutedImpl;
|
||||
// TODO: this does not seems to be needed at all:
|
||||
// template<int RowCol,typename IndicesType,typename MatrixType, typename StorageKind> class PermutedImpl;
|
||||
|
||||
/** \class PermutationBase
|
||||
* \ingroup Core_Module
|
||||
@@ -41,10 +42,6 @@ template<int RowCol,typename IndicesType,typename MatrixType, typename StorageKi
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename PermutationType, typename MatrixType, int Side, bool Transposed=false>
|
||||
struct permut_matrix_product_retval;
|
||||
template<typename PermutationType, typename MatrixType, int Side, bool Transposed=false>
|
||||
struct permut_sparsematrix_product_retval;
|
||||
enum PermPermProduct_t {PermPermProduct};
|
||||
|
||||
} // end namespace internal
|
||||
@@ -60,19 +57,18 @@ class PermutationBase : public EigenBase<Derived>
|
||||
typedef typename Traits::IndicesType IndicesType;
|
||||
enum {
|
||||
Flags = Traits::Flags,
|
||||
CoeffReadCost = Traits::CoeffReadCost,
|
||||
RowsAtCompileTime = Traits::RowsAtCompileTime,
|
||||
ColsAtCompileTime = Traits::ColsAtCompileTime,
|
||||
MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = Traits::MaxColsAtCompileTime
|
||||
};
|
||||
typedef typename Traits::Scalar Scalar;
|
||||
typedef typename Traits::Index Index;
|
||||
typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime,0,MaxRowsAtCompileTime,MaxColsAtCompileTime>
|
||||
typedef typename Traits::StorageIndex StorageIndex;
|
||||
typedef Matrix<StorageIndex,RowsAtCompileTime,ColsAtCompileTime,0,MaxRowsAtCompileTime,MaxColsAtCompileTime>
|
||||
DenseMatrixType;
|
||||
typedef PermutationMatrix<IndicesType::SizeAtCompileTime,IndicesType::MaxSizeAtCompileTime,Index>
|
||||
typedef PermutationMatrix<IndicesType::SizeAtCompileTime,IndicesType::MaxSizeAtCompileTime,StorageIndex>
|
||||
PlainPermutationType;
|
||||
using Base::derived;
|
||||
typedef Transpose<PermutationBase> TransposeReturnType;
|
||||
#endif
|
||||
|
||||
/** Copies the other permutation into *this */
|
||||
@@ -118,7 +114,7 @@ class PermutationBase : public EigenBase<Derived>
|
||||
void evalTo(MatrixBase<DenseDerived>& other) const
|
||||
{
|
||||
other.setZero();
|
||||
for (int i=0; i<rows();++i)
|
||||
for (Index i=0; i<rows(); ++i)
|
||||
other.coeffRef(indices().coeff(i),i) = typename DenseDerived::Scalar(1);
|
||||
}
|
||||
#endif
|
||||
@@ -147,7 +143,8 @@ class PermutationBase : public EigenBase<Derived>
|
||||
/** Sets *this to be the identity permutation matrix */
|
||||
void setIdentity()
|
||||
{
|
||||
for(Index i = 0; i < size(); ++i)
|
||||
StorageIndex n = StorageIndex(size());
|
||||
for(StorageIndex i = 0; i < n; ++i)
|
||||
indices().coeffRef(i) = i;
|
||||
}
|
||||
|
||||
@@ -163,18 +160,18 @@ class PermutationBase : public EigenBase<Derived>
|
||||
*
|
||||
* \returns a reference to *this.
|
||||
*
|
||||
* \warning This is much slower than applyTranspositionOnTheRight(int,int):
|
||||
* \warning This is much slower than applyTranspositionOnTheRight(Index,Index):
|
||||
* this has linear complexity and requires a lot of branching.
|
||||
*
|
||||
* \sa applyTranspositionOnTheRight(int,int)
|
||||
* \sa applyTranspositionOnTheRight(Index,Index)
|
||||
*/
|
||||
Derived& applyTranspositionOnTheLeft(Index i, Index j)
|
||||
{
|
||||
eigen_assert(i>=0 && j>=0 && i<size() && j<size());
|
||||
for(Index k = 0; k < size(); ++k)
|
||||
{
|
||||
if(indices().coeff(k) == i) indices().coeffRef(k) = j;
|
||||
else if(indices().coeff(k) == j) indices().coeffRef(k) = i;
|
||||
if(indices().coeff(k) == i) indices().coeffRef(k) = StorageIndex(j);
|
||||
else if(indices().coeff(k) == j) indices().coeffRef(k) = StorageIndex(i);
|
||||
}
|
||||
return derived();
|
||||
}
|
||||
@@ -185,7 +182,7 @@ class PermutationBase : public EigenBase<Derived>
|
||||
*
|
||||
* This is a fast operation, it only consists in swapping two indices.
|
||||
*
|
||||
* \sa applyTranspositionOnTheLeft(int,int)
|
||||
* \sa applyTranspositionOnTheLeft(Index,Index)
|
||||
*/
|
||||
Derived& applyTranspositionOnTheRight(Index i, Index j)
|
||||
{
|
||||
@@ -198,14 +195,14 @@ class PermutationBase : public EigenBase<Derived>
|
||||
*
|
||||
* \note \note_try_to_help_rvo
|
||||
*/
|
||||
inline Transpose<PermutationBase> inverse() const
|
||||
{ return derived(); }
|
||||
inline TransposeReturnType inverse() const
|
||||
{ return TransposeReturnType(derived()); }
|
||||
/** \returns the tranpose permutation matrix.
|
||||
*
|
||||
* \note \note_try_to_help_rvo
|
||||
*/
|
||||
inline Transpose<PermutationBase> transpose() const
|
||||
{ return derived(); }
|
||||
inline TransposeReturnType transpose() const
|
||||
{ return TransposeReturnType(derived()); }
|
||||
|
||||
/**** multiplication helpers to hopefully get RVO ****/
|
||||
|
||||
@@ -215,13 +212,13 @@ class PermutationBase : public EigenBase<Derived>
|
||||
template<typename OtherDerived>
|
||||
void assignTranspose(const PermutationBase<OtherDerived>& other)
|
||||
{
|
||||
for (int i=0; i<rows();++i) indices().coeffRef(other.indices().coeff(i)) = i;
|
||||
for (Index i=0; i<rows();++i) indices().coeffRef(other.indices().coeff(i)) = i;
|
||||
}
|
||||
template<typename Lhs,typename Rhs>
|
||||
void assignProduct(const Lhs& lhs, const Rhs& rhs)
|
||||
{
|
||||
eigen_assert(lhs.cols() == rhs.rows());
|
||||
for (int i=0; i<rows();++i) indices().coeffRef(i) = lhs.indices().coeff(rhs.indices().coeff(i));
|
||||
for (Index i=0; i<rows();++i) indices().coeffRef(i) = lhs.indices().coeff(rhs.indices().coeff(i));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -250,6 +247,35 @@ class PermutationBase : public EigenBase<Derived>
|
||||
template<typename Other> friend
|
||||
inline PlainPermutationType operator*(const Transpose<PermutationBase<Other> >& other, const PermutationBase& perm)
|
||||
{ return PlainPermutationType(internal::PermPermProduct, other.eval(), perm); }
|
||||
|
||||
/** \returns the determinant of the permutation matrix, which is either 1 or -1 depending on the parity of the permutation.
|
||||
*
|
||||
* This function is O(\c n) procedure allocating a buffer of \c n booleans.
|
||||
*/
|
||||
Index determinant() const
|
||||
{
|
||||
Index res = 1;
|
||||
Index n = size();
|
||||
Matrix<bool,RowsAtCompileTime,1,0,MaxRowsAtCompileTime> mask(n);
|
||||
mask.fill(false);
|
||||
Index r = 0;
|
||||
while(r < n)
|
||||
{
|
||||
// search for the next seed
|
||||
while(r<n && mask[r]) r++;
|
||||
if(r>=n)
|
||||
break;
|
||||
// we got one, let's follow it until we are back to the seed
|
||||
Index k0 = r++;
|
||||
mask.coeffRef(k0) = true;
|
||||
for(Index k=indices().coeff(k0); k!=k0; k=indices().coeff(k))
|
||||
{
|
||||
mask.coeffRef(k) = true;
|
||||
res = -res;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
@@ -262,7 +288,7 @@ class PermutationBase : public EigenBase<Derived>
|
||||
*
|
||||
* \param SizeAtCompileTime the number of rows/cols, or Dynamic
|
||||
* \param MaxSizeAtCompileTime the maximum number of rows/cols, or Dynamic. This optional parameter defaults to SizeAtCompileTime. Most of the time, you should not have to specify it.
|
||||
* \param IndexType the interger type of the indices
|
||||
* \param StorageIndex the integer type of the indices
|
||||
*
|
||||
* This class represents a permutation matrix, internally stored as a vector of integers.
|
||||
*
|
||||
@@ -270,24 +296,28 @@ class PermutationBase : public EigenBase<Derived>
|
||||
*/
|
||||
|
||||
namespace internal {
|
||||
template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType>
|
||||
struct traits<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType> >
|
||||
: traits<Matrix<IndexType,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> >
|
||||
template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex>
|
||||
struct traits<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, _StorageIndex> >
|
||||
: traits<Matrix<_StorageIndex,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> >
|
||||
{
|
||||
typedef IndexType Index;
|
||||
typedef Matrix<IndexType, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType;
|
||||
typedef PermutationStorage StorageKind;
|
||||
typedef Matrix<_StorageIndex, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType;
|
||||
typedef _StorageIndex StorageIndex;
|
||||
};
|
||||
}
|
||||
|
||||
template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType>
|
||||
class PermutationMatrix : public PermutationBase<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType> >
|
||||
template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex>
|
||||
class PermutationMatrix : public PermutationBase<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, _StorageIndex> >
|
||||
{
|
||||
typedef PermutationBase<PermutationMatrix> Base;
|
||||
typedef internal::traits<PermutationMatrix> Traits;
|
||||
public:
|
||||
|
||||
typedef const PermutationMatrix& Nested;
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
typedef typename Traits::IndicesType IndicesType;
|
||||
typedef typename Traits::StorageIndex StorageIndex;
|
||||
#endif
|
||||
|
||||
inline PermutationMatrix()
|
||||
@@ -295,8 +325,10 @@ class PermutationMatrix : public PermutationBase<PermutationMatrix<SizeAtCompile
|
||||
|
||||
/** Constructs an uninitialized permutation matrix of given size.
|
||||
*/
|
||||
inline PermutationMatrix(int size) : m_indices(size)
|
||||
{}
|
||||
explicit inline PermutationMatrix(Index size) : m_indices(size)
|
||||
{
|
||||
eigen_internal_assert(size <= NumTraits<StorageIndex>::highest());
|
||||
}
|
||||
|
||||
/** Copy constructor. */
|
||||
template<typename OtherDerived>
|
||||
@@ -317,7 +349,7 @@ class PermutationMatrix : public PermutationBase<PermutationMatrix<SizeAtCompile
|
||||
* array's size.
|
||||
*/
|
||||
template<typename Other>
|
||||
explicit inline PermutationMatrix(const MatrixBase<Other>& a_indices) : m_indices(a_indices)
|
||||
explicit inline PermutationMatrix(const MatrixBase<Other>& indices) : m_indices(indices)
|
||||
{}
|
||||
|
||||
/** Convert the Transpositions \a tr to a permutation matrix */
|
||||
@@ -365,9 +397,12 @@ class PermutationMatrix : public PermutationBase<PermutationMatrix<SizeAtCompile
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
template<typename Other>
|
||||
PermutationMatrix(const Transpose<PermutationBase<Other> >& other)
|
||||
: m_indices(other.nestedPermutation().size())
|
||||
: m_indices(other.nestedExpression().size())
|
||||
{
|
||||
for (int i=0; i<m_indices.size();++i) m_indices.coeffRef(other.nestedPermutation().indices().coeff(i)) = i;
|
||||
eigen_internal_assert(m_indices.size() <= NumTraits<StorageIndex>::highest());
|
||||
StorageIndex end = StorageIndex(m_indices.size());
|
||||
for (StorageIndex i=0; i<end;++i)
|
||||
m_indices.coeffRef(other.nestedExpression().indices().coeff(i)) = i;
|
||||
}
|
||||
template<typename Lhs,typename Rhs>
|
||||
PermutationMatrix(internal::PermPermProduct_t, const Lhs& lhs, const Rhs& rhs)
|
||||
@@ -384,18 +419,19 @@ class PermutationMatrix : public PermutationBase<PermutationMatrix<SizeAtCompile
|
||||
|
||||
|
||||
namespace internal {
|
||||
template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int _PacketAccess>
|
||||
struct traits<Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType>,_PacketAccess> >
|
||||
: traits<Matrix<IndexType,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> >
|
||||
template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex, int _PacketAccess>
|
||||
struct traits<Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, _StorageIndex>,_PacketAccess> >
|
||||
: traits<Matrix<_StorageIndex,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> >
|
||||
{
|
||||
typedef IndexType Index;
|
||||
typedef Map<const Matrix<IndexType, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1>, _PacketAccess> IndicesType;
|
||||
typedef PermutationStorage StorageKind;
|
||||
typedef Map<const Matrix<_StorageIndex, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1>, _PacketAccess> IndicesType;
|
||||
typedef _StorageIndex StorageIndex;
|
||||
};
|
||||
}
|
||||
|
||||
template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int _PacketAccess>
|
||||
class Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType>,_PacketAccess>
|
||||
: public PermutationBase<Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType>,_PacketAccess> >
|
||||
template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex, int _PacketAccess>
|
||||
class Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, _StorageIndex>,_PacketAccess>
|
||||
: public PermutationBase<Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, _StorageIndex>,_PacketAccess> >
|
||||
{
|
||||
typedef PermutationBase<Map> Base;
|
||||
typedef internal::traits<Map> Traits;
|
||||
@@ -403,14 +439,14 @@ class Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType>,
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
typedef typename Traits::IndicesType IndicesType;
|
||||
typedef typename IndicesType::Scalar Index;
|
||||
typedef typename IndicesType::Scalar StorageIndex;
|
||||
#endif
|
||||
|
||||
inline Map(const Index* indicesPtr)
|
||||
inline Map(const StorageIndex* indicesPtr)
|
||||
: m_indices(indicesPtr)
|
||||
{}
|
||||
|
||||
inline Map(const Index* indicesPtr, Index size)
|
||||
inline Map(const StorageIndex* indicesPtr, Index size)
|
||||
: m_indices(indicesPtr,size)
|
||||
{}
|
||||
|
||||
@@ -457,8 +493,6 @@ class Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, IndexType>,
|
||||
* \sa class PermutationBase, class PermutationMatrix
|
||||
*/
|
||||
|
||||
struct PermutationStorage {};
|
||||
|
||||
template<typename _IndicesType> class TranspositionsWrapper;
|
||||
namespace internal {
|
||||
template<typename _IndicesType>
|
||||
@@ -466,15 +500,14 @@ struct traits<PermutationWrapper<_IndicesType> >
|
||||
{
|
||||
typedef PermutationStorage StorageKind;
|
||||
typedef typename _IndicesType::Scalar Scalar;
|
||||
typedef typename _IndicesType::Scalar Index;
|
||||
typedef typename _IndicesType::Scalar StorageIndex;
|
||||
typedef _IndicesType IndicesType;
|
||||
enum {
|
||||
RowsAtCompileTime = _IndicesType::SizeAtCompileTime,
|
||||
ColsAtCompileTime = _IndicesType::SizeAtCompileTime,
|
||||
MaxRowsAtCompileTime = IndicesType::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = IndicesType::MaxColsAtCompileTime,
|
||||
Flags = 0,
|
||||
CoeffReadCost = _IndicesType::CoeffReadCost
|
||||
MaxRowsAtCompileTime = IndicesType::MaxSizeAtCompileTime,
|
||||
MaxColsAtCompileTime = IndicesType::MaxSizeAtCompileTime,
|
||||
Flags = 0
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -490,8 +523,8 @@ class PermutationWrapper : public PermutationBase<PermutationWrapper<_IndicesTyp
|
||||
typedef typename Traits::IndicesType IndicesType;
|
||||
#endif
|
||||
|
||||
inline PermutationWrapper(const IndicesType& a_indices)
|
||||
: m_indices(a_indices)
|
||||
inline PermutationWrapper(const IndicesType& indices)
|
||||
: m_indices(indices)
|
||||
{}
|
||||
|
||||
/** const version of indices(). */
|
||||
@@ -503,104 +536,33 @@ class PermutationWrapper : public PermutationBase<PermutationWrapper<_IndicesTyp
|
||||
typename IndicesType::Nested m_indices;
|
||||
};
|
||||
|
||||
|
||||
/** \returns the matrix with the permutation applied to the columns.
|
||||
*/
|
||||
template<typename Derived, typename PermutationDerived>
|
||||
inline const internal::permut_matrix_product_retval<PermutationDerived, Derived, OnTheRight>
|
||||
operator*(const MatrixBase<Derived>& matrix,
|
||||
const PermutationBase<PermutationDerived> &permutation)
|
||||
template<typename MatrixDerived, typename PermutationDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
const Product<MatrixDerived, PermutationDerived, AliasFreeProduct>
|
||||
operator*(const MatrixBase<MatrixDerived> &matrix,
|
||||
const PermutationBase<PermutationDerived>& permutation)
|
||||
{
|
||||
return internal::permut_matrix_product_retval
|
||||
<PermutationDerived, Derived, OnTheRight>
|
||||
(permutation.derived(), matrix.derived());
|
||||
return Product<MatrixDerived, PermutationDerived, AliasFreeProduct>
|
||||
(matrix.derived(), permutation.derived());
|
||||
}
|
||||
|
||||
/** \returns the matrix with the permutation applied to the rows.
|
||||
*/
|
||||
template<typename Derived, typename PermutationDerived>
|
||||
inline const internal::permut_matrix_product_retval
|
||||
<PermutationDerived, Derived, OnTheLeft>
|
||||
template<typename PermutationDerived, typename MatrixDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
const Product<PermutationDerived, MatrixDerived, AliasFreeProduct>
|
||||
operator*(const PermutationBase<PermutationDerived> &permutation,
|
||||
const MatrixBase<Derived>& matrix)
|
||||
const MatrixBase<MatrixDerived>& matrix)
|
||||
{
|
||||
return internal::permut_matrix_product_retval
|
||||
<PermutationDerived, Derived, OnTheLeft>
|
||||
(permutation.derived(), matrix.derived());
|
||||
return Product<PermutationDerived, MatrixDerived, AliasFreeProduct>
|
||||
(permutation.derived(), matrix.derived());
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename PermutationType, typename MatrixType, int Side, bool Transposed>
|
||||
struct traits<permut_matrix_product_retval<PermutationType, MatrixType, Side, Transposed> >
|
||||
{
|
||||
typedef typename MatrixType::PlainObject ReturnType;
|
||||
};
|
||||
|
||||
template<typename PermutationType, typename MatrixType, int Side, bool Transposed>
|
||||
struct permut_matrix_product_retval
|
||||
: public ReturnByValue<permut_matrix_product_retval<PermutationType, MatrixType, Side, Transposed> >
|
||||
{
|
||||
typedef typename remove_all<typename MatrixType::Nested>::type MatrixTypeNestedCleaned;
|
||||
typedef typename MatrixType::Index Index;
|
||||
|
||||
permut_matrix_product_retval(const PermutationType& perm, const MatrixType& matrix)
|
||||
: m_permutation(perm), m_matrix(matrix)
|
||||
{}
|
||||
|
||||
inline Index rows() const { return m_matrix.rows(); }
|
||||
inline Index cols() const { return m_matrix.cols(); }
|
||||
|
||||
template<typename Dest> inline void evalTo(Dest& dst) const
|
||||
{
|
||||
const Index n = Side==OnTheLeft ? rows() : cols();
|
||||
|
||||
if(is_same<MatrixTypeNestedCleaned,Dest>::value && extract_data(dst) == extract_data(m_matrix))
|
||||
{
|
||||
// apply the permutation inplace
|
||||
Matrix<bool,PermutationType::RowsAtCompileTime,1,0,PermutationType::MaxRowsAtCompileTime> mask(m_permutation.size());
|
||||
mask.fill(false);
|
||||
Index r = 0;
|
||||
while(r < m_permutation.size())
|
||||
{
|
||||
// search for the next seed
|
||||
while(r<m_permutation.size() && mask[r]) r++;
|
||||
if(r>=m_permutation.size())
|
||||
break;
|
||||
// we got one, let's follow it until we are back to the seed
|
||||
Index k0 = r++;
|
||||
Index kPrev = k0;
|
||||
mask.coeffRef(k0) = true;
|
||||
for(Index k=m_permutation.indices().coeff(k0); k!=k0; k=m_permutation.indices().coeff(k))
|
||||
{
|
||||
Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>(dst, k)
|
||||
.swap(Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>
|
||||
(dst,((Side==OnTheLeft) ^ Transposed) ? k0 : kPrev));
|
||||
|
||||
mask.coeffRef(k) = true;
|
||||
kPrev = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = 0; i < n; ++i)
|
||||
{
|
||||
Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>
|
||||
(dst, ((Side==OnTheLeft) ^ Transposed) ? m_permutation.indices().coeff(i) : i)
|
||||
|
||||
=
|
||||
|
||||
Block<const MatrixTypeNestedCleaned,Side==OnTheLeft ? 1 : MatrixType::RowsAtCompileTime,Side==OnTheRight ? 1 : MatrixType::ColsAtCompileTime>
|
||||
(m_matrix, ((Side==OnTheRight) ^ Transposed) ? m_permutation.indices().coeff(i) : i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
const PermutationType& m_permutation;
|
||||
typename MatrixType::Nested m_matrix;
|
||||
};
|
||||
|
||||
/* Template partial specialization for transposed/inverse permutations */
|
||||
|
||||
template<typename Derived>
|
||||
@@ -610,6 +572,8 @@ struct traits<Transpose<PermutationBase<Derived> > >
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
// TODO: the specificties should be handled by the evaluator,
|
||||
// at the very least we should only specialize TransposeImpl
|
||||
template<typename Derived>
|
||||
class Transpose<PermutationBase<Derived> >
|
||||
: public EigenBase<Transpose<PermutationBase<Derived> > >
|
||||
@@ -624,26 +588,26 @@ class Transpose<PermutationBase<Derived> >
|
||||
typedef typename Derived::DenseMatrixType DenseMatrixType;
|
||||
enum {
|
||||
Flags = Traits::Flags,
|
||||
CoeffReadCost = Traits::CoeffReadCost,
|
||||
RowsAtCompileTime = Traits::RowsAtCompileTime,
|
||||
ColsAtCompileTime = Traits::ColsAtCompileTime,
|
||||
MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = Traits::MaxColsAtCompileTime
|
||||
};
|
||||
typedef typename Traits::Scalar Scalar;
|
||||
typedef typename Traits::StorageIndex StorageIndex;
|
||||
#endif
|
||||
|
||||
Transpose(const PermutationType& p) : m_permutation(p) {}
|
||||
|
||||
inline int rows() const { return m_permutation.rows(); }
|
||||
inline int cols() const { return m_permutation.cols(); }
|
||||
inline Index rows() const { return m_permutation.rows(); }
|
||||
inline Index cols() const { return m_permutation.cols(); }
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
template<typename DenseDerived>
|
||||
void evalTo(MatrixBase<DenseDerived>& other) const
|
||||
{
|
||||
other.setZero();
|
||||
for (int i=0; i<rows();++i)
|
||||
for (Index i=0; i<rows();++i)
|
||||
other.coeffRef(i, m_permutation.indices().coeff(i)) = typename DenseDerived::Scalar(1);
|
||||
}
|
||||
#endif
|
||||
@@ -656,22 +620,22 @@ class Transpose<PermutationBase<Derived> >
|
||||
/** \returns the matrix with the inverse permutation applied to the columns.
|
||||
*/
|
||||
template<typename OtherDerived> friend
|
||||
inline const internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheRight, true>
|
||||
const Product<OtherDerived, Transpose, AliasFreeProduct>
|
||||
operator*(const MatrixBase<OtherDerived>& matrix, const Transpose& trPerm)
|
||||
{
|
||||
return internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheRight, true>(trPerm.m_permutation, matrix.derived());
|
||||
return Product<OtherDerived, Transpose, AliasFreeProduct>(matrix.derived(), trPerm.derived());
|
||||
}
|
||||
|
||||
/** \returns the matrix with the inverse permutation applied to the rows.
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
inline const internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheLeft, true>
|
||||
const Product<Transpose, OtherDerived, AliasFreeProduct>
|
||||
operator*(const MatrixBase<OtherDerived>& matrix) const
|
||||
{
|
||||
return internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheLeft, true>(m_permutation, matrix.derived());
|
||||
return Product<Transpose, OtherDerived, AliasFreeProduct>(*this, matrix.derived());
|
||||
}
|
||||
|
||||
const PermutationType& nestedPermutation() const { return m_permutation; }
|
||||
const PermutationType& nestedExpression() const { return m_permutation; }
|
||||
|
||||
protected:
|
||||
const PermutationType& m_permutation;
|
||||
@@ -683,6 +647,12 @@ const PermutationWrapper<const Derived> MatrixBase<Derived>::asPermutation() con
|
||||
return derived();
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<> struct AssignmentKind<DenseShape,PermutationShape> { typedef EigenBase2EigenBase Kind; };
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_PERMUTATIONMATRIX_H
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace internal {
|
||||
|
||||
template<int MaxSizeAtCompileTime> struct check_rows_cols_for_overflow {
|
||||
template<typename Index>
|
||||
EIGEN_DEVICE_FUNC
|
||||
static EIGEN_ALWAYS_INLINE void run(Index, Index)
|
||||
{
|
||||
}
|
||||
@@ -35,6 +36,7 @@ template<int MaxSizeAtCompileTime> struct check_rows_cols_for_overflow {
|
||||
|
||||
template<> struct check_rows_cols_for_overflow<Dynamic> {
|
||||
template<typename Index>
|
||||
EIGEN_DEVICE_FUNC
|
||||
static EIGEN_ALWAYS_INLINE void run(Index rows, Index cols)
|
||||
{
|
||||
// http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242
|
||||
@@ -47,7 +49,10 @@ template<> struct check_rows_cols_for_overflow<Dynamic> {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Derived, typename OtherDerived = Derived, bool IsVector = bool(Derived::IsVectorAtCompileTime)> struct conservative_resize_like_impl;
|
||||
template <typename Derived,
|
||||
typename OtherDerived = Derived,
|
||||
bool IsVector = bool(Derived::IsVectorAtCompileTime) && bool(OtherDerived::IsVectorAtCompileTime)>
|
||||
struct conservative_resize_like_impl;
|
||||
|
||||
template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl;
|
||||
|
||||
@@ -64,8 +69,9 @@ template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct m
|
||||
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
||||
namespace internal {
|
||||
|
||||
// this is a warkaround to doxygen not being able to understand the inheritence logic
|
||||
// this is a workaround to doxygen not being able to understand the inheritance logic
|
||||
// when it is hidden by the dense_xpr_base helper struct.
|
||||
/** This class is just a workaround for Doxygen and it does not not actually exist. */
|
||||
template<typename Derived> struct dense_xpr_base_dispatcher_for_doxygen;// : public MatrixBase<Derived> {};
|
||||
/** This class is just a workaround for Doxygen and it does not not actually exist. */
|
||||
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
||||
@@ -90,8 +96,8 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
typedef typename internal::dense_xpr_base<Derived>::type Base;
|
||||
|
||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||
typedef typename internal::traits<Derived>::Index Index;
|
||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||
|
||||
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
typedef Derived DenseType;
|
||||
@@ -110,28 +116,36 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
typedef Eigen::Map<Derived, Unaligned> MapType;
|
||||
friend class Eigen::Map<const Derived, Unaligned>;
|
||||
typedef const Eigen::Map<const Derived, Unaligned> ConstMapType;
|
||||
friend class Eigen::Map<Derived, Aligned>;
|
||||
typedef Eigen::Map<Derived, Aligned> AlignedMapType;
|
||||
friend class Eigen::Map<const Derived, Aligned>;
|
||||
typedef const Eigen::Map<const Derived, Aligned> ConstAlignedMapType;
|
||||
#if EIGEN_MAX_ALIGN_BYTES>0
|
||||
// for EIGEN_MAX_ALIGN_BYTES==0, AlignedMax==Unaligned, and many compilers generate warnings for friend-ing a class twice.
|
||||
friend class Eigen::Map<Derived, AlignedMax>;
|
||||
friend class Eigen::Map<const Derived, AlignedMax>;
|
||||
#endif
|
||||
typedef Eigen::Map<Derived, AlignedMax> AlignedMapType;
|
||||
typedef const Eigen::Map<const Derived, AlignedMax> ConstAlignedMapType;
|
||||
template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; };
|
||||
template<typename StrideType> struct StridedConstMapType { typedef Eigen::Map<const Derived, Unaligned, StrideType> type; };
|
||||
template<typename StrideType> struct StridedAlignedMapType { typedef Eigen::Map<Derived, Aligned, StrideType> type; };
|
||||
template<typename StrideType> struct StridedConstAlignedMapType { typedef Eigen::Map<const Derived, Aligned, StrideType> type; };
|
||||
template<typename StrideType> struct StridedAlignedMapType { typedef Eigen::Map<Derived, AlignedMax, StrideType> type; };
|
||||
template<typename StrideType> struct StridedConstAlignedMapType { typedef Eigen::Map<const Derived, AlignedMax, StrideType> type; };
|
||||
|
||||
protected:
|
||||
DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
|
||||
|
||||
public:
|
||||
enum { NeedsToAlign = SizeAtCompileTime != Dynamic && (internal::traits<Derived>::Flags & AlignedBit) != 0 };
|
||||
enum { NeedsToAlign = (SizeAtCompileTime != Dynamic) && (internal::traits<Derived>::Alignment>0) };
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
Base& base() { return *static_cast<Base*>(this); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
const Base& base() const { return *static_cast<const Base*>(this); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const Scalar& coeff(Index rowId, Index colId) const
|
||||
{
|
||||
if(Flags & RowMajorBit)
|
||||
@@ -140,11 +154,13 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
return m_storage.data()[rowId + colId * m_storage.rows()];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const
|
||||
{
|
||||
return m_storage.data()[index];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId)
|
||||
{
|
||||
if(Flags & RowMajorBit)
|
||||
@@ -153,11 +169,13 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
return m_storage.data()[rowId + colId * m_storage.rows()];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
|
||||
{
|
||||
return m_storage.data()[index];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const Scalar& coeffRef(Index rowId, Index colId) const
|
||||
{
|
||||
if(Flags & RowMajorBit)
|
||||
@@ -166,6 +184,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
return m_storage.data()[rowId + colId * m_storage.rows()];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const
|
||||
{
|
||||
return m_storage.data()[index];
|
||||
@@ -206,11 +225,11 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
}
|
||||
|
||||
/** \returns a const pointer to the data array of this matrix */
|
||||
EIGEN_STRONG_INLINE const Scalar *data() const
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar *data() const
|
||||
{ return m_storage.data(); }
|
||||
|
||||
/** \returns a pointer to the data array of this matrix */
|
||||
EIGEN_STRONG_INLINE Scalar *data()
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar *data()
|
||||
{ return m_storage.data(); }
|
||||
|
||||
/** Resizes \c *this to a \a rows x \a cols matrix.
|
||||
@@ -229,22 +248,23 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
*
|
||||
* \sa resize(Index) for vectors, resize(NoChange_t, Index), resize(Index, NoChange_t)
|
||||
*/
|
||||
EIGEN_STRONG_INLINE void resize(Index nbRows, Index nbCols)
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
|
||||
{
|
||||
eigen_assert( EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,nbRows==RowsAtCompileTime)
|
||||
&& EIGEN_IMPLIES(ColsAtCompileTime!=Dynamic,nbCols==ColsAtCompileTime)
|
||||
&& EIGEN_IMPLIES(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic,nbRows<=MaxRowsAtCompileTime)
|
||||
&& EIGEN_IMPLIES(ColsAtCompileTime==Dynamic && MaxColsAtCompileTime!=Dynamic,nbCols<=MaxColsAtCompileTime)
|
||||
&& nbRows>=0 && nbCols>=0 && "Invalid sizes when resizing a matrix or array.");
|
||||
internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(nbRows, nbCols);
|
||||
eigen_assert( EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,rows==RowsAtCompileTime)
|
||||
&& EIGEN_IMPLIES(ColsAtCompileTime!=Dynamic,cols==ColsAtCompileTime)
|
||||
&& EIGEN_IMPLIES(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic,rows<=MaxRowsAtCompileTime)
|
||||
&& EIGEN_IMPLIES(ColsAtCompileTime==Dynamic && MaxColsAtCompileTime!=Dynamic,cols<=MaxColsAtCompileTime)
|
||||
&& rows>=0 && cols>=0 && "Invalid sizes when resizing a matrix or array.");
|
||||
internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(rows, cols);
|
||||
#ifdef EIGEN_INITIALIZE_COEFFS
|
||||
Index size = nbRows*nbCols;
|
||||
Index size = rows*cols;
|
||||
bool size_changed = size != this->size();
|
||||
m_storage.resize(size, nbRows, nbCols);
|
||||
m_storage.resize(size, rows, cols);
|
||||
if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
||||
#else
|
||||
internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(nbRows, nbCols);
|
||||
m_storage.resize(nbRows*nbCols, nbRows, nbCols);
|
||||
internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(rows, cols);
|
||||
m_storage.resize(rows*cols, rows, cols);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -259,6 +279,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
*
|
||||
* \sa resize(Index,Index), resize(NoChange_t, Index), resize(Index, NoChange_t)
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline void resize(Index size)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase)
|
||||
@@ -283,9 +304,10 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
*
|
||||
* \sa resize(Index,Index)
|
||||
*/
|
||||
inline void resize(NoChange_t, Index nbCols)
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline void resize(NoChange_t, Index cols)
|
||||
{
|
||||
resize(rows(), nbCols);
|
||||
resize(rows(), cols);
|
||||
}
|
||||
|
||||
/** Resizes the matrix, changing only the number of rows. For the parameter of type NoChange_t, just pass the special value \c NoChange
|
||||
@@ -296,9 +318,10 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
*
|
||||
* \sa resize(Index,Index)
|
||||
*/
|
||||
inline void resize(Index nbRows, NoChange_t)
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline void resize(Index rows, NoChange_t)
|
||||
{
|
||||
resize(nbRows, cols());
|
||||
resize(rows, cols());
|
||||
}
|
||||
|
||||
/** Resizes \c *this to have the same dimensions as \a other.
|
||||
@@ -309,6 +332,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
* remain row-vectors and vectors remain vectors.
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
|
||||
{
|
||||
const OtherDerived& other = _other.derived();
|
||||
@@ -336,9 +360,10 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
* Matrices are resized relative to the top-left element. In case values need to be
|
||||
* appended to the matrix they will be uninitialized.
|
||||
*/
|
||||
EIGEN_STRONG_INLINE void conservativeResize(Index nbRows, Index nbCols)
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols)
|
||||
{
|
||||
internal::conservative_resize_like_impl<Derived>::run(*this, nbRows, nbCols);
|
||||
internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols);
|
||||
}
|
||||
|
||||
/** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
|
||||
@@ -348,10 +373,11 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
*
|
||||
* In case the matrix is growing, new rows will be uninitialized.
|
||||
*/
|
||||
EIGEN_STRONG_INLINE void conservativeResize(Index nbRows, NoChange_t)
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t)
|
||||
{
|
||||
// Note: see the comment in conservativeResize(Index,Index)
|
||||
conservativeResize(nbRows, cols());
|
||||
conservativeResize(rows, cols());
|
||||
}
|
||||
|
||||
/** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
|
||||
@@ -361,10 +387,11 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
*
|
||||
* In case the matrix is growing, new columns will be uninitialized.
|
||||
*/
|
||||
EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index nbCols)
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols)
|
||||
{
|
||||
// Note: see the comment in conservativeResize(Index,Index)
|
||||
conservativeResize(rows(), nbCols);
|
||||
conservativeResize(rows(), cols);
|
||||
}
|
||||
|
||||
/** Resizes the vector to \a size while retaining old values.
|
||||
@@ -375,6 +402,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
*
|
||||
* When values are appended, they will be uninitialized.
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void conservativeResize(Index size)
|
||||
{
|
||||
internal::conservative_resize_like_impl<Derived>::run(*this, size);
|
||||
@@ -390,6 +418,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
* appended to the matrix they will copied from \c other.
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other);
|
||||
@@ -398,6 +427,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
/** This is a special case of the templated operator=. Its purpose is to
|
||||
* prevent a default operator= from hiding the templated operator=.
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other)
|
||||
{
|
||||
return _set(other);
|
||||
@@ -405,6 +435,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
|
||||
/** \sa MatrixBase::lazyAssign() */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
_resize_to_match(other);
|
||||
@@ -412,12 +443,14 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
}
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func)
|
||||
{
|
||||
resize(func.rows(), func.cols());
|
||||
return Base::operator=(func);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE PlainObjectBase() : m_storage()
|
||||
{
|
||||
// _check_template_params();
|
||||
@@ -427,15 +460,37 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
// FIXME is it still needed ?
|
||||
/** \internal */
|
||||
PlainObjectBase(internal::constructor_without_unaligned_array_assert)
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit PlainObjectBase(internal::constructor_without_unaligned_array_assert)
|
||||
: m_storage(internal::constructor_without_unaligned_array_assert())
|
||||
{
|
||||
// _check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
||||
}
|
||||
#endif
|
||||
|
||||
EIGEN_STRONG_INLINE PlainObjectBase(Index a_size, Index nbRows, Index nbCols)
|
||||
: m_storage(a_size, nbRows, nbCols)
|
||||
#ifdef EIGEN_HAVE_RVALUE_REFERENCES
|
||||
EIGEN_DEVICE_FUNC
|
||||
PlainObjectBase(PlainObjectBase&& other)
|
||||
: m_storage( std::move(other.m_storage) )
|
||||
{
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
PlainObjectBase& operator=(PlainObjectBase&& other)
|
||||
{
|
||||
using std::swap;
|
||||
swap(m_storage, other.m_storage);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Copy constructor */
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other)
|
||||
: Base(), m_storage(other.m_storage) { }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols)
|
||||
: m_storage(size, rows, cols)
|
||||
{
|
||||
// _check_template_params();
|
||||
// EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
|
||||
@@ -444,6 +499,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
/** \copydoc MatrixBase::operator=(const EigenBase<OtherDerived>&)
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other)
|
||||
{
|
||||
_resize_to_match(other);
|
||||
@@ -451,14 +507,36 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
return this->derived();
|
||||
}
|
||||
|
||||
/** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */
|
||||
/** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other)
|
||||
: m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase<OtherDerived> &other)
|
||||
: m_storage()
|
||||
{
|
||||
_check_template_params();
|
||||
internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.derived().rows(), other.derived().cols());
|
||||
Base::operator=(other.derived());
|
||||
resizeLike(other);
|
||||
_set_noalias(other);
|
||||
}
|
||||
|
||||
/** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other)
|
||||
: m_storage()
|
||||
{
|
||||
_check_template_params();
|
||||
resizeLike(other);
|
||||
*this = other.derived();
|
||||
}
|
||||
/** \brief Copy constructor with in-place evaluation */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE PlainObjectBase(const ReturnByValue<OtherDerived>& other)
|
||||
{
|
||||
_check_template_params();
|
||||
// FIXME this does not automatically transpose vectors if necessary
|
||||
resize(other.rows(), other.cols());
|
||||
other.evalTo(this->derived());
|
||||
}
|
||||
|
||||
/** \name Map
|
||||
@@ -535,16 +613,16 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
//@}
|
||||
|
||||
using Base::setConstant;
|
||||
Derived& setConstant(Index size, const Scalar& value);
|
||||
Derived& setConstant(Index rows, Index cols, const Scalar& value);
|
||||
EIGEN_DEVICE_FUNC Derived& setConstant(Index size, const Scalar& value);
|
||||
EIGEN_DEVICE_FUNC Derived& setConstant(Index rows, Index cols, const Scalar& value);
|
||||
|
||||
using Base::setZero;
|
||||
Derived& setZero(Index size);
|
||||
Derived& setZero(Index rows, Index cols);
|
||||
EIGEN_DEVICE_FUNC Derived& setZero(Index size);
|
||||
EIGEN_DEVICE_FUNC Derived& setZero(Index rows, Index cols);
|
||||
|
||||
using Base::setOnes;
|
||||
Derived& setOnes(Index size);
|
||||
Derived& setOnes(Index rows, Index cols);
|
||||
EIGEN_DEVICE_FUNC Derived& setOnes(Index size);
|
||||
EIGEN_DEVICE_FUNC Derived& setOnes(Index rows, Index cols);
|
||||
|
||||
using Base::setRandom;
|
||||
Derived& setRandom(Index size);
|
||||
@@ -563,6 +641,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
* remain row-vectors and vectors remain vectors.
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other)
|
||||
{
|
||||
#ifdef EIGEN_NO_AUTOMATIC_RESIZING
|
||||
@@ -589,25 +668,23 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
*
|
||||
* \internal
|
||||
*/
|
||||
// aliasing is dealt once in internall::call_assignment
|
||||
// so at this stage we have to assume aliasing... and resising has to be done later.
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
_set_selector(other.derived(), typename internal::conditional<static_cast<bool>(int(OtherDerived::Flags) & EvalBeforeAssigningBit), internal::true_type, internal::false_type>::type());
|
||||
internal::call_assignment(this->derived(), other.derived());
|
||||
return this->derived();
|
||||
}
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::true_type&) { _set_noalias(other.eval()); }
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::false_type&) { _set_noalias(other); }
|
||||
|
||||
/** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which
|
||||
* is the case when creating a new matrix) so one can enforce lazy evaluation.
|
||||
*
|
||||
* \sa operator=(const MatrixBase<OtherDerived>&), _set()
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
// I don't think we need this resize call since the lazyAssign will anyways resize
|
||||
@@ -615,40 +692,166 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
//_resize_to_match(other);
|
||||
// the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because
|
||||
// it wouldn't allow to copy a row-vector into a column-vector.
|
||||
return internal::assign_selector<Derived,OtherDerived,false>::run(this->derived(), other.derived());
|
||||
internal::call_assignment_no_alias(this->derived(), other.derived(), internal::assign_op<Scalar>());
|
||||
return this->derived();
|
||||
}
|
||||
|
||||
template<typename T0, typename T1>
|
||||
EIGEN_STRONG_INLINE void _init2(Index nbRows, Index nbCols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) &&
|
||||
bool(NumTraits<T1>::IsInteger),
|
||||
FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
|
||||
resize(nbRows,nbCols);
|
||||
resize(rows,cols);
|
||||
}
|
||||
|
||||
template<typename T0, typename T1>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void _init2(const Scalar& val0, const Scalar& val1, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
|
||||
m_storage.data()[0] = val0;
|
||||
m_storage.data()[1] = val1;
|
||||
}
|
||||
|
||||
template<typename T0, typename T1>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void _init2(const Index& val0, const Index& val1,
|
||||
typename internal::enable_if< (!internal::is_same<Index,Scalar>::value)
|
||||
&& (internal::is_same<T0,Index>::value)
|
||||
&& (internal::is_same<T1,Index>::value)
|
||||
&& Base::SizeAtCompileTime==2,T1>::type* = 0)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
|
||||
m_storage.data()[0] = Scalar(val0);
|
||||
m_storage.data()[1] = Scalar(val1);
|
||||
}
|
||||
|
||||
// The argument is convertible to the Index type and we either have a non 1x1 Matrix, or a dynamic-sized Array,
|
||||
// then the argument is meant to be the size of the object.
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void _init1(Index size, typename internal::enable_if< (Base::SizeAtCompileTime!=1 || !internal::is_convertible<T, Scalar>::value)
|
||||
&& ((!internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value || Base::SizeAtCompileTime==Dynamic)),T>::type* = 0)
|
||||
{
|
||||
// NOTE MSVC 2008 complains if we directly put bool(NumTraits<T>::IsInteger) as the EIGEN_STATIC_ASSERT argument.
|
||||
const bool is_integer = NumTraits<T>::IsInteger;
|
||||
EIGEN_STATIC_ASSERT(is_integer,
|
||||
FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
|
||||
resize(size);
|
||||
}
|
||||
|
||||
// We have a 1x1 matrix/array => the argument is interpreted as the value of the unique coefficient (case where scalar type can be implicitely converted)
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void _init1(const Scalar& val0, typename internal::enable_if<Base::SizeAtCompileTime==1 && internal::is_convertible<T, Scalar>::value,T>::type* = 0)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1)
|
||||
m_storage.data()[0] = val0;
|
||||
}
|
||||
|
||||
// We have a 1x1 matrix/array => the argument is interpreted as the value of the unique coefficient (case where scalar type match the index type)
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void _init1(const Index& val0,
|
||||
typename internal::enable_if< (!internal::is_same<Index,Scalar>::value)
|
||||
&& (internal::is_same<Index,T>::value)
|
||||
&& Base::SizeAtCompileTime==1
|
||||
&& internal::is_convertible<T, Scalar>::value,T*>::type* = 0)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1)
|
||||
m_storage.data()[0] = Scalar(val0);
|
||||
}
|
||||
|
||||
// Initialize a fixed size matrix from a pointer to raw data
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void _init1(const Scalar* data){
|
||||
this->_set_noalias(ConstMapType(data));
|
||||
}
|
||||
|
||||
// Initialize an arbitrary matrix from a dense expression
|
||||
template<typename T, typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void _init1(const DenseBase<OtherDerived>& other){
|
||||
this->_set_noalias(other);
|
||||
}
|
||||
|
||||
// Initialize an arbitrary matrix from a generic Eigen expression
|
||||
template<typename T, typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void _init1(const EigenBase<OtherDerived>& other){
|
||||
this->derived() = other;
|
||||
}
|
||||
|
||||
template<typename T, typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void _init1(const ReturnByValue<OtherDerived>& other)
|
||||
{
|
||||
resize(other.rows(), other.cols());
|
||||
other.evalTo(this->derived());
|
||||
}
|
||||
|
||||
template<typename T, typename OtherDerived, int ColsAtCompileTime>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void _init1(const RotationBase<OtherDerived,ColsAtCompileTime>& r)
|
||||
{
|
||||
this->derived() = r;
|
||||
}
|
||||
|
||||
// For fixed -size arrays:
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void _init1(const Scalar& val0,
|
||||
typename internal::enable_if< Base::SizeAtCompileTime!=Dynamic
|
||||
&& Base::SizeAtCompileTime!=1
|
||||
&& internal::is_convertible<T, Scalar>::value
|
||||
&& internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T>::type* = 0)
|
||||
{
|
||||
Base::setConstant(val0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE void _init1(const Index& val0,
|
||||
typename internal::enable_if< (!internal::is_same<Index,Scalar>::value)
|
||||
&& (internal::is_same<Index,T>::value)
|
||||
&& Base::SizeAtCompileTime!=Dynamic
|
||||
&& Base::SizeAtCompileTime!=1
|
||||
&& internal::is_convertible<T, Scalar>::value
|
||||
&& internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T*>::type* = 0)
|
||||
{
|
||||
Base::setConstant(val0);
|
||||
}
|
||||
|
||||
template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
|
||||
friend struct internal::matrix_swap_impl;
|
||||
|
||||
/** \internal generic implementation of swap for dense storage since for dynamic-sized matrices of same type it is enough to swap the
|
||||
* data pointers.
|
||||
public:
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
/** \internal
|
||||
* \brief Override DenseBase::swap() since for dynamic-sized matrices
|
||||
* of same type it is enough to swap the data pointers.
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
void _swap(DenseBase<OtherDerived> const & other)
|
||||
EIGEN_DEVICE_FUNC
|
||||
void swap(DenseBase<OtherDerived> & other)
|
||||
{
|
||||
enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
|
||||
internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.const_cast_derived());
|
||||
internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.derived());
|
||||
}
|
||||
|
||||
public:
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
/** \internal
|
||||
* \brief const version forwarded to DenseBase::swap
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
void swap(DenseBase<OtherDerived> const & other)
|
||||
{ Base::swap(other.derived()); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
static EIGEN_STRONG_INLINE void _check_template_params()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
|
||||
@@ -662,16 +865,16 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
&& (Options & (DontAlign|RowMajor)) == Options),
|
||||
INVALID_MATRIX_TEMPLATE_PARAMETERS)
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
enum { ThisConstantIsPrivateInPlainObjectBase };
|
||||
enum { IsPlainObjectBase = 1 };
|
||||
#endif
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <typename Derived, typename OtherDerived, bool IsVector>
|
||||
struct internal::conservative_resize_like_impl
|
||||
struct conservative_resize_like_impl
|
||||
{
|
||||
typedef typename Derived::Index Index;
|
||||
static void run(DenseBase<Derived>& _this, Index rows, Index cols)
|
||||
{
|
||||
if (_this.rows() == rows && _this.cols() == cols) return;
|
||||
@@ -729,12 +932,14 @@ struct internal::conservative_resize_like_impl
|
||||
}
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Here, the specialization for vectors inherits from the general matrix case
|
||||
// to allow calling .conservativeResize(rows,cols) on vectors.
|
||||
template <typename Derived, typename OtherDerived>
|
||||
struct conservative_resize_like_impl<Derived,OtherDerived,true>
|
||||
: conservative_resize_like_impl<Derived,OtherDerived,false>
|
||||
{
|
||||
typedef typename Derived::Index Index;
|
||||
using conservative_resize_like_impl<Derived,OtherDerived,false>::run;
|
||||
|
||||
static void run(DenseBase<Derived>& _this, Index size)
|
||||
{
|
||||
const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
|
||||
@@ -760,6 +965,7 @@ struct conservative_resize_like_impl<Derived,OtherDerived,true>
|
||||
template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
|
||||
struct matrix_swap_impl
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline void run(MatrixTypeA& a, MatrixTypeB& b)
|
||||
{
|
||||
a.base().swap(b);
|
||||
@@ -769,6 +975,7 @@ struct matrix_swap_impl
|
||||
template<typename MatrixTypeA, typename MatrixTypeB>
|
||||
struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline void run(MatrixTypeA& a, MatrixTypeB& b)
|
||||
{
|
||||
static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage);
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
template<typename Lhs, typename Rhs> class Product;
|
||||
template<typename Lhs, typename Rhs, typename StorageKind> class ProductImpl;
|
||||
template<typename Lhs, typename Rhs, int Option, typename StorageKind> class ProductImpl;
|
||||
|
||||
/** \class Product
|
||||
* \ingroup Core_Module
|
||||
@@ -24,53 +23,121 @@ template<typename Lhs, typename Rhs, typename StorageKind> class ProductImpl;
|
||||
* \param Rhs the type of the right-hand side expression
|
||||
*
|
||||
* This class represents an expression of the product of two arbitrary matrices.
|
||||
*
|
||||
* The other template parameters are:
|
||||
* \tparam Option can be DefaultProduct, AliasFreeProduct, or LazyProduct
|
||||
*
|
||||
*/
|
||||
|
||||
// Use ProductReturnType to get correct traits, in particular vectorization flags
|
||||
|
||||
namespace internal {
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct traits<Product<Lhs, Rhs> >
|
||||
: traits<typename ProductReturnType<Lhs, Rhs>::Type>
|
||||
{
|
||||
// We want A+B*C to be of type Product<Matrix, Sum> and not Product<Matrix, Matrix>
|
||||
// TODO: This flag should eventually go in a separate evaluator traits class
|
||||
|
||||
// Determine the scalar of Product<Lhs, Rhs>. This is normally the same as Lhs::Scalar times
|
||||
// Rhs::Scalar, but product with permutation matrices inherit the scalar of the other factor.
|
||||
template<typename Lhs, typename Rhs, typename LhsShape = typename evaluator_traits<Lhs>::Shape,
|
||||
typename RhsShape = typename evaluator_traits<Rhs>::Shape >
|
||||
struct product_result_scalar
|
||||
{
|
||||
typedef typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType Scalar;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename RhsShape>
|
||||
struct product_result_scalar<Lhs, Rhs, PermutationShape, RhsShape>
|
||||
{
|
||||
typedef typename Rhs::Scalar Scalar;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename LhsShape>
|
||||
struct product_result_scalar<Lhs, Rhs, LhsShape, PermutationShape>
|
||||
{
|
||||
typedef typename Lhs::Scalar Scalar;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename RhsShape>
|
||||
struct product_result_scalar<Lhs, Rhs, TranspositionsShape, RhsShape>
|
||||
{
|
||||
typedef typename Rhs::Scalar Scalar;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename LhsShape>
|
||||
struct product_result_scalar<Lhs, Rhs, LhsShape, TranspositionsShape>
|
||||
{
|
||||
typedef typename Lhs::Scalar Scalar;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, int Option>
|
||||
struct traits<Product<Lhs, Rhs, Option> >
|
||||
{
|
||||
typedef typename remove_all<Lhs>::type LhsCleaned;
|
||||
typedef typename remove_all<Rhs>::type RhsCleaned;
|
||||
typedef traits<LhsCleaned> LhsTraits;
|
||||
typedef traits<RhsCleaned> RhsTraits;
|
||||
|
||||
typedef MatrixXpr XprKind;
|
||||
|
||||
typedef typename product_result_scalar<LhsCleaned,RhsCleaned>::Scalar Scalar;
|
||||
typedef typename product_promote_storage_type<typename LhsTraits::StorageKind,
|
||||
typename RhsTraits::StorageKind,
|
||||
internal::product_type<Lhs,Rhs>::ret>::ret StorageKind;
|
||||
typedef typename promote_index_type<typename LhsTraits::StorageIndex,
|
||||
typename RhsTraits::StorageIndex>::type StorageIndex;
|
||||
|
||||
enum {
|
||||
Flags = traits<typename ProductReturnType<Lhs, Rhs>::Type>::Flags & ~EvalBeforeNestingBit
|
||||
RowsAtCompileTime = LhsTraits::RowsAtCompileTime,
|
||||
ColsAtCompileTime = RhsTraits::ColsAtCompileTime,
|
||||
MaxRowsAtCompileTime = LhsTraits::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = RhsTraits::MaxColsAtCompileTime,
|
||||
|
||||
// FIXME: only needed by GeneralMatrixMatrixTriangular
|
||||
InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(LhsTraits::ColsAtCompileTime, RhsTraits::RowsAtCompileTime),
|
||||
|
||||
// The storage order is somewhat arbitrary here. The correct one will be determined through the evaluator.
|
||||
Flags = (MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1) ? RowMajorBit
|
||||
: (MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1) ? 0
|
||||
: ( ((LhsTraits::Flags&NoPreferredStorageOrderBit) && (RhsTraits::Flags&RowMajorBit))
|
||||
|| ((RhsTraits::Flags&NoPreferredStorageOrderBit) && (LhsTraits::Flags&RowMajorBit)) ) ? RowMajorBit
|
||||
: NoPreferredStorageOrderBit
|
||||
};
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
class Product : public ProductImpl<Lhs,Rhs,typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind,
|
||||
typename internal::traits<Rhs>::StorageKind>::ret>
|
||||
template<typename _Lhs, typename _Rhs, int Option>
|
||||
class Product : public ProductImpl<_Lhs,_Rhs,Option,
|
||||
typename internal::product_promote_storage_type<typename internal::traits<_Lhs>::StorageKind,
|
||||
typename internal::traits<_Rhs>::StorageKind,
|
||||
internal::product_type<_Lhs,_Rhs>::ret>::ret>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef _Lhs Lhs;
|
||||
typedef _Rhs Rhs;
|
||||
|
||||
typedef typename ProductImpl<
|
||||
Lhs, Rhs,
|
||||
typename internal::promote_storage_type<typename Lhs::StorageKind,
|
||||
typename Rhs::StorageKind>::ret>::Base Base;
|
||||
Lhs, Rhs, Option,
|
||||
typename internal::product_promote_storage_type<typename internal::traits<Lhs>::StorageKind,
|
||||
typename internal::traits<Rhs>::StorageKind,
|
||||
internal::product_type<Lhs,Rhs>::ret>::ret>::Base Base;
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(Product)
|
||||
|
||||
typedef typename Lhs::Nested LhsNested;
|
||||
typedef typename Rhs::Nested RhsNested;
|
||||
typedef typename internal::ref_selector<Lhs>::type LhsNested;
|
||||
typedef typename internal::ref_selector<Rhs>::type RhsNested;
|
||||
typedef typename internal::remove_all<LhsNested>::type LhsNestedCleaned;
|
||||
typedef typename internal::remove_all<RhsNested>::type RhsNestedCleaned;
|
||||
|
||||
Product(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs)
|
||||
EIGEN_DEVICE_FUNC Product(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs)
|
||||
{
|
||||
eigen_assert(lhs.cols() == rhs.rows()
|
||||
&& "invalid matrix product"
|
||||
&& "if you wanted a coeff-wise or a dot product use the respective explicit functions");
|
||||
}
|
||||
|
||||
inline Index rows() const { return m_lhs.rows(); }
|
||||
inline Index cols() const { return m_rhs.cols(); }
|
||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_lhs.rows(); }
|
||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_rhs.cols(); }
|
||||
|
||||
const LhsNestedCleaned& lhs() const { return m_lhs; }
|
||||
const RhsNestedCleaned& rhs() const { return m_rhs; }
|
||||
EIGEN_DEVICE_FUNC const LhsNestedCleaned& lhs() const { return m_lhs; }
|
||||
EIGEN_DEVICE_FUNC const RhsNestedCleaned& rhs() const { return m_rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
@@ -78,14 +145,76 @@ class Product : public ProductImpl<Lhs,Rhs,typename internal::promote_storage_ty
|
||||
RhsNested m_rhs;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
class ProductImpl<Lhs,Rhs,Dense> : public internal::dense_xpr_base<Product<Lhs,Rhs> >::type
|
||||
{
|
||||
typedef Product<Lhs, Rhs> Derived;
|
||||
public:
|
||||
namespace internal {
|
||||
|
||||
template<typename Lhs, typename Rhs, int Option, int ProductTag = internal::product_type<Lhs,Rhs>::ret>
|
||||
class dense_product_base
|
||||
: public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
|
||||
{};
|
||||
|
||||
typedef typename internal::dense_xpr_base<Product<Lhs, Rhs> >::type Base;
|
||||
/** Convertion to scalar for inner-products */
|
||||
template<typename Lhs, typename Rhs, int Option>
|
||||
class dense_product_base<Lhs, Rhs, Option, InnerProduct>
|
||||
: public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
|
||||
{
|
||||
typedef Product<Lhs,Rhs,Option> ProductXpr;
|
||||
typedef typename internal::dense_xpr_base<ProductXpr>::type Base;
|
||||
public:
|
||||
using Base::derived;
|
||||
typedef typename Base::Scalar Scalar;
|
||||
|
||||
operator const Scalar() const
|
||||
{
|
||||
return internal::evaluator<ProductXpr>(derived()).coeff(0,0);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Generic API dispatcher
|
||||
template<typename Lhs, typename Rhs, int Option, typename StorageKind>
|
||||
class ProductImpl : public internal::generic_xpr_base<Product<Lhs,Rhs,Option>, MatrixXpr, StorageKind>::type
|
||||
{
|
||||
public:
|
||||
typedef typename internal::generic_xpr_base<Product<Lhs,Rhs,Option>, MatrixXpr, StorageKind>::type Base;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, int Option>
|
||||
class ProductImpl<Lhs,Rhs,Option,Dense>
|
||||
: public internal::dense_product_base<Lhs,Rhs,Option>
|
||||
{
|
||||
typedef Product<Lhs, Rhs, Option> Derived;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename internal::dense_product_base<Lhs, Rhs, Option> Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
||||
protected:
|
||||
enum {
|
||||
IsOneByOne = (RowsAtCompileTime == 1 || RowsAtCompileTime == Dynamic) &&
|
||||
(ColsAtCompileTime == 1 || ColsAtCompileTime == Dynamic),
|
||||
EnableCoeff = IsOneByOne || Option==LazyProduct
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
EIGEN_DEVICE_FUNC Scalar coeff(Index row, Index col) const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
|
||||
eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) );
|
||||
|
||||
return internal::evaluator<Derived>(derived()).coeff(row,col);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC Scalar coeff(Index i) const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
|
||||
eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) );
|
||||
|
||||
return internal::evaluator<Derived>(derived()).coeff(i);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
@@ -102,6 +231,15 @@ prod(const Lhs& lhs, const Rhs& rhs)
|
||||
return Product<Lhs,Rhs>(lhs,rhs);
|
||||
}
|
||||
|
||||
/** \internal used to test the evaluator only
|
||||
*/
|
||||
template<typename Lhs,typename Rhs>
|
||||
const Product<Lhs,Rhs,LazyProduct>
|
||||
lazyprod(const Lhs& lhs, const Rhs& rhs)
|
||||
{
|
||||
return Product<Lhs,Rhs,LazyProduct>(lhs,rhs);
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_PRODUCT_H
|
||||
|
||||
@@ -1,278 +0,0 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef EIGEN_PRODUCTBASE_H
|
||||
#define EIGEN_PRODUCTBASE_H
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
/** \class ProductBase
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
*/
|
||||
|
||||
namespace internal {
|
||||
template<typename Derived, typename _Lhs, typename _Rhs>
|
||||
struct traits<ProductBase<Derived,_Lhs,_Rhs> >
|
||||
{
|
||||
typedef MatrixXpr XprKind;
|
||||
typedef typename remove_all<_Lhs>::type Lhs;
|
||||
typedef typename remove_all<_Rhs>::type Rhs;
|
||||
typedef typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType Scalar;
|
||||
typedef typename promote_storage_type<typename traits<Lhs>::StorageKind,
|
||||
typename traits<Rhs>::StorageKind>::ret StorageKind;
|
||||
typedef typename promote_index_type<typename traits<Lhs>::Index,
|
||||
typename traits<Rhs>::Index>::type Index;
|
||||
enum {
|
||||
RowsAtCompileTime = traits<Lhs>::RowsAtCompileTime,
|
||||
ColsAtCompileTime = traits<Rhs>::ColsAtCompileTime,
|
||||
MaxRowsAtCompileTime = traits<Lhs>::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = traits<Rhs>::MaxColsAtCompileTime,
|
||||
Flags = (MaxRowsAtCompileTime==1 ? RowMajorBit : 0)
|
||||
| EvalBeforeNestingBit | EvalBeforeAssigningBit | NestByRefBit,
|
||||
// Note that EvalBeforeNestingBit and NestByRefBit
|
||||
// are not used in practice because nested is overloaded for products
|
||||
CoeffReadCost = 0 // FIXME why is it needed ?
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
#define EIGEN_PRODUCT_PUBLIC_INTERFACE(Derived) \
|
||||
typedef ProductBase<Derived, Lhs, Rhs > Base; \
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived) \
|
||||
typedef typename Base::LhsNested LhsNested; \
|
||||
typedef typename Base::_LhsNested _LhsNested; \
|
||||
typedef typename Base::LhsBlasTraits LhsBlasTraits; \
|
||||
typedef typename Base::ActualLhsType ActualLhsType; \
|
||||
typedef typename Base::_ActualLhsType _ActualLhsType; \
|
||||
typedef typename Base::RhsNested RhsNested; \
|
||||
typedef typename Base::_RhsNested _RhsNested; \
|
||||
typedef typename Base::RhsBlasTraits RhsBlasTraits; \
|
||||
typedef typename Base::ActualRhsType ActualRhsType; \
|
||||
typedef typename Base::_ActualRhsType _ActualRhsType; \
|
||||
using Base::m_lhs; \
|
||||
using Base::m_rhs;
|
||||
|
||||
template<typename Derived, typename Lhs, typename Rhs>
|
||||
class ProductBase : public MatrixBase<Derived>
|
||||
{
|
||||
public:
|
||||
typedef MatrixBase<Derived> Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(ProductBase)
|
||||
|
||||
typedef typename Lhs::Nested LhsNested;
|
||||
typedef typename internal::remove_all<LhsNested>::type _LhsNested;
|
||||
typedef internal::blas_traits<_LhsNested> LhsBlasTraits;
|
||||
typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType;
|
||||
typedef typename internal::remove_all<ActualLhsType>::type _ActualLhsType;
|
||||
typedef typename internal::traits<Lhs>::Scalar LhsScalar;
|
||||
|
||||
typedef typename Rhs::Nested RhsNested;
|
||||
typedef typename internal::remove_all<RhsNested>::type _RhsNested;
|
||||
typedef internal::blas_traits<_RhsNested> RhsBlasTraits;
|
||||
typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType;
|
||||
typedef typename internal::remove_all<ActualRhsType>::type _ActualRhsType;
|
||||
typedef typename internal::traits<Rhs>::Scalar RhsScalar;
|
||||
|
||||
// Diagonal of a product: no need to evaluate the arguments because they are going to be evaluated only once
|
||||
typedef CoeffBasedProduct<LhsNested, RhsNested, 0> FullyLazyCoeffBaseProductType;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename Base::PlainObject PlainObject;
|
||||
|
||||
ProductBase(const Lhs& a_lhs, const Rhs& a_rhs)
|
||||
: m_lhs(a_lhs), m_rhs(a_rhs)
|
||||
{
|
||||
eigen_assert(a_lhs.cols() == a_rhs.rows()
|
||||
&& "invalid matrix product"
|
||||
&& "if you wanted a coeff-wise or a dot product use the respective explicit functions");
|
||||
}
|
||||
|
||||
inline Index rows() const { return m_lhs.rows(); }
|
||||
inline Index cols() const { return m_rhs.cols(); }
|
||||
|
||||
template<typename Dest>
|
||||
inline void evalTo(Dest& dst) const { dst.setZero(); scaleAndAddTo(dst,Scalar(1)); }
|
||||
|
||||
template<typename Dest>
|
||||
inline void addTo(Dest& dst) const { scaleAndAddTo(dst,Scalar(1)); }
|
||||
|
||||
template<typename Dest>
|
||||
inline void subTo(Dest& dst) const { scaleAndAddTo(dst,Scalar(-1)); }
|
||||
|
||||
template<typename Dest>
|
||||
inline void scaleAndAddTo(Dest& dst, const Scalar& alpha) const { derived().scaleAndAddTo(dst,alpha); }
|
||||
|
||||
const _LhsNested& lhs() const { return m_lhs; }
|
||||
const _RhsNested& rhs() const { return m_rhs; }
|
||||
|
||||
// Implicit conversion to the nested type (trigger the evaluation of the product)
|
||||
operator const PlainObject& () const
|
||||
{
|
||||
m_result.resize(m_lhs.rows(), m_rhs.cols());
|
||||
derived().evalTo(m_result);
|
||||
return m_result;
|
||||
}
|
||||
|
||||
const Diagonal<const FullyLazyCoeffBaseProductType,0> diagonal() const
|
||||
{ return FullyLazyCoeffBaseProductType(m_lhs, m_rhs); }
|
||||
|
||||
template<int Index>
|
||||
const Diagonal<FullyLazyCoeffBaseProductType,Index> diagonal() const
|
||||
{ return FullyLazyCoeffBaseProductType(m_lhs, m_rhs); }
|
||||
|
||||
const Diagonal<FullyLazyCoeffBaseProductType,Dynamic> diagonal(Index index) const
|
||||
{ return FullyLazyCoeffBaseProductType(m_lhs, m_rhs).diagonal(index); }
|
||||
|
||||
// restrict coeff accessors to 1x1 expressions. No need to care about mutators here since this isnt a Lvalue expression
|
||||
typename Base::CoeffReturnType coeff(Index row, Index col) const
|
||||
{
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
return lhs().row(row).cwiseProduct(rhs().col(col).transpose()).sum();
|
||||
#else
|
||||
EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
|
||||
eigen_assert(this->rows() == 1 && this->cols() == 1);
|
||||
Matrix<Scalar,1,1> result = *this;
|
||||
return result.coeff(row,col);
|
||||
#endif
|
||||
}
|
||||
|
||||
typename Base::CoeffReturnType coeff(Index i) const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
|
||||
eigen_assert(this->rows() == 1 && this->cols() == 1);
|
||||
Matrix<Scalar,1,1> result = *this;
|
||||
return result.coeff(i);
|
||||
}
|
||||
|
||||
const Scalar& coeffRef(Index row, Index col) const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
|
||||
eigen_assert(this->rows() == 1 && this->cols() == 1);
|
||||
return derived().coeffRef(row,col);
|
||||
}
|
||||
|
||||
const Scalar& coeffRef(Index i) const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
|
||||
eigen_assert(this->rows() == 1 && this->cols() == 1);
|
||||
return derived().coeffRef(i);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
LhsNested m_lhs;
|
||||
RhsNested m_rhs;
|
||||
|
||||
mutable PlainObject m_result;
|
||||
};
|
||||
|
||||
// here we need to overload the nested rule for products
|
||||
// such that the nested type is a const reference to a plain matrix
|
||||
namespace internal {
|
||||
template<typename Lhs, typename Rhs, int Mode, int N, typename PlainObject>
|
||||
struct nested<GeneralProduct<Lhs,Rhs,Mode>, N, PlainObject>
|
||||
{
|
||||
typedef PlainObject const& type;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename NestedProduct>
|
||||
class ScaledProduct;
|
||||
|
||||
// Note that these two operator* functions are not defined as member
|
||||
// functions of ProductBase, because, otherwise we would have to
|
||||
// define all overloads defined in MatrixBase. Furthermore, Using
|
||||
// "using Base::operator*" would not work with MSVC.
|
||||
//
|
||||
// Also note that here we accept any compatible scalar types
|
||||
template<typename Derived,typename Lhs,typename Rhs>
|
||||
const ScaledProduct<Derived>
|
||||
operator*(const ProductBase<Derived,Lhs,Rhs>& prod, const typename Derived::Scalar& x)
|
||||
{ return ScaledProduct<Derived>(prod.derived(), x); }
|
||||
|
||||
template<typename Derived,typename Lhs,typename Rhs>
|
||||
typename internal::enable_if<!internal::is_same<typename Derived::Scalar,typename Derived::RealScalar>::value,
|
||||
const ScaledProduct<Derived> >::type
|
||||
operator*(const ProductBase<Derived,Lhs,Rhs>& prod, const typename Derived::RealScalar& x)
|
||||
{ return ScaledProduct<Derived>(prod.derived(), x); }
|
||||
|
||||
|
||||
template<typename Derived,typename Lhs,typename Rhs>
|
||||
const ScaledProduct<Derived>
|
||||
operator*(const typename Derived::Scalar& x,const ProductBase<Derived,Lhs,Rhs>& prod)
|
||||
{ return ScaledProduct<Derived>(prod.derived(), x); }
|
||||
|
||||
template<typename Derived,typename Lhs,typename Rhs>
|
||||
typename internal::enable_if<!internal::is_same<typename Derived::Scalar,typename Derived::RealScalar>::value,
|
||||
const ScaledProduct<Derived> >::type
|
||||
operator*(const typename Derived::RealScalar& x,const ProductBase<Derived,Lhs,Rhs>& prod)
|
||||
{ return ScaledProduct<Derived>(prod.derived(), x); }
|
||||
|
||||
namespace internal {
|
||||
template<typename NestedProduct>
|
||||
struct traits<ScaledProduct<NestedProduct> >
|
||||
: traits<ProductBase<ScaledProduct<NestedProduct>,
|
||||
typename NestedProduct::_LhsNested,
|
||||
typename NestedProduct::_RhsNested> >
|
||||
{
|
||||
typedef typename traits<NestedProduct>::StorageKind StorageKind;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename NestedProduct>
|
||||
class ScaledProduct
|
||||
: public ProductBase<ScaledProduct<NestedProduct>,
|
||||
typename NestedProduct::_LhsNested,
|
||||
typename NestedProduct::_RhsNested>
|
||||
{
|
||||
public:
|
||||
typedef ProductBase<ScaledProduct<NestedProduct>,
|
||||
typename NestedProduct::_LhsNested,
|
||||
typename NestedProduct::_RhsNested> Base;
|
||||
typedef typename Base::Scalar Scalar;
|
||||
typedef typename Base::PlainObject PlainObject;
|
||||
// EIGEN_PRODUCT_PUBLIC_INTERFACE(ScaledProduct)
|
||||
|
||||
ScaledProduct(const NestedProduct& prod, const Scalar& x)
|
||||
: Base(prod.lhs(),prod.rhs()), m_prod(prod), m_alpha(x) {}
|
||||
|
||||
template<typename Dest>
|
||||
inline void evalTo(Dest& dst) const { dst.setZero(); scaleAndAddTo(dst, Scalar(1)); }
|
||||
|
||||
template<typename Dest>
|
||||
inline void addTo(Dest& dst) const { scaleAndAddTo(dst, Scalar(1)); }
|
||||
|
||||
template<typename Dest>
|
||||
inline void subTo(Dest& dst) const { scaleAndAddTo(dst, Scalar(-1)); }
|
||||
|
||||
template<typename Dest>
|
||||
inline void scaleAndAddTo(Dest& dst, const Scalar& a_alpha) const { m_prod.derived().scaleAndAddTo(dst,a_alpha * m_alpha); }
|
||||
|
||||
const Scalar& alpha() const { return m_alpha; }
|
||||
|
||||
protected:
|
||||
const NestedProduct& m_prod;
|
||||
Scalar m_alpha;
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* Overloaded to perform an efficient C = (A*B).lazy() */
|
||||
template<typename Derived>
|
||||
template<typename ProductDerived, typename Lhs, typename Rhs>
|
||||
Derived& MatrixBase<Derived>::lazyAssign(const ProductBase<ProductDerived, Lhs,Rhs>& other)
|
||||
{
|
||||
other.derived().evalTo(derived());
|
||||
return derived();
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_PRODUCTBASE_H
|
||||
1116
Eigen/src/Core/ProductEvaluators.h
Normal file → Executable file
1116
Eigen/src/Core/ProductEvaluators.h
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
@@ -28,12 +28,18 @@ struct functor_traits<scalar_random_op<Scalar> >
|
||||
|
||||
/** \returns a random matrix expression
|
||||
*
|
||||
* Numbers are uniformly spread through their whole definition range for integer types,
|
||||
* and in the [-1:1] range for floating point scalar types.
|
||||
*
|
||||
* The parameters \a rows and \a cols are the number of rows and of columns of
|
||||
* the returned matrix. Must be compatible with this MatrixBase type.
|
||||
*
|
||||
* \not_reentrant
|
||||
*
|
||||
* This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
|
||||
* it is redundant to pass \a rows and \a cols as arguments, so Random() should be used
|
||||
* instead.
|
||||
*
|
||||
*
|
||||
* Example: \include MatrixBase_random_int_int.cpp
|
||||
* Output: \verbinclude MatrixBase_random_int_int.out
|
||||
@@ -41,22 +47,28 @@ struct functor_traits<scalar_random_op<Scalar> >
|
||||
* This expression has the "evaluate before nesting" flag so that it will be evaluated into
|
||||
* a temporary matrix whenever it is nested in a larger expression. This prevents unexpected
|
||||
* behavior with expressions involving random matrices.
|
||||
*
|
||||
* See DenseBase::NullaryExpr(Index, const CustomNullaryOp&) for an example using C++11 random generators.
|
||||
*
|
||||
* \sa MatrixBase::setRandom(), MatrixBase::Random(Index), MatrixBase::Random()
|
||||
* \sa DenseBase::setRandom(), DenseBase::Random(Index), DenseBase::Random()
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline const CwiseNullaryOp<internal::scalar_random_op<typename internal::traits<Derived>::Scalar>, Derived>
|
||||
inline const typename DenseBase<Derived>::RandomReturnType
|
||||
DenseBase<Derived>::Random(Index rows, Index cols)
|
||||
{
|
||||
return NullaryExpr(rows, cols, internal::scalar_random_op<Scalar>());
|
||||
}
|
||||
|
||||
/** \returns a random vector expression
|
||||
*
|
||||
* Numbers are uniformly spread through their whole definition range for integer types,
|
||||
* and in the [-1:1] range for floating point scalar types.
|
||||
*
|
||||
* The parameter \a size is the size of the returned vector.
|
||||
* Must be compatible with this MatrixBase type.
|
||||
*
|
||||
* \only_for_vectors
|
||||
* \not_reentrant
|
||||
*
|
||||
* This variant is meant to be used for dynamic-size vector types. For fixed-size types,
|
||||
* it is redundant to pass \a size as argument, so Random() should be used
|
||||
@@ -69,10 +81,10 @@ DenseBase<Derived>::Random(Index rows, Index cols)
|
||||
* a temporary vector whenever it is nested in a larger expression. This prevents unexpected
|
||||
* behavior with expressions involving random matrices.
|
||||
*
|
||||
* \sa MatrixBase::setRandom(), MatrixBase::Random(Index,Index), MatrixBase::Random()
|
||||
* \sa DenseBase::setRandom(), DenseBase::Random(Index,Index), DenseBase::Random()
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline const CwiseNullaryOp<internal::scalar_random_op<typename internal::traits<Derived>::Scalar>, Derived>
|
||||
inline const typename DenseBase<Derived>::RandomReturnType
|
||||
DenseBase<Derived>::Random(Index size)
|
||||
{
|
||||
return NullaryExpr(size, internal::scalar_random_op<Scalar>());
|
||||
@@ -80,6 +92,9 @@ DenseBase<Derived>::Random(Index size)
|
||||
|
||||
/** \returns a fixed-size random matrix or vector expression
|
||||
*
|
||||
* Numbers are uniformly spread through their whole definition range for integer types,
|
||||
* and in the [-1:1] range for floating point scalar types.
|
||||
*
|
||||
* This variant is only for fixed-size MatrixBase types. For dynamic-size types, you
|
||||
* need to use the variants taking size arguments.
|
||||
*
|
||||
@@ -89,11 +104,13 @@ DenseBase<Derived>::Random(Index size)
|
||||
* This expression has the "evaluate before nesting" flag so that it will be evaluated into
|
||||
* a temporary matrix whenever it is nested in a larger expression. This prevents unexpected
|
||||
* behavior with expressions involving random matrices.
|
||||
*
|
||||
* \not_reentrant
|
||||
*
|
||||
* \sa MatrixBase::setRandom(), MatrixBase::Random(Index,Index), MatrixBase::Random(Index)
|
||||
* \sa DenseBase::setRandom(), DenseBase::Random(Index,Index), DenseBase::Random(Index)
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline const CwiseNullaryOp<internal::scalar_random_op<typename internal::traits<Derived>::Scalar>, Derived>
|
||||
inline const typename DenseBase<Derived>::RandomReturnType
|
||||
DenseBase<Derived>::Random()
|
||||
{
|
||||
return NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_random_op<Scalar>());
|
||||
@@ -101,6 +118,11 @@ DenseBase<Derived>::Random()
|
||||
|
||||
/** Sets all coefficients in this expression to random values.
|
||||
*
|
||||
* Numbers are uniformly spread through their whole definition range for integer types,
|
||||
* and in the [-1:1] range for floating point scalar types.
|
||||
*
|
||||
* \not_reentrant
|
||||
*
|
||||
* Example: \include MatrixBase_setRandom.cpp
|
||||
* Output: \verbinclude MatrixBase_setRandom.out
|
||||
*
|
||||
@@ -114,12 +136,16 @@ inline Derived& DenseBase<Derived>::setRandom()
|
||||
|
||||
/** Resizes to the given \a newSize, and sets all coefficients in this expression to random values.
|
||||
*
|
||||
* Numbers are uniformly spread through their whole definition range for integer types,
|
||||
* and in the [-1:1] range for floating point scalar types.
|
||||
*
|
||||
* \only_for_vectors
|
||||
* \not_reentrant
|
||||
*
|
||||
* Example: \include Matrix_setRandom_int.cpp
|
||||
* Output: \verbinclude Matrix_setRandom_int.out
|
||||
*
|
||||
* \sa MatrixBase::setRandom(), setRandom(Index,Index), class CwiseNullaryOp, MatrixBase::Random()
|
||||
* \sa DenseBase::setRandom(), setRandom(Index,Index), class CwiseNullaryOp, DenseBase::Random()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived&
|
||||
@@ -131,19 +157,24 @@ PlainObjectBase<Derived>::setRandom(Index newSize)
|
||||
|
||||
/** Resizes to the given size, and sets all coefficients in this expression to random values.
|
||||
*
|
||||
* \param nbRows the new number of rows
|
||||
* \param nbCols the new number of columns
|
||||
* Numbers are uniformly spread through their whole definition range for integer types,
|
||||
* and in the [-1:1] range for floating point scalar types.
|
||||
*
|
||||
* \not_reentrant
|
||||
*
|
||||
* \param rows the new number of rows
|
||||
* \param cols the new number of columns
|
||||
*
|
||||
* Example: \include Matrix_setRandom_int_int.cpp
|
||||
* Output: \verbinclude Matrix_setRandom_int_int.out
|
||||
*
|
||||
* \sa MatrixBase::setRandom(), setRandom(Index), class CwiseNullaryOp, MatrixBase::Random()
|
||||
* \sa DenseBase::setRandom(), setRandom(Index), class CwiseNullaryOp, DenseBase::Random()
|
||||
*/
|
||||
template<typename Derived>
|
||||
EIGEN_STRONG_INLINE Derived&
|
||||
PlainObjectBase<Derived>::setRandom(Index nbRows, Index nbCols)
|
||||
PlainObjectBase<Derived>::setRandom(Index rows, Index cols)
|
||||
{
|
||||
resize(nbRows, nbCols);
|
||||
resize(rows, cols);
|
||||
return setRandom();
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,25 @@ public:
|
||||
? CompleteUnrolling
|
||||
: NoUnrolling
|
||||
};
|
||||
|
||||
#ifdef EIGEN_DEBUG_ASSIGN
|
||||
static void debug()
|
||||
{
|
||||
std::cerr << "Xpr: " << typeid(typename Derived::XprType).name() << std::endl;
|
||||
std::cerr.setf(std::ios::hex, std::ios::basefield);
|
||||
EIGEN_DEBUG_VAR(Derived::Flags)
|
||||
std::cerr.unsetf(std::ios::hex);
|
||||
EIGEN_DEBUG_VAR(InnerMaxSize)
|
||||
EIGEN_DEBUG_VAR(PacketSize)
|
||||
EIGEN_DEBUG_VAR(MightVectorize)
|
||||
EIGEN_DEBUG_VAR(MayLinearVectorize)
|
||||
EIGEN_DEBUG_VAR(MaySliceVectorize)
|
||||
EIGEN_DEBUG_VAR(Traversal)
|
||||
EIGEN_DEBUG_VAR(UnrollingLimit)
|
||||
EIGEN_DEBUG_VAR(Unrolling)
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
@@ -82,6 +101,7 @@ struct redux_novec_unroller
|
||||
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func& func)
|
||||
{
|
||||
return func(redux_novec_unroller<Func, Derived, Start, HalfLength>::run(mat,func),
|
||||
@@ -99,6 +119,7 @@ struct redux_novec_unroller<Func, Derived, Start, 1>
|
||||
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func&)
|
||||
{
|
||||
return mat.coeffByOuterInner(outer, inner);
|
||||
@@ -112,6 +133,7 @@ template<typename Func, typename Derived, int Start>
|
||||
struct redux_novec_unroller<Func, Derived, Start, 0>
|
||||
{
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
static EIGEN_STRONG_INLINE Scalar run(const Derived&, const Func&) { return Scalar(); }
|
||||
};
|
||||
|
||||
@@ -143,7 +165,7 @@ struct redux_vec_unroller<Func, Derived, Start, 1>
|
||||
index = Start * packet_traits<typename Derived::Scalar>::size,
|
||||
outer = index / int(Derived::InnerSizeAtCompileTime),
|
||||
inner = index % int(Derived::InnerSizeAtCompileTime),
|
||||
alignment = (Derived::Flags & AlignedBit) ? Aligned : Unaligned
|
||||
alignment = Derived::Alignment
|
||||
};
|
||||
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
@@ -151,7 +173,7 @@ struct redux_vec_unroller<Func, Derived, Start, 1>
|
||||
|
||||
static EIGEN_STRONG_INLINE PacketScalar run(const Derived &mat, const Func&)
|
||||
{
|
||||
return mat.template packetByOuterInner<alignment>(outer, inner);
|
||||
return mat.template packetByOuterInner<alignment,PacketScalar>(outer, inner);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -169,8 +191,8 @@ template<typename Func, typename Derived>
|
||||
struct redux_impl<Func, Derived, DefaultTraversal, NoUnrolling>
|
||||
{
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
typedef typename Derived::Index Index;
|
||||
static EIGEN_STRONG_INLINE Scalar run(const Derived& mat, const Func& func)
|
||||
EIGEN_DEVICE_FUNC
|
||||
static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func& func)
|
||||
{
|
||||
eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix");
|
||||
Scalar res;
|
||||
@@ -194,18 +216,18 @@ struct redux_impl<Func, Derived, LinearVectorizedTraversal, NoUnrolling>
|
||||
{
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
typedef typename packet_traits<Scalar>::type PacketScalar;
|
||||
typedef typename Derived::Index Index;
|
||||
|
||||
static Scalar run(const Derived& mat, const Func& func)
|
||||
static Scalar run(const Derived &mat, const Func& func)
|
||||
{
|
||||
const Index size = mat.size();
|
||||
eigen_assert(size && "you are using an empty matrix");
|
||||
|
||||
const Index packetSize = packet_traits<Scalar>::size;
|
||||
const Index alignedStart = internal::first_aligned(mat);
|
||||
const int packetAlignment = unpacket_traits<PacketScalar>::alignment;
|
||||
enum {
|
||||
alignment = bool(Derived::Flags & DirectAccessBit) || bool(Derived::Flags & AlignedBit)
|
||||
? Aligned : Unaligned
|
||||
alignment0 = (bool(Derived::Flags & DirectAccessBit) && bool(packet_traits<Scalar>::AlignedOnScalar)) ? int(packetAlignment) : int(Unaligned),
|
||||
alignment = EIGEN_PLAIN_ENUM_MAX(alignment0, Derived::Alignment)
|
||||
};
|
||||
const Index alignedStart = internal::first_default_aligned(mat.nestedExpression());
|
||||
const Index alignedSize2 = ((size-alignedStart)/(2*packetSize))*(2*packetSize);
|
||||
const Index alignedSize = ((size-alignedStart)/(packetSize))*(packetSize);
|
||||
const Index alignedEnd2 = alignedStart + alignedSize2;
|
||||
@@ -213,19 +235,19 @@ struct redux_impl<Func, Derived, LinearVectorizedTraversal, NoUnrolling>
|
||||
Scalar res;
|
||||
if(alignedSize)
|
||||
{
|
||||
PacketScalar packet_res0 = mat.template packet<alignment>(alignedStart);
|
||||
PacketScalar packet_res0 = mat.template packet<alignment,PacketScalar>(alignedStart);
|
||||
if(alignedSize>packetSize) // we have at least two packets to partly unroll the loop
|
||||
{
|
||||
PacketScalar packet_res1 = mat.template packet<alignment>(alignedStart+packetSize);
|
||||
PacketScalar packet_res1 = mat.template packet<alignment,PacketScalar>(alignedStart+packetSize);
|
||||
for(Index index = alignedStart + 2*packetSize; index < alignedEnd2; index += 2*packetSize)
|
||||
{
|
||||
packet_res0 = func.packetOp(packet_res0, mat.template packet<alignment>(index));
|
||||
packet_res1 = func.packetOp(packet_res1, mat.template packet<alignment>(index+packetSize));
|
||||
packet_res0 = func.packetOp(packet_res0, mat.template packet<alignment,PacketScalar>(index));
|
||||
packet_res1 = func.packetOp(packet_res1, mat.template packet<alignment,PacketScalar>(index+packetSize));
|
||||
}
|
||||
|
||||
packet_res0 = func.packetOp(packet_res0,packet_res1);
|
||||
if(alignedEnd>alignedEnd2)
|
||||
packet_res0 = func.packetOp(packet_res0, mat.template packet<alignment>(alignedEnd2));
|
||||
packet_res0 = func.packetOp(packet_res0, mat.template packet<alignment,PacketScalar>(alignedEnd2));
|
||||
}
|
||||
res = func.predux(packet_res0);
|
||||
|
||||
@@ -251,10 +273,9 @@ template<typename Func, typename Derived>
|
||||
struct redux_impl<Func, Derived, SliceVectorizedTraversal, NoUnrolling>
|
||||
{
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
typedef typename packet_traits<Scalar>::type PacketScalar;
|
||||
typedef typename Derived::Index Index;
|
||||
typedef typename packet_traits<Scalar>::type PacketType;
|
||||
|
||||
static Scalar run(const Derived& mat, const Func& func)
|
||||
EIGEN_DEVICE_FUNC static Scalar run(const Derived &mat, const Func& func)
|
||||
{
|
||||
eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix");
|
||||
const Index innerSize = mat.innerSize();
|
||||
@@ -266,10 +287,10 @@ struct redux_impl<Func, Derived, SliceVectorizedTraversal, NoUnrolling>
|
||||
Scalar res;
|
||||
if(packetedInnerSize)
|
||||
{
|
||||
PacketScalar packet_res = mat.template packet<Unaligned>(0,0);
|
||||
PacketType packet_res = mat.template packet<Unaligned,PacketType>(0,0);
|
||||
for(Index j=0; j<outerSize; ++j)
|
||||
for(Index i=(j==0?packetSize:0); i<packetedInnerSize; i+=Index(packetSize))
|
||||
packet_res = func.packetOp(packet_res, mat.template packetByOuterInner<Unaligned>(j,i));
|
||||
packet_res = func.packetOp(packet_res, mat.template packetByOuterInner<Unaligned,PacketType>(j,i));
|
||||
|
||||
res = func.predux(packet_res);
|
||||
for(Index j=0; j<outerSize; ++j)
|
||||
@@ -296,16 +317,83 @@ struct redux_impl<Func, Derived, LinearVectorizedTraversal, CompleteUnrolling>
|
||||
Size = Derived::SizeAtCompileTime,
|
||||
VectorizedSize = (Size / PacketSize) * PacketSize
|
||||
};
|
||||
static EIGEN_STRONG_INLINE Scalar run(const Derived& mat, const Func& func)
|
||||
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func& func)
|
||||
{
|
||||
eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix");
|
||||
Scalar res = func.predux(redux_vec_unroller<Func, Derived, 0, Size / PacketSize>::run(mat,func));
|
||||
if (VectorizedSize != Size)
|
||||
res = func(res,redux_novec_unroller<Func, Derived, VectorizedSize, Size-VectorizedSize>::run(mat,func));
|
||||
return res;
|
||||
if (VectorizedSize > 0) {
|
||||
Scalar res = func.predux(redux_vec_unroller<Func, Derived, 0, Size / PacketSize>::run(mat,func));
|
||||
if (VectorizedSize != Size)
|
||||
res = func(res,redux_novec_unroller<Func, Derived, VectorizedSize, Size-VectorizedSize>::run(mat,func));
|
||||
return res;
|
||||
}
|
||||
else {
|
||||
return redux_novec_unroller<Func, Derived, 0, Size>::run(mat,func);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// evaluator adaptor
|
||||
template<typename _XprType>
|
||||
class redux_evaluator
|
||||
{
|
||||
public:
|
||||
typedef _XprType XprType;
|
||||
EIGEN_DEVICE_FUNC explicit redux_evaluator(const XprType &xpr) : m_evaluator(xpr), m_xpr(xpr) {}
|
||||
|
||||
typedef typename XprType::Scalar Scalar;
|
||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||
typedef typename XprType::PacketScalar PacketScalar;
|
||||
typedef typename XprType::PacketReturnType PacketReturnType;
|
||||
|
||||
enum {
|
||||
MaxRowsAtCompileTime = XprType::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = XprType::MaxColsAtCompileTime,
|
||||
// TODO we should not remove DirectAccessBit and rather find an elegant way to query the alignment offset at runtime from the evaluator
|
||||
Flags = evaluator<XprType>::Flags & ~DirectAccessBit,
|
||||
IsRowMajor = XprType::IsRowMajor,
|
||||
SizeAtCompileTime = XprType::SizeAtCompileTime,
|
||||
InnerSizeAtCompileTime = XprType::InnerSizeAtCompileTime,
|
||||
CoeffReadCost = evaluator<XprType>::CoeffReadCost,
|
||||
Alignment = evaluator<XprType>::Alignment
|
||||
};
|
||||
|
||||
EIGEN_DEVICE_FUNC Index rows() const { return m_xpr.rows(); }
|
||||
EIGEN_DEVICE_FUNC Index cols() const { return m_xpr.cols(); }
|
||||
EIGEN_DEVICE_FUNC Index size() const { return m_xpr.size(); }
|
||||
EIGEN_DEVICE_FUNC Index innerSize() const { return m_xpr.innerSize(); }
|
||||
EIGEN_DEVICE_FUNC Index outerSize() const { return m_xpr.outerSize(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
CoeffReturnType coeff(Index row, Index col) const
|
||||
{ return m_evaluator.coeff(row, col); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
CoeffReturnType coeff(Index index) const
|
||||
{ return m_evaluator.coeff(index); }
|
||||
|
||||
template<int LoadMode, typename PacketType>
|
||||
PacketReturnType packet(Index row, Index col) const
|
||||
{ return m_evaluator.template packet<LoadMode,PacketType>(row, col); }
|
||||
|
||||
template<int LoadMode, typename PacketType>
|
||||
PacketReturnType packet(Index index) const
|
||||
{ return m_evaluator.template packet<LoadMode,PacketType>(index); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
CoeffReturnType coeffByOuterInner(Index outer, Index inner) const
|
||||
{ return m_evaluator.coeff(IsRowMajor ? outer : inner, IsRowMajor ? inner : outer); }
|
||||
|
||||
template<int LoadMode, typename PacketType>
|
||||
PacketReturnType packetByOuterInner(Index outer, Index inner) const
|
||||
{ return m_evaluator.template packet<LoadMode,PacketType>(IsRowMajor ? outer : inner, IsRowMajor ? inner : outer); }
|
||||
|
||||
const XprType & nestedExpression() const { return m_xpr; }
|
||||
|
||||
protected:
|
||||
internal::evaluator<XprType> m_evaluator;
|
||||
const XprType &m_xpr;
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
/***************************************************************************
|
||||
@@ -316,18 +404,31 @@ struct redux_impl<Func, Derived, LinearVectorizedTraversal, CompleteUnrolling>
|
||||
/** \returns the result of a full redux operation on the whole matrix or vector using \a func
|
||||
*
|
||||
* The template parameter \a BinaryOp is the type of the functor \a func which must be
|
||||
* an associative operator. Both current STL and TR1 functor styles are handled.
|
||||
* an associative operator. Both current C++98 and C++11 functor styles are handled.
|
||||
*
|
||||
* \sa DenseBase::sum(), DenseBase::minCoeff(), DenseBase::maxCoeff(), MatrixBase::colwise(), MatrixBase::rowwise()
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename Func>
|
||||
EIGEN_STRONG_INLINE typename internal::result_of<Func(typename internal::traits<Derived>::Scalar)>::type
|
||||
typename internal::traits<Derived>::Scalar
|
||||
DenseBase<Derived>::redux(const Func& func) const
|
||||
{
|
||||
typedef typename internal::remove_all<typename Derived::Nested>::type ThisNested;
|
||||
return internal::redux_impl<Func, ThisNested>
|
||||
::run(derived(), func);
|
||||
eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
|
||||
|
||||
// FIXME, eval_nest should be handled by redux_evaluator, however:
|
||||
// - it is currently difficult to provide the right Flags since they are still handled by the expressions
|
||||
// - handling it here might reduce the number of template instantiations
|
||||
// typedef typename internal::nested_eval<Derived,1>::type ThisNested;
|
||||
// typedef typename internal::remove_all<ThisNested>::type ThisNestedCleaned;
|
||||
// typedef typename internal::redux_evaluator<ThisNestedCleaned> ThisEvaluator;
|
||||
//
|
||||
// ThisNested thisNested(derived());
|
||||
// ThisEvaluator thisEval(thisNested);
|
||||
|
||||
typedef typename internal::redux_evaluator<Derived> ThisEvaluator;
|
||||
ThisEvaluator thisEval(derived());
|
||||
|
||||
return internal::redux_impl<Func, ThisEvaluator>::run(thisEval, func);
|
||||
}
|
||||
|
||||
/** \returns the minimum of all coefficients of \c *this.
|
||||
@@ -337,7 +438,7 @@ template<typename Derived>
|
||||
EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
||||
DenseBase<Derived>::minCoeff() const
|
||||
{
|
||||
return this->redux(Eigen::internal::scalar_min_op<Scalar>());
|
||||
return derived().redux(Eigen::internal::scalar_min_op<Scalar>());
|
||||
}
|
||||
|
||||
/** \returns the maximum of all coefficients of \c *this.
|
||||
@@ -347,7 +448,7 @@ template<typename Derived>
|
||||
EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
||||
DenseBase<Derived>::maxCoeff() const
|
||||
{
|
||||
return this->redux(Eigen::internal::scalar_max_op<Scalar>());
|
||||
return derived().redux(Eigen::internal::scalar_max_op<Scalar>());
|
||||
}
|
||||
|
||||
/** \returns the sum of all coefficients of *this
|
||||
@@ -360,7 +461,7 @@ DenseBase<Derived>::sum() const
|
||||
{
|
||||
if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
|
||||
return Scalar(0);
|
||||
return this->redux(Eigen::internal::scalar_sum_op<Scalar>());
|
||||
return derived().redux(Eigen::internal::scalar_sum_op<Scalar>());
|
||||
}
|
||||
|
||||
/** \returns the mean of all coefficients of *this
|
||||
@@ -371,7 +472,7 @@ template<typename Derived>
|
||||
EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
|
||||
DenseBase<Derived>::mean() const
|
||||
{
|
||||
return Scalar(this->redux(Eigen::internal::scalar_sum_op<Scalar>())) / Scalar(this->size());
|
||||
return Scalar(derived().redux(Eigen::internal::scalar_sum_op<Scalar>())) / Scalar(this->size());
|
||||
}
|
||||
|
||||
/** \returns the product of all coefficients of *this
|
||||
@@ -387,7 +488,7 @@ DenseBase<Derived>::prod() const
|
||||
{
|
||||
if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
|
||||
return Scalar(1);
|
||||
return this->redux(Eigen::internal::scalar_product_op<Scalar>());
|
||||
return derived().redux(Eigen::internal::scalar_product_op<Scalar>());
|
||||
}
|
||||
|
||||
/** \returns the trace of \c *this, i.e. the sum of the coefficients on the main diagonal.
|
||||
|
||||
@@ -12,24 +12,20 @@
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
template<typename Derived> class RefBase;
|
||||
template<typename PlainObjectType, int Options = 0,
|
||||
typename StrideType = typename internal::conditional<PlainObjectType::IsVectorAtCompileTime,InnerStride<1>,OuterStride<> >::type > class Ref;
|
||||
|
||||
/** \class Ref
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* \brief A matrix or vector expression mapping an existing expressions
|
||||
* \brief A matrix or vector expression mapping an existing expression
|
||||
*
|
||||
* \tparam PlainObjectType the equivalent matrix type of the mapped data
|
||||
* \tparam Options specifies whether the pointer is \c #Aligned, or \c #Unaligned.
|
||||
* \tparam MapOptions specifies the pointer alignment in bytes. It can be: \c #Aligned128, , \c #Aligned64, \c #Aligned32, \c #Aligned16, \c #Aligned8 or \c #Unaligned.
|
||||
* The default is \c #Unaligned.
|
||||
* \tparam StrideType optionally specifies strides. By default, Ref implies a contiguous storage along the inner dimension (inner stride==1),
|
||||
* but accept a variable outer stride (leading dimension).
|
||||
* but accepts a variable outer stride (leading dimension).
|
||||
* This can be overridden by specifying strides.
|
||||
* The type passed here must be a specialization of the Stride template, see examples below.
|
||||
*
|
||||
* This class permits to write non template functions taking Eigen's object as parameters while limiting the number of copies.
|
||||
* This class provides a way to write non-template functions taking Eigen objects as parameters while limiting the number of copies.
|
||||
* A Ref<> object can represent either a const expression or a l-value:
|
||||
* \code
|
||||
* // in-out argument:
|
||||
@@ -39,10 +35,10 @@ template<typename PlainObjectType, int Options = 0,
|
||||
* void foo2(const Ref<const VectorXf>& x);
|
||||
* \endcode
|
||||
*
|
||||
* In the in-out case, the input argument must satisfies the constraints of the actual Ref<> type, otherwise a compilation issue will be triggered.
|
||||
* In the in-out case, the input argument must satisfy the constraints of the actual Ref<> type, otherwise a compilation issue will be triggered.
|
||||
* By default, a Ref<VectorXf> can reference any dense vector expression of float having a contiguous memory layout.
|
||||
* Likewise, a Ref<MatrixXf> can reference any column major dense matrix expression of float whose column's elements are contiguously stored with
|
||||
* the possibility to have a constant space inbetween each column, i.e.: the inner stride mmust be equal to 1, but the outer-stride (or leading dimension),
|
||||
* Likewise, a Ref<MatrixXf> can reference any column-major dense matrix expression of float whose column's elements are contiguously stored with
|
||||
* the possibility to have a constant space in-between each column, i.e. the inner stride must be equal to 1, but the outer stride (or leading dimension)
|
||||
* can be greater than the number of rows.
|
||||
*
|
||||
* In the const case, if the input expression does not match the above requirement, then it is evaluated into a temporary before being passed to the function.
|
||||
@@ -52,21 +48,22 @@ template<typename PlainObjectType, int Options = 0,
|
||||
* VectorXf a;
|
||||
* foo1(a.head()); // OK
|
||||
* foo1(A.col()); // OK
|
||||
* foo1(A.row()); // compilation error because here innerstride!=1
|
||||
* foo2(A.row()); // The row is copied into a contiguous temporary
|
||||
* foo1(A.row()); // Compilation error because here innerstride!=1
|
||||
* foo2(A.row()); // Compilation error because A.row() is a 1xN object while foo2 is expecting a Nx1 object
|
||||
* foo2(A.row().transpose()); // The row is copied into a contiguous temporary
|
||||
* foo2(2*a); // The expression is evaluated into a temporary
|
||||
* foo2(A.col().segment(2,4)); // No temporary
|
||||
* \endcode
|
||||
*
|
||||
* The range of inputs that can be referenced without temporary can be enlarged using the last two template parameter.
|
||||
* The range of inputs that can be referenced without temporary can be enlarged using the last two template parameters.
|
||||
* Here is an example accepting an innerstride!=1:
|
||||
* \code
|
||||
* // in-out argument:
|
||||
* void foo3(Ref<VectorXf,0,InnerStride<> > x);
|
||||
* foo3(A.row()); // OK
|
||||
* \endcode
|
||||
* The downside here is that the function foo3 might be significantly slower than foo1 because it won't be able to exploit vectorization, and will involved more
|
||||
* expensive address computations even if the input is contiguously stored in memory. To overcome this issue, one might propose to overloads internally calling a
|
||||
* The downside here is that the function foo3 might be significantly slower than foo1 because it won't be able to exploit vectorization, and will involve more
|
||||
* expensive address computations even if the input is contiguously stored in memory. To overcome this issue, one might propose to overload internally calling a
|
||||
* template function, e.g.:
|
||||
* \code
|
||||
* // in the .h:
|
||||
@@ -94,24 +91,27 @@ struct traits<Ref<_PlainObjectType, _Options, _StrideType> >
|
||||
typedef _PlainObjectType PlainObjectType;
|
||||
typedef _StrideType StrideType;
|
||||
enum {
|
||||
Options = _Options
|
||||
Options = _Options,
|
||||
Flags = traits<Map<_PlainObjectType, _Options, _StrideType> >::Flags | NestByRefBit,
|
||||
Alignment = traits<Map<_PlainObjectType, _Options, _StrideType> >::Alignment
|
||||
};
|
||||
|
||||
template<typename Derived> struct match {
|
||||
enum {
|
||||
HasDirectAccess = internal::has_direct_access<Derived>::ret,
|
||||
StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)),
|
||||
StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)),
|
||||
InnerStrideMatch = int(StrideType::InnerStrideAtCompileTime)==int(Dynamic)
|
||||
|| int(StrideType::InnerStrideAtCompileTime)==int(Derived::InnerStrideAtCompileTime)
|
||||
|| (int(StrideType::InnerStrideAtCompileTime)==0 && int(Derived::InnerStrideAtCompileTime)==1),
|
||||
OuterStrideMatch = Derived::IsVectorAtCompileTime
|
||||
|| int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime),
|
||||
AlignmentMatch = (_Options!=Aligned) || ((PlainObjectType::Flags&AlignedBit)==0) || ((traits<Derived>::Flags&AlignedBit)==AlignedBit),
|
||||
MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch
|
||||
AlignmentMatch = (int(traits<PlainObjectType>::Alignment)==int(Unaligned)) || (int(evaluator<Derived>::Alignment) >= int(Alignment)), // FIXME the first condition is not very clear, it should be replaced by the required alignment
|
||||
ScalarTypeMatch = internal::is_same<typename PlainObjectType::Scalar, typename Derived::Scalar>::value,
|
||||
MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch && ScalarTypeMatch
|
||||
};
|
||||
typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type;
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
@@ -130,12 +130,12 @@ public:
|
||||
typedef MapBase<Derived> Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(RefBase)
|
||||
|
||||
inline Index innerStride() const
|
||||
EIGEN_DEVICE_FUNC inline Index innerStride() const
|
||||
{
|
||||
return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
|
||||
}
|
||||
|
||||
inline Index outerStride() const
|
||||
EIGEN_DEVICE_FUNC inline Index outerStride() const
|
||||
{
|
||||
return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
|
||||
: IsVectorAtCompileTime ? this->size()
|
||||
@@ -143,7 +143,7 @@ public:
|
||||
: this->rows();
|
||||
}
|
||||
|
||||
RefBase()
|
||||
EIGEN_DEVICE_FUNC RefBase()
|
||||
: Base(0,RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime),
|
||||
// Stride<> does not allow default ctor for Dynamic strides, so let' initialize it with dummy values:
|
||||
m_stride(StrideType::OuterStrideAtCompileTime==Dynamic?0:StrideType::OuterStrideAtCompileTime,
|
||||
@@ -157,7 +157,7 @@ protected:
|
||||
typedef Stride<StrideType::OuterStrideAtCompileTime,StrideType::InnerStrideAtCompileTime> StrideBase;
|
||||
|
||||
template<typename Expression>
|
||||
void construct(Expression& expr)
|
||||
EIGEN_DEVICE_FUNC void construct(Expression& expr)
|
||||
{
|
||||
if(PlainObjectType::RowsAtCompileTime==1)
|
||||
{
|
||||
@@ -171,8 +171,12 @@ protected:
|
||||
}
|
||||
else
|
||||
::new (static_cast<Base*>(this)) Base(expr.data(), expr.rows(), expr.cols());
|
||||
::new (&m_stride) StrideBase(StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(),
|
||||
StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride());
|
||||
|
||||
if(Expression::IsVectorAtCompileTime && (!PlainObjectType::IsVectorAtCompileTime) && ((Expression::Flags&RowMajorBit)!=(PlainObjectType::Flags&RowMajorBit)))
|
||||
::new (&m_stride) StrideBase(expr.innerStride(), StrideType::InnerStrideAtCompileTime==0?0:1);
|
||||
else
|
||||
::new (&m_stride) StrideBase(StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(),
|
||||
StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride());
|
||||
}
|
||||
|
||||
StrideBase m_stride;
|
||||
@@ -182,7 +186,11 @@ protected:
|
||||
template<typename PlainObjectType, int Options, typename StrideType> class Ref
|
||||
: public RefBase<Ref<PlainObjectType, Options, StrideType> >
|
||||
{
|
||||
private:
|
||||
typedef internal::traits<Ref> Traits;
|
||||
template<typename Derived>
|
||||
EIGEN_DEVICE_FUNC inline Ref(const PlainObjectBase<Derived>& expr,
|
||||
typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0);
|
||||
public:
|
||||
|
||||
typedef RefBase<Ref> Base;
|
||||
@@ -191,20 +199,23 @@ template<typename PlainObjectType, int Options, typename StrideType> class Ref
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
template<typename Derived>
|
||||
inline Ref(PlainObjectBase<Derived>& expr,
|
||||
typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
|
||||
EIGEN_DEVICE_FUNC inline Ref(PlainObjectBase<Derived>& expr,
|
||||
typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
|
||||
{
|
||||
Base::construct(expr);
|
||||
EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
|
||||
Base::construct(expr.derived());
|
||||
}
|
||||
template<typename Derived>
|
||||
inline Ref(const DenseBase<Derived>& expr,
|
||||
typename internal::enable_if<bool(internal::is_lvalue<Derived>::value&&bool(Traits::template match<Derived>::MatchAtCompileTime)),Derived>::type* = 0,
|
||||
int = Derived::ThisConstantIsPrivateInPlainObjectBase)
|
||||
EIGEN_DEVICE_FUNC inline Ref(const DenseBase<Derived>& expr,
|
||||
typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
|
||||
#else
|
||||
template<typename Derived>
|
||||
inline Ref(DenseBase<Derived>& expr)
|
||||
#endif
|
||||
{
|
||||
EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
|
||||
EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
|
||||
EIGEN_STATIC_ASSERT(!Derived::IsPlainObjectBase,THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
|
||||
Base::construct(expr.const_cast_derived());
|
||||
}
|
||||
|
||||
@@ -223,7 +234,8 @@ template<typename TPlainObjectType, int Options, typename StrideType> class Ref<
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
|
||||
|
||||
template<typename Derived>
|
||||
inline Ref(const DenseBase<Derived>& expr)
|
||||
EIGEN_DEVICE_FUNC inline Ref(const DenseBase<Derived>& expr,
|
||||
typename internal::enable_if<bool(Traits::template match<Derived>::ScalarTypeMatch),Derived>::type* = 0)
|
||||
{
|
||||
// std::cout << match_helper<Derived>::HasDirectAccess << "," << match_helper<Derived>::OuterStrideMatch << "," << match_helper<Derived>::InnerStrideMatch << "\n";
|
||||
// std::cout << int(StrideType::OuterStrideAtCompileTime) << " - " << int(Derived::OuterStrideAtCompileTime) << "\n";
|
||||
@@ -231,18 +243,27 @@ template<typename TPlainObjectType, int Options, typename StrideType> class Ref<
|
||||
construct(expr.derived(), typename Traits::template match<Derived>::type());
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC inline Ref(const Ref& other) : Base(other) {
|
||||
// copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy
|
||||
}
|
||||
|
||||
template<typename OtherRef>
|
||||
EIGEN_DEVICE_FUNC inline Ref(const RefBase<OtherRef>& other) {
|
||||
construct(other.derived(), typename Traits::template match<OtherRef>::type());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
template<typename Expression>
|
||||
void construct(const Expression& expr,internal::true_type)
|
||||
EIGEN_DEVICE_FUNC void construct(const Expression& expr,internal::true_type)
|
||||
{
|
||||
Base::construct(expr);
|
||||
}
|
||||
|
||||
template<typename Expression>
|
||||
void construct(const Expression& expr, internal::false_type)
|
||||
EIGEN_DEVICE_FUNC void construct(const Expression& expr, internal::false_type)
|
||||
{
|
||||
m_object.lazyAssign(expr);
|
||||
internal::call_assignment_no_alias(m_object,expr,internal::assign_op<Scalar>());
|
||||
Base::construct(m_object);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,10 +35,7 @@ struct traits<Replicate<MatrixType,RowFactor,ColFactor> >
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename traits<MatrixType>::StorageKind StorageKind;
|
||||
typedef typename traits<MatrixType>::XprKind XprKind;
|
||||
enum {
|
||||
Factor = (RowFactor==Dynamic || ColFactor==Dynamic) ? Dynamic : RowFactor*ColFactor
|
||||
};
|
||||
typedef typename nested<MatrixType,Factor>::type MatrixTypeNested;
|
||||
typedef typename ref_selector<MatrixType>::type MatrixTypeNested;
|
||||
typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
|
||||
enum {
|
||||
RowsAtCompileTime = RowFactor==Dynamic || int(MatrixType::RowsAtCompileTime)==Dynamic
|
||||
@@ -53,8 +50,9 @@ struct traits<Replicate<MatrixType,RowFactor,ColFactor> >
|
||||
IsRowMajor = MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1 ? 1
|
||||
: MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1 ? 0
|
||||
: (MatrixType::Flags & RowMajorBit) ? 1 : 0,
|
||||
Flags = (_MatrixTypeNested::Flags & HereditaryBits & ~RowMajorBit) | (IsRowMajor ? RowMajorBit : 0),
|
||||
CoeffReadCost = _MatrixTypeNested::CoeffReadCost
|
||||
|
||||
// FIXME enable DirectAccess with negative strides?
|
||||
Flags = IsRowMajor ? RowMajorBit : 0
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -68,10 +66,12 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
|
||||
|
||||
typedef typename internal::dense_xpr_base<Replicate>::type Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Replicate)
|
||||
typedef typename internal::remove_all<MatrixType>::type NestedExpression;
|
||||
|
||||
template<typename OriginalMatrixType>
|
||||
inline explicit Replicate(const OriginalMatrixType& a_matrix)
|
||||
: m_matrix(a_matrix), m_rowFactor(RowFactor), m_colFactor(ColFactor)
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline explicit Replicate(const OriginalMatrixType& matrix)
|
||||
: m_matrix(matrix), m_rowFactor(RowFactor), m_colFactor(ColFactor)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT((internal::is_same<typename internal::remove_const<MatrixType>::type,OriginalMatrixType>::value),
|
||||
THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
|
||||
@@ -79,41 +79,20 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
|
||||
}
|
||||
|
||||
template<typename OriginalMatrixType>
|
||||
inline Replicate(const OriginalMatrixType& a_matrix, Index rowFactor, Index colFactor)
|
||||
: m_matrix(a_matrix), m_rowFactor(rowFactor), m_colFactor(colFactor)
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Replicate(const OriginalMatrixType& matrix, Index rowFactor, Index colFactor)
|
||||
: m_matrix(matrix), m_rowFactor(rowFactor), m_colFactor(colFactor)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT((internal::is_same<typename internal::remove_const<MatrixType>::type,OriginalMatrixType>::value),
|
||||
THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index rows() const { return m_matrix.rows() * m_rowFactor.value(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index cols() const { return m_matrix.cols() * m_colFactor.value(); }
|
||||
|
||||
inline Scalar coeff(Index rowId, Index colId) const
|
||||
{
|
||||
// try to avoid using modulo; this is a pure optimization strategy
|
||||
const Index actual_row = internal::traits<MatrixType>::RowsAtCompileTime==1 ? 0
|
||||
: RowFactor==1 ? rowId
|
||||
: rowId%m_matrix.rows();
|
||||
const Index actual_col = internal::traits<MatrixType>::ColsAtCompileTime==1 ? 0
|
||||
: ColFactor==1 ? colId
|
||||
: colId%m_matrix.cols();
|
||||
|
||||
return m_matrix.coeff(actual_row, actual_col);
|
||||
}
|
||||
template<int LoadMode>
|
||||
inline PacketScalar packet(Index rowId, Index colId) const
|
||||
{
|
||||
const Index actual_row = internal::traits<MatrixType>::RowsAtCompileTime==1 ? 0
|
||||
: RowFactor==1 ? rowId
|
||||
: rowId%m_matrix.rows();
|
||||
const Index actual_col = internal::traits<MatrixType>::ColsAtCompileTime==1 ? 0
|
||||
: ColFactor==1 ? colId
|
||||
: colId%m_matrix.cols();
|
||||
|
||||
return m_matrix.template packet<LoadMode>(actual_row, actual_col);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
const _MatrixTypeNested& nestedExpression() const
|
||||
{
|
||||
return m_matrix;
|
||||
@@ -135,27 +114,12 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<int RowFactor, int ColFactor>
|
||||
inline const Replicate<Derived,RowFactor,ColFactor>
|
||||
const Replicate<Derived,RowFactor,ColFactor>
|
||||
DenseBase<Derived>::replicate() const
|
||||
{
|
||||
return Replicate<Derived,RowFactor,ColFactor>(derived());
|
||||
}
|
||||
|
||||
/**
|
||||
* \return an expression of the replication of \c *this
|
||||
*
|
||||
* Example: \include MatrixBase_replicate_int_int.cpp
|
||||
* Output: \verbinclude MatrixBase_replicate_int_int.out
|
||||
*
|
||||
* \sa VectorwiseOp::replicate(), DenseBase::replicate<int,int>(), class Replicate
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline const Replicate<Derived,Dynamic,Dynamic>
|
||||
DenseBase<Derived>::replicate(Index rowFactor,Index colFactor) const
|
||||
{
|
||||
return Replicate<Derived,Dynamic,Dynamic>(derived(),rowFactor,colFactor);
|
||||
}
|
||||
|
||||
/**
|
||||
* \return an expression of the replication of each column (or row) of \c *this
|
||||
*
|
||||
|
||||
@@ -38,9 +38,10 @@ struct traits<ReturnByValue<Derived> >
|
||||
* So internal::nested always gives the plain return matrix type.
|
||||
*
|
||||
* FIXME: I don't understand why we need this specialization: isn't this taken care of by the EvalBeforeNestingBit ??
|
||||
* Answer: EvalBeforeNestingBit should be deprecated since we have the evaluators
|
||||
*/
|
||||
template<typename Derived,int n,typename PlainObject>
|
||||
struct nested<ReturnByValue<Derived>, n, PlainObject>
|
||||
struct nested_eval<ReturnByValue<Derived>, n, PlainObject>
|
||||
{
|
||||
typedef typename traits<Derived>::ReturnType type;
|
||||
};
|
||||
@@ -48,7 +49,7 @@ struct nested<ReturnByValue<Derived>, n, PlainObject>
|
||||
} // end namespace internal
|
||||
|
||||
template<typename Derived> class ReturnByValue
|
||||
: internal::no_assignment_operator, public internal::dense_xpr_base< ReturnByValue<Derived> >::type
|
||||
: public internal::dense_xpr_base< ReturnByValue<Derived> >::type, internal::no_assignment_operator
|
||||
{
|
||||
public:
|
||||
typedef typename internal::traits<Derived>::ReturnType ReturnType;
|
||||
@@ -57,10 +58,11 @@ template<typename Derived> class ReturnByValue
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(ReturnByValue)
|
||||
|
||||
template<typename Dest>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline void evalTo(Dest& dst) const
|
||||
{ static_cast<const Derived*>(this)->evalTo(dst); }
|
||||
inline Index rows() const { return static_cast<const Derived*>(this)->rows(); }
|
||||
inline Index cols() const { return static_cast<const Derived*>(this)->cols(); }
|
||||
EIGEN_DEVICE_FUNC inline Index rows() const { return static_cast<const Derived*>(this)->rows(); }
|
||||
EIGEN_DEVICE_FUNC inline Index cols() const { return static_cast<const Derived*>(this)->cols(); }
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
#define Unusable YOU_ARE_TRYING_TO_ACCESS_A_SINGLE_COEFFICIENT_IN_A_SPECIAL_EXPRESSION_WHERE_THAT_IS_NOT_ALLOWED_BECAUSE_THAT_WOULD_BE_INEFFICIENT
|
||||
@@ -72,6 +74,7 @@ template<typename Derived> class ReturnByValue
|
||||
const Unusable& coeff(Index,Index) const { return *reinterpret_cast<const Unusable*>(this); }
|
||||
Unusable& coeffRef(Index) { return *reinterpret_cast<Unusable*>(this); }
|
||||
Unusable& coeffRef(Index,Index) { return *reinterpret_cast<Unusable*>(this); }
|
||||
#undef Unusable
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -83,6 +86,33 @@ Derived& DenseBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
|
||||
return derived();
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Expression is evaluated in a temporary; default implementation of Assignment is bypassed so that
|
||||
// when a ReturnByValue expression is assigned, the evaluator is not constructed.
|
||||
// TODO: Finalize port to new regime; ReturnByValue should not exist in the expression world
|
||||
|
||||
template<typename Derived>
|
||||
struct evaluator<ReturnByValue<Derived> >
|
||||
: public evaluator<typename internal::traits<Derived>::ReturnType>
|
||||
{
|
||||
typedef ReturnByValue<Derived> XprType;
|
||||
typedef typename internal::traits<Derived>::ReturnType PlainObject;
|
||||
typedef evaluator<PlainObject> Base;
|
||||
|
||||
EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr)
|
||||
: m_result(xpr.rows(), xpr.cols())
|
||||
{
|
||||
::new (static_cast<Base*>(this)) Base(m_result);
|
||||
xpr.evalTo(m_result);
|
||||
}
|
||||
|
||||
protected:
|
||||
PlainObject m_result;
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_RETURNBYVALUE_H
|
||||
|
||||
@@ -37,32 +37,25 @@ struct traits<Reverse<MatrixType, Direction> >
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename traits<MatrixType>::StorageKind StorageKind;
|
||||
typedef typename traits<MatrixType>::XprKind XprKind;
|
||||
typedef typename nested<MatrixType>::type MatrixTypeNested;
|
||||
typedef typename ref_selector<MatrixType>::type MatrixTypeNested;
|
||||
typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
|
||||
enum {
|
||||
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
|
||||
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
|
||||
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
|
||||
|
||||
// let's enable LinearAccess only with vectorization because of the product overhead
|
||||
LinearAccess = ( (Direction==BothDirections) && (int(_MatrixTypeNested::Flags)&PacketAccessBit) )
|
||||
? LinearAccessBit : 0,
|
||||
|
||||
Flags = int(_MatrixTypeNested::Flags) & (HereditaryBits | LvalueBit | PacketAccessBit | LinearAccess),
|
||||
|
||||
CoeffReadCost = _MatrixTypeNested::CoeffReadCost
|
||||
Flags = _MatrixTypeNested::Flags & (RowMajorBit | LvalueBit)
|
||||
};
|
||||
};
|
||||
|
||||
template<typename PacketScalar, bool ReversePacket> struct reverse_packet_cond
|
||||
template<typename PacketType, bool ReversePacket> struct reverse_packet_cond
|
||||
{
|
||||
static inline PacketScalar run(const PacketScalar& x) { return preverse(x); }
|
||||
static inline PacketType run(const PacketType& x) { return preverse(x); }
|
||||
};
|
||||
|
||||
template<typename PacketScalar> struct reverse_packet_cond<PacketScalar,false>
|
||||
template<typename PacketType> struct reverse_packet_cond<PacketType,false>
|
||||
{
|
||||
static inline PacketScalar run(const PacketScalar& x) { return x; }
|
||||
static inline PacketType run(const PacketType& x) { return x; }
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
@@ -74,12 +67,9 @@ template<typename MatrixType, int Direction> class Reverse
|
||||
|
||||
typedef typename internal::dense_xpr_base<Reverse>::type Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Reverse)
|
||||
typedef typename internal::remove_all<MatrixType>::type NestedExpression;
|
||||
using Base::IsRowMajor;
|
||||
|
||||
// next line is necessary because otherwise const version of operator()
|
||||
// is hidden by non-const version defined in this file
|
||||
using Base::operator();
|
||||
|
||||
protected:
|
||||
enum {
|
||||
PacketSize = internal::packet_traits<Scalar>::size,
|
||||
@@ -95,82 +85,19 @@ template<typename MatrixType, int Direction> class Reverse
|
||||
typedef internal::reverse_packet_cond<PacketScalar,ReversePacket> reverse_packet;
|
||||
public:
|
||||
|
||||
inline Reverse(const MatrixType& matrix) : m_matrix(matrix) { }
|
||||
EIGEN_DEVICE_FUNC explicit inline Reverse(const MatrixType& matrix) : m_matrix(matrix) { }
|
||||
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse)
|
||||
|
||||
inline Index rows() const { return m_matrix.rows(); }
|
||||
inline Index cols() const { return m_matrix.cols(); }
|
||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_matrix.rows(); }
|
||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_matrix.cols(); }
|
||||
|
||||
inline Index innerStride() const
|
||||
EIGEN_DEVICE_FUNC inline Index innerStride() const
|
||||
{
|
||||
return -m_matrix.innerStride();
|
||||
}
|
||||
|
||||
inline Scalar& operator()(Index row, Index col)
|
||||
{
|
||||
eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
|
||||
return coeffRef(row, col);
|
||||
}
|
||||
|
||||
inline Scalar& coeffRef(Index row, Index col)
|
||||
{
|
||||
return m_matrix.const_cast_derived().coeffRef(ReverseRow ? m_matrix.rows() - row - 1 : row,
|
||||
ReverseCol ? m_matrix.cols() - col - 1 : col);
|
||||
}
|
||||
|
||||
inline CoeffReturnType coeff(Index row, Index col) const
|
||||
{
|
||||
return m_matrix.coeff(ReverseRow ? m_matrix.rows() - row - 1 : row,
|
||||
ReverseCol ? m_matrix.cols() - col - 1 : col);
|
||||
}
|
||||
|
||||
inline CoeffReturnType coeff(Index index) const
|
||||
{
|
||||
return m_matrix.coeff(m_matrix.size() - index - 1);
|
||||
}
|
||||
|
||||
inline Scalar& coeffRef(Index index)
|
||||
{
|
||||
return m_matrix.const_cast_derived().coeffRef(m_matrix.size() - index - 1);
|
||||
}
|
||||
|
||||
inline Scalar& operator()(Index index)
|
||||
{
|
||||
eigen_assert(index >= 0 && index < m_matrix.size());
|
||||
return coeffRef(index);
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
inline const PacketScalar packet(Index row, Index col) const
|
||||
{
|
||||
return reverse_packet::run(m_matrix.template packet<LoadMode>(
|
||||
ReverseRow ? m_matrix.rows() - row - OffsetRow : row,
|
||||
ReverseCol ? m_matrix.cols() - col - OffsetCol : col));
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
inline void writePacket(Index row, Index col, const PacketScalar& x)
|
||||
{
|
||||
m_matrix.const_cast_derived().template writePacket<LoadMode>(
|
||||
ReverseRow ? m_matrix.rows() - row - OffsetRow : row,
|
||||
ReverseCol ? m_matrix.cols() - col - OffsetCol : col,
|
||||
reverse_packet::run(x));
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
inline const PacketScalar packet(Index index) const
|
||||
{
|
||||
return internal::preverse(m_matrix.template packet<LoadMode>( m_matrix.size() - index - PacketSize ));
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
inline void writePacket(Index index, const PacketScalar& x)
|
||||
{
|
||||
m_matrix.const_cast_derived().template writePacket<LoadMode>(m_matrix.size() - index - PacketSize, internal::preverse(x));
|
||||
}
|
||||
|
||||
const typename internal::remove_all<typename MatrixType::Nested>::type&
|
||||
EIGEN_DEVICE_FUNC const typename internal::remove_all<typename MatrixType::Nested>::type&
|
||||
nestedExpression() const
|
||||
{
|
||||
return m_matrix;
|
||||
@@ -190,33 +117,93 @@ template<typename Derived>
|
||||
inline typename DenseBase<Derived>::ReverseReturnType
|
||||
DenseBase<Derived>::reverse()
|
||||
{
|
||||
return derived();
|
||||
return ReverseReturnType(derived());
|
||||
}
|
||||
|
||||
/** This is the const version of reverse(). */
|
||||
template<typename Derived>
|
||||
inline const typename DenseBase<Derived>::ConstReverseReturnType
|
||||
DenseBase<Derived>::reverse() const
|
||||
{
|
||||
return derived();
|
||||
}
|
||||
|
||||
//reverse const overload moved DenseBase.h due to a CUDA compiler bug
|
||||
|
||||
/** This is the "in place" version of reverse: it reverses \c *this.
|
||||
*
|
||||
* In most cases it is probably better to simply use the reversed expression
|
||||
* of a matrix. However, when reversing the matrix data itself is really needed,
|
||||
* then this "in-place" version is probably the right choice because it provides
|
||||
* the following additional features:
|
||||
* the following additional benefits:
|
||||
* - less error prone: doing the same operation with .reverse() requires special care:
|
||||
* \code m = m.reverse().eval(); \endcode
|
||||
* - this API allows to avoid creating a temporary (the current implementation creates a temporary, but that could be avoided using swap)
|
||||
* - this API enables reverse operations without the need for a temporary
|
||||
* - it allows future optimizations (cache friendliness, etc.)
|
||||
*
|
||||
* \sa reverse() */
|
||||
* \sa VectorwiseOp::reverseInPlace(), reverse() */
|
||||
template<typename Derived>
|
||||
inline void DenseBase<Derived>::reverseInPlace()
|
||||
{
|
||||
derived() = derived().reverse().eval();
|
||||
if(cols()>rows())
|
||||
{
|
||||
Index half = cols()/2;
|
||||
leftCols(half).swap(rightCols(half).reverse());
|
||||
if((cols()%2)==1)
|
||||
{
|
||||
Index half2 = rows()/2;
|
||||
col(half).head(half2).swap(col(half).tail(half2).reverse());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Index half = rows()/2;
|
||||
topRows(half).swap(bottomRows(half).reverse());
|
||||
if((rows()%2)==1)
|
||||
{
|
||||
Index half2 = cols()/2;
|
||||
row(half).head(half2).swap(row(half).tail(half2).reverse());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<int Direction>
|
||||
struct vectorwise_reverse_inplace_impl;
|
||||
|
||||
template<>
|
||||
struct vectorwise_reverse_inplace_impl<Vertical>
|
||||
{
|
||||
template<typename ExpressionType>
|
||||
static void run(ExpressionType &xpr)
|
||||
{
|
||||
Index half = xpr.rows()/2;
|
||||
xpr.topRows(half).swap(xpr.bottomRows(half).colwise().reverse());
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct vectorwise_reverse_inplace_impl<Horizontal>
|
||||
{
|
||||
template<typename ExpressionType>
|
||||
static void run(ExpressionType &xpr)
|
||||
{
|
||||
Index half = xpr.cols()/2;
|
||||
xpr.leftCols(half).swap(xpr.rightCols(half).rowwise().reverse());
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
/** This is the "in place" version of VectorwiseOp::reverse: it reverses each column or row of \c *this.
|
||||
*
|
||||
* In most cases it is probably better to simply use the reversed expression
|
||||
* of a matrix. However, when reversing the matrix data itself is really needed,
|
||||
* then this "in-place" version is probably the right choice because it provides
|
||||
* the following additional benefits:
|
||||
* - less error prone: doing the same operation with .reverse() requires special care:
|
||||
* \code m = m.reverse().eval(); \endcode
|
||||
* - this API enables reverse operations without the need for a temporary
|
||||
*
|
||||
* \sa DenseBase::reverseInPlace(), reverse() */
|
||||
template<typename ExpressionType, int Direction>
|
||||
void VectorwiseOp<ExpressionType,Direction>::reverseInPlace()
|
||||
{
|
||||
internal::vectorwise_reverse_inplace_impl<Direction>::run(_expression().const_cast_derived());
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -43,23 +43,21 @@ struct traits<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
|
||||
ColsAtCompileTime = ConditionMatrixType::ColsAtCompileTime,
|
||||
MaxRowsAtCompileTime = ConditionMatrixType::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = ConditionMatrixType::MaxColsAtCompileTime,
|
||||
Flags = (unsigned int)ThenMatrixType::Flags & ElseMatrixType::Flags & HereditaryBits,
|
||||
CoeffReadCost = traits<typename remove_all<ConditionMatrixNested>::type>::CoeffReadCost
|
||||
+ EIGEN_SIZE_MAX(traits<typename remove_all<ThenMatrixNested>::type>::CoeffReadCost,
|
||||
traits<typename remove_all<ElseMatrixNested>::type>::CoeffReadCost)
|
||||
Flags = (unsigned int)ThenMatrixType::Flags & ElseMatrixType::Flags & RowMajorBit
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType>
|
||||
class Select : internal::no_assignment_operator,
|
||||
public internal::dense_xpr_base< Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >::type
|
||||
class Select : public internal::dense_xpr_base< Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >::type,
|
||||
internal::no_assignment_operator
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename internal::dense_xpr_base<Select>::type Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Select)
|
||||
|
||||
inline EIGEN_DEVICE_FUNC
|
||||
Select(const ConditionMatrixType& a_conditionMatrix,
|
||||
const ThenMatrixType& a_thenMatrix,
|
||||
const ElseMatrixType& a_elseMatrix)
|
||||
@@ -69,9 +67,10 @@ class Select : internal::no_assignment_operator,
|
||||
eigen_assert(m_condition.cols() == m_then.cols() && m_condition.cols() == m_else.cols());
|
||||
}
|
||||
|
||||
Index rows() const { return m_condition.rows(); }
|
||||
Index cols() const { return m_condition.cols(); }
|
||||
inline EIGEN_DEVICE_FUNC Index rows() const { return m_condition.rows(); }
|
||||
inline EIGEN_DEVICE_FUNC Index cols() const { return m_condition.cols(); }
|
||||
|
||||
inline EIGEN_DEVICE_FUNC
|
||||
const Scalar coeff(Index i, Index j) const
|
||||
{
|
||||
if (m_condition.coeff(i,j))
|
||||
@@ -80,6 +79,7 @@ class Select : internal::no_assignment_operator,
|
||||
return m_else.coeff(i,j);
|
||||
}
|
||||
|
||||
inline EIGEN_DEVICE_FUNC
|
||||
const Scalar coeff(Index i) const
|
||||
{
|
||||
if (m_condition.coeff(i))
|
||||
@@ -88,17 +88,17 @@ class Select : internal::no_assignment_operator,
|
||||
return m_else.coeff(i);
|
||||
}
|
||||
|
||||
const ConditionMatrixType& conditionMatrix() const
|
||||
inline EIGEN_DEVICE_FUNC const ConditionMatrixType& conditionMatrix() const
|
||||
{
|
||||
return m_condition;
|
||||
}
|
||||
|
||||
const ThenMatrixType& thenMatrix() const
|
||||
inline EIGEN_DEVICE_FUNC const ThenMatrixType& thenMatrix() const
|
||||
{
|
||||
return m_then;
|
||||
}
|
||||
|
||||
const ElseMatrixType& elseMatrix() const
|
||||
inline EIGEN_DEVICE_FUNC const ElseMatrixType& elseMatrix() const
|
||||
{
|
||||
return m_else;
|
||||
}
|
||||
|
||||
@@ -32,54 +32,57 @@ namespace internal {
|
||||
template<typename MatrixType, unsigned int UpLo>
|
||||
struct traits<SelfAdjointView<MatrixType, UpLo> > : traits<MatrixType>
|
||||
{
|
||||
typedef typename nested<MatrixType>::type MatrixTypeNested;
|
||||
typedef typename ref_selector<MatrixType>::type MatrixTypeNested;
|
||||
typedef typename remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned;
|
||||
typedef MatrixType ExpressionType;
|
||||
typedef typename MatrixType::PlainObject DenseMatrixType;
|
||||
typedef typename MatrixType::PlainObject FullMatrixType;
|
||||
enum {
|
||||
Mode = UpLo | SelfAdjoint,
|
||||
Flags = MatrixTypeNestedCleaned::Flags & (HereditaryBits)
|
||||
& (~(PacketAccessBit | DirectAccessBit | LinearAccessBit)), // FIXME these flags should be preserved
|
||||
CoeffReadCost = MatrixTypeNestedCleaned::CoeffReadCost
|
||||
FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
|
||||
Flags = MatrixTypeNestedCleaned::Flags & (HereditaryBits|FlagsLvalueBit)
|
||||
& (~(PacketAccessBit | DirectAccessBit | LinearAccessBit)) // FIXME these flags should be preserved
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
template <typename Lhs, int LhsMode, bool LhsIsVector,
|
||||
typename Rhs, int RhsMode, bool RhsIsVector>
|
||||
struct SelfadjointProductMatrix;
|
||||
|
||||
// FIXME could also be called SelfAdjointWrapper to be consistent with DiagonalWrapper ??
|
||||
template<typename MatrixType, unsigned int UpLo> class SelfAdjointView
|
||||
: public TriangularBase<SelfAdjointView<MatrixType, UpLo> >
|
||||
template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
|
||||
: public TriangularBase<SelfAdjointView<_MatrixType, UpLo> >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef _MatrixType MatrixType;
|
||||
typedef TriangularBase<SelfAdjointView> Base;
|
||||
typedef typename internal::traits<SelfAdjointView>::MatrixTypeNested MatrixTypeNested;
|
||||
typedef typename internal::traits<SelfAdjointView>::MatrixTypeNestedCleaned MatrixTypeNestedCleaned;
|
||||
|
||||
/** \brief The type of coefficients in this matrix */
|
||||
typedef typename internal::traits<SelfAdjointView>::Scalar Scalar;
|
||||
|
||||
typedef typename MatrixType::Index Index;
|
||||
typedef typename MatrixType::StorageIndex StorageIndex;
|
||||
|
||||
enum {
|
||||
Mode = internal::traits<SelfAdjointView>::Mode
|
||||
Mode = internal::traits<SelfAdjointView>::Mode,
|
||||
Flags = internal::traits<SelfAdjointView>::Flags
|
||||
};
|
||||
typedef typename MatrixType::PlainObject PlainObject;
|
||||
|
||||
inline SelfAdjointView(MatrixType& matrix) : m_matrix(matrix)
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit inline SelfAdjointView(MatrixType& matrix) : m_matrix(matrix)
|
||||
{}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index rows() const { return m_matrix.rows(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index cols() const { return m_matrix.cols(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index outerStride() const { return m_matrix.outerStride(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index innerStride() const { return m_matrix.innerStride(); }
|
||||
|
||||
/** \sa MatrixBase::coeff()
|
||||
* \warning the coordinates must fit into the referenced triangular part
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Scalar coeff(Index row, Index col) const
|
||||
{
|
||||
Base::check_coordinates_internal(row, col);
|
||||
@@ -89,36 +92,46 @@ template<typename MatrixType, unsigned int UpLo> class SelfAdjointView
|
||||
/** \sa MatrixBase::coeffRef()
|
||||
* \warning the coordinates must fit into the referenced triangular part
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Scalar& coeffRef(Index row, Index col)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_LVALUE(SelfAdjointView);
|
||||
Base::check_coordinates_internal(row, col);
|
||||
return m_matrix.const_cast_derived().coeffRef(row, col);
|
||||
}
|
||||
|
||||
/** \internal */
|
||||
EIGEN_DEVICE_FUNC
|
||||
const MatrixTypeNestedCleaned& _expression() const { return m_matrix; }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
const MatrixTypeNestedCleaned& nestedExpression() const { return m_matrix; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
MatrixTypeNestedCleaned& nestedExpression() { return *const_cast<MatrixTypeNestedCleaned*>(&m_matrix); }
|
||||
|
||||
/** Efficient self-adjoint matrix times vector/matrix product */
|
||||
/** Efficient triangular matrix times vector/matrix product */
|
||||
template<typename OtherDerived>
|
||||
SelfadjointProductMatrix<MatrixType,Mode,false,OtherDerived,0,OtherDerived::IsVectorAtCompileTime>
|
||||
EIGEN_DEVICE_FUNC
|
||||
const Product<SelfAdjointView,OtherDerived>
|
||||
operator*(const MatrixBase<OtherDerived>& rhs) const
|
||||
{
|
||||
return SelfadjointProductMatrix
|
||||
<MatrixType,Mode,false,OtherDerived,0,OtherDerived::IsVectorAtCompileTime>
|
||||
(m_matrix, rhs.derived());
|
||||
return Product<SelfAdjointView,OtherDerived>(*this, rhs.derived());
|
||||
}
|
||||
|
||||
/** Efficient vector/matrix times self-adjoint matrix product */
|
||||
/** Efficient vector/matrix times triangular matrix product */
|
||||
template<typename OtherDerived> friend
|
||||
SelfadjointProductMatrix<OtherDerived,0,OtherDerived::IsVectorAtCompileTime,MatrixType,Mode,false>
|
||||
EIGEN_DEVICE_FUNC
|
||||
const Product<OtherDerived,SelfAdjointView>
|
||||
operator*(const MatrixBase<OtherDerived>& lhs, const SelfAdjointView& rhs)
|
||||
{
|
||||
return SelfadjointProductMatrix
|
||||
<OtherDerived,0,OtherDerived::IsVectorAtCompileTime,MatrixType,Mode,false>
|
||||
(lhs.derived(),rhs.m_matrix);
|
||||
return Product<OtherDerived,SelfAdjointView>(lhs.derived(),rhs);
|
||||
}
|
||||
|
||||
friend EIGEN_DEVICE_FUNC
|
||||
const SelfAdjointView<const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,MatrixType>,UpLo>
|
||||
operator*(const Scalar& s, const SelfAdjointView& mat)
|
||||
{
|
||||
return (s*mat.nestedExpression()).template selfadjointView<UpLo>();
|
||||
}
|
||||
|
||||
/** Perform a symmetric rank 2 update of the selfadjoint matrix \c *this:
|
||||
@@ -132,6 +145,7 @@ template<typename MatrixType, unsigned int UpLo> class SelfAdjointView
|
||||
* \sa rankUpdate(const MatrixBase<DerivedU>&, Scalar)
|
||||
*/
|
||||
template<typename DerivedU, typename DerivedV>
|
||||
EIGEN_DEVICE_FUNC
|
||||
SelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, const MatrixBase<DerivedV>& v, const Scalar& alpha = Scalar(1));
|
||||
|
||||
/** Perform a symmetric rank K update of the selfadjoint matrix \c *this:
|
||||
@@ -145,6 +159,7 @@ template<typename MatrixType, unsigned int UpLo> class SelfAdjointView
|
||||
* \sa rankUpdate(const MatrixBase<DerivedU>&, const MatrixBase<DerivedV>&, Scalar)
|
||||
*/
|
||||
template<typename DerivedU>
|
||||
EIGEN_DEVICE_FUNC
|
||||
SelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, const Scalar& alpha = Scalar(1));
|
||||
|
||||
/////////// Cholesky module ///////////
|
||||
@@ -159,31 +174,10 @@ template<typename MatrixType, unsigned int UpLo> class SelfAdjointView
|
||||
/** Return type of eigenvalues() */
|
||||
typedef Matrix<RealScalar, internal::traits<MatrixType>::ColsAtCompileTime, 1> EigenvaluesReturnType;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EigenvaluesReturnType eigenvalues() const;
|
||||
EIGEN_DEVICE_FUNC
|
||||
RealScalar operatorNorm() const;
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
template<typename OtherDerived>
|
||||
SelfAdjointView& operator=(const MatrixBase<OtherDerived>& other)
|
||||
{
|
||||
enum {
|
||||
OtherPart = UpLo == Upper ? StrictlyLower : StrictlyUpper
|
||||
};
|
||||
m_matrix.const_cast_derived().template triangularView<UpLo>() = other;
|
||||
m_matrix.const_cast_derived().template triangularView<OtherPart>() = other.adjoint();
|
||||
return *this;
|
||||
}
|
||||
template<typename OtherMatrixType, unsigned int OtherMode>
|
||||
SelfAdjointView& operator=(const TriangularView<OtherMatrixType, OtherMode>& other)
|
||||
{
|
||||
enum {
|
||||
OtherPart = UpLo == Upper ? StrictlyLower : StrictlyUpper
|
||||
};
|
||||
m_matrix.const_cast_derived().template triangularView<UpLo>() = other.toDenseMatrix();
|
||||
m_matrix.const_cast_derived().template triangularView<OtherPart>() = other.toDenseMatrix().adjoint();
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
MatrixTypeNested m_matrix;
|
||||
@@ -201,90 +195,56 @@ template<typename MatrixType, unsigned int UpLo> class SelfAdjointView
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename Derived1, typename Derived2, int UnrollCount, bool ClearOpposite>
|
||||
struct triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Upper), UnrollCount, ClearOpposite>
|
||||
// TODO currently a selfadjoint expression has the form SelfAdjointView<.,.>
|
||||
// in the future selfadjoint-ness should be defined by the expression traits
|
||||
// such that Transpose<SelfAdjointView<.,.> > is valid. (currently TriangularBase::transpose() is overloaded to make it work)
|
||||
template<typename MatrixType, unsigned int Mode>
|
||||
struct evaluator_traits<SelfAdjointView<MatrixType,Mode> >
|
||||
{
|
||||
enum {
|
||||
col = (UnrollCount-1) / Derived1::RowsAtCompileTime,
|
||||
row = (UnrollCount-1) % Derived1::RowsAtCompileTime
|
||||
};
|
||||
typedef typename storage_kind_to_evaluator_kind<typename MatrixType::StorageKind>::Kind Kind;
|
||||
typedef SelfAdjointShape Shape;
|
||||
|
||||
static const int AssumeAliasing = 0;
|
||||
};
|
||||
|
||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
||||
template<int UpLo, int SetOpposite, typename DstEvaluatorTypeT, typename SrcEvaluatorTypeT, typename Functor, int Version>
|
||||
class triangular_dense_assignment_kernel<UpLo,SelfAdjoint,SetOpposite,DstEvaluatorTypeT,SrcEvaluatorTypeT,Functor,Version>
|
||||
: public generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version>
|
||||
{
|
||||
protected:
|
||||
typedef generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version> Base;
|
||||
typedef typename Base::DstXprType DstXprType;
|
||||
typedef typename Base::SrcXprType SrcXprType;
|
||||
using Base::m_dst;
|
||||
using Base::m_src;
|
||||
using Base::m_functor;
|
||||
public:
|
||||
|
||||
typedef typename Base::DstEvaluatorType DstEvaluatorType;
|
||||
typedef typename Base::SrcEvaluatorType SrcEvaluatorType;
|
||||
typedef typename Base::Scalar Scalar;
|
||||
typedef typename Base::AssignmentTraits AssignmentTraits;
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC triangular_dense_assignment_kernel(DstEvaluatorType &dst, const SrcEvaluatorType &src, const Functor &func, DstXprType& dstExpr)
|
||||
: Base(dst, src, func, dstExpr)
|
||||
{}
|
||||
|
||||
EIGEN_DEVICE_FUNC void assignCoeff(Index row, Index col)
|
||||
{
|
||||
triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Upper), UnrollCount-1, ClearOpposite>::run(dst, src);
|
||||
|
||||
if(row == col)
|
||||
dst.coeffRef(row, col) = numext::real(src.coeff(row, col));
|
||||
else if(row < col)
|
||||
dst.coeffRef(col, row) = numext::conj(dst.coeffRef(row, col) = src.coeff(row, col));
|
||||
eigen_internal_assert(row!=col);
|
||||
Scalar tmp = m_src.coeff(row,col);
|
||||
m_functor.assignCoeff(m_dst.coeffRef(row,col), tmp);
|
||||
m_functor.assignCoeff(m_dst.coeffRef(col,row), numext::conj(tmp));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
||||
struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Upper, 0, ClearOpposite>
|
||||
{
|
||||
static inline void run(Derived1 &, const Derived2 &) {}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, int UnrollCount, bool ClearOpposite>
|
||||
struct triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Lower), UnrollCount, ClearOpposite>
|
||||
{
|
||||
enum {
|
||||
col = (UnrollCount-1) / Derived1::RowsAtCompileTime,
|
||||
row = (UnrollCount-1) % Derived1::RowsAtCompileTime
|
||||
};
|
||||
|
||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
||||
|
||||
EIGEN_DEVICE_FUNC void assignDiagonalCoeff(Index id)
|
||||
{
|
||||
triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Lower), UnrollCount-1, ClearOpposite>::run(dst, src);
|
||||
|
||||
if(row == col)
|
||||
dst.coeffRef(row, col) = numext::real(src.coeff(row, col));
|
||||
else if(row > col)
|
||||
dst.coeffRef(col, row) = numext::conj(dst.coeffRef(row, col) = src.coeff(row, col));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
||||
struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Lower, 0, ClearOpposite>
|
||||
{
|
||||
static inline void run(Derived1 &, const Derived2 &) {}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
||||
struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Upper, Dynamic, ClearOpposite>
|
||||
{
|
||||
typedef typename Derived1::Index Index;
|
||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
for(Index j = 0; j < dst.cols(); ++j)
|
||||
{
|
||||
for(Index i = 0; i < j; ++i)
|
||||
{
|
||||
dst.copyCoeff(i, j, src);
|
||||
dst.coeffRef(j,i) = numext::conj(dst.coeff(i,j));
|
||||
}
|
||||
dst.copyCoeff(j, j, src);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
||||
struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Lower, Dynamic, ClearOpposite>
|
||||
{
|
||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
typedef typename Derived1::Index Index;
|
||||
for(Index i = 0; i < dst.rows(); ++i)
|
||||
{
|
||||
for(Index j = 0; j < i; ++j)
|
||||
{
|
||||
dst.copyCoeff(i, j, src);
|
||||
dst.coeffRef(j,i) = numext::conj(dst.coeff(i,j));
|
||||
}
|
||||
dst.copyCoeff(i, i, src);
|
||||
}
|
||||
Base::assignCoeff(id,id);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC void assignOppositeCoeff(Index, Index)
|
||||
{ eigen_internal_assert(false && "should never be called"); }
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
@@ -298,7 +258,7 @@ template<unsigned int UpLo>
|
||||
typename MatrixBase<Derived>::template ConstSelfAdjointViewReturnType<UpLo>::Type
|
||||
MatrixBase<Derived>::selfadjointView() const
|
||||
{
|
||||
return derived();
|
||||
return typename ConstSelfAdjointViewReturnType<UpLo>::Type(derived());
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
@@ -306,7 +266,7 @@ template<unsigned int UpLo>
|
||||
typename MatrixBase<Derived>::template SelfAdjointViewReturnType<UpLo>::Type
|
||||
MatrixBase<Derived>::selfadjointView()
|
||||
{
|
||||
return derived();
|
||||
return typename SelfAdjointViewReturnType<UpLo>::Type(derived());
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -12,183 +12,35 @@
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
/** \class SelfCwiseBinaryOp
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* \internal
|
||||
*
|
||||
* \brief Internal helper class for optimizing operators like +=, -=
|
||||
*
|
||||
* This is a pseudo expression class re-implementing the copyCoeff/copyPacket
|
||||
* method to directly performs a +=/-= operations in an optimal way. In particular,
|
||||
* this allows to make sure that the input/output data are loaded only once using
|
||||
* aligned packet loads.
|
||||
*
|
||||
* \sa class SwapWrapper for a similar trick.
|
||||
*/
|
||||
|
||||
namespace internal {
|
||||
template<typename BinaryOp, typename Lhs, typename Rhs>
|
||||
struct traits<SelfCwiseBinaryOp<BinaryOp,Lhs,Rhs> >
|
||||
: traits<CwiseBinaryOp<BinaryOp,Lhs,Rhs> >
|
||||
{
|
||||
enum {
|
||||
// Note that it is still a good idea to preserve the DirectAccessBit
|
||||
// so that assign can correctly align the data.
|
||||
Flags = traits<CwiseBinaryOp<BinaryOp,Lhs,Rhs> >::Flags | (Lhs::Flags&DirectAccessBit) | (Lhs::Flags&LvalueBit),
|
||||
OuterStrideAtCompileTime = Lhs::OuterStrideAtCompileTime,
|
||||
InnerStrideAtCompileTime = Lhs::InnerStrideAtCompileTime
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
template<typename BinaryOp, typename Lhs, typename Rhs> class SelfCwiseBinaryOp
|
||||
: public internal::dense_xpr_base< SelfCwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename internal::dense_xpr_base<SelfCwiseBinaryOp>::type Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(SelfCwiseBinaryOp)
|
||||
|
||||
typedef typename internal::packet_traits<Scalar>::type Packet;
|
||||
|
||||
inline SelfCwiseBinaryOp(Lhs& xpr, const BinaryOp& func = BinaryOp()) : m_matrix(xpr), m_functor(func) {}
|
||||
|
||||
inline Index rows() const { return m_matrix.rows(); }
|
||||
inline Index cols() const { return m_matrix.cols(); }
|
||||
inline Index outerStride() const { return m_matrix.outerStride(); }
|
||||
inline Index innerStride() const { return m_matrix.innerStride(); }
|
||||
inline const Scalar* data() const { return m_matrix.data(); }
|
||||
|
||||
// note that this function is needed by assign to correctly align loads/stores
|
||||
// TODO make Assign use .data()
|
||||
inline Scalar& coeffRef(Index row, Index col)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_LVALUE(Lhs)
|
||||
return m_matrix.const_cast_derived().coeffRef(row, col);
|
||||
}
|
||||
inline const Scalar& coeffRef(Index row, Index col) const
|
||||
{
|
||||
return m_matrix.coeffRef(row, col);
|
||||
}
|
||||
|
||||
// note that this function is needed by assign to correctly align loads/stores
|
||||
// TODO make Assign use .data()
|
||||
inline Scalar& coeffRef(Index index)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_LVALUE(Lhs)
|
||||
return m_matrix.const_cast_derived().coeffRef(index);
|
||||
}
|
||||
inline const Scalar& coeffRef(Index index) const
|
||||
{
|
||||
return m_matrix.const_cast_derived().coeffRef(index);
|
||||
}
|
||||
|
||||
template<typename OtherDerived>
|
||||
void copyCoeff(Index row, Index col, const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
OtherDerived& _other = other.const_cast_derived();
|
||||
eigen_internal_assert(row >= 0 && row < rows()
|
||||
&& col >= 0 && col < cols());
|
||||
Scalar& tmp = m_matrix.coeffRef(row,col);
|
||||
tmp = m_functor(tmp, _other.coeff(row,col));
|
||||
}
|
||||
|
||||
template<typename OtherDerived>
|
||||
void copyCoeff(Index index, const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
OtherDerived& _other = other.const_cast_derived();
|
||||
eigen_internal_assert(index >= 0 && index < m_matrix.size());
|
||||
Scalar& tmp = m_matrix.coeffRef(index);
|
||||
tmp = m_functor(tmp, _other.coeff(index));
|
||||
}
|
||||
|
||||
template<typename OtherDerived, int StoreMode, int LoadMode>
|
||||
void copyPacket(Index row, Index col, const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
OtherDerived& _other = other.const_cast_derived();
|
||||
eigen_internal_assert(row >= 0 && row < rows()
|
||||
&& col >= 0 && col < cols());
|
||||
m_matrix.template writePacket<StoreMode>(row, col,
|
||||
m_functor.packetOp(m_matrix.template packet<StoreMode>(row, col),_other.template packet<LoadMode>(row, col)) );
|
||||
}
|
||||
|
||||
template<typename OtherDerived, int StoreMode, int LoadMode>
|
||||
void copyPacket(Index index, const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
OtherDerived& _other = other.const_cast_derived();
|
||||
eigen_internal_assert(index >= 0 && index < m_matrix.size());
|
||||
m_matrix.template writePacket<StoreMode>(index,
|
||||
m_functor.packetOp(m_matrix.template packet<StoreMode>(index),_other.template packet<LoadMode>(index)) );
|
||||
}
|
||||
|
||||
// reimplement lazyAssign to handle complex *= real
|
||||
// see CwiseBinaryOp ctor for details
|
||||
template<typename RhsDerived>
|
||||
EIGEN_STRONG_INLINE SelfCwiseBinaryOp& lazyAssign(const DenseBase<RhsDerived>& rhs)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs,RhsDerived)
|
||||
EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename RhsDerived::Scalar);
|
||||
|
||||
#ifdef EIGEN_DEBUG_ASSIGN
|
||||
internal::assign_traits<SelfCwiseBinaryOp, RhsDerived>::debug();
|
||||
#endif
|
||||
eigen_assert(rows() == rhs.rows() && cols() == rhs.cols());
|
||||
internal::assign_impl<SelfCwiseBinaryOp, RhsDerived>::run(*this,rhs.derived());
|
||||
#ifndef EIGEN_NO_DEBUG
|
||||
this->checkTransposeAliasing(rhs.derived());
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
// overloaded to honor evaluation of special matrices
|
||||
// maybe another solution would be to not use SelfCwiseBinaryOp
|
||||
// at first...
|
||||
SelfCwiseBinaryOp& operator=(const Rhs& _rhs)
|
||||
{
|
||||
typename internal::nested<Rhs>::type rhs(_rhs);
|
||||
return Base::operator=(rhs);
|
||||
}
|
||||
|
||||
Lhs& expression() const
|
||||
{
|
||||
return m_matrix;
|
||||
}
|
||||
|
||||
const BinaryOp& functor() const
|
||||
{
|
||||
return m_functor;
|
||||
}
|
||||
|
||||
protected:
|
||||
Lhs& m_matrix;
|
||||
const BinaryOp& m_functor;
|
||||
|
||||
private:
|
||||
SelfCwiseBinaryOp& operator=(const SelfCwiseBinaryOp&);
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
inline Derived& DenseBase<Derived>::operator*=(const Scalar& other)
|
||||
{
|
||||
typedef typename Derived::PlainObject PlainObject;
|
||||
SelfCwiseBinaryOp<internal::scalar_product_op<Scalar>, Derived, typename PlainObject::ConstantReturnType> tmp(derived());
|
||||
tmp = PlainObject::Constant(rows(),cols(),other);
|
||||
internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::mul_assign_op<Scalar>());
|
||||
return derived();
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
inline Derived& ArrayBase<Derived>::operator+=(const Scalar& other)
|
||||
{
|
||||
typedef typename Derived::PlainObject PlainObject;
|
||||
internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::add_assign_op<Scalar>());
|
||||
return derived();
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
inline Derived& ArrayBase<Derived>::operator-=(const Scalar& other)
|
||||
{
|
||||
typedef typename Derived::PlainObject PlainObject;
|
||||
internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::sub_assign_op<Scalar>());
|
||||
return derived();
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
inline Derived& DenseBase<Derived>::operator/=(const Scalar& other)
|
||||
{
|
||||
typedef typename internal::conditional<NumTraits<Scalar>::IsInteger,
|
||||
internal::scalar_quotient_op<Scalar>,
|
||||
internal::scalar_product_op<Scalar> >::type BinOp;
|
||||
typedef typename Derived::PlainObject PlainObject;
|
||||
SelfCwiseBinaryOp<BinOp, Derived, typename PlainObject::ConstantReturnType> tmp(derived());
|
||||
Scalar actual_other;
|
||||
if(NumTraits<Scalar>::IsInteger) actual_other = other;
|
||||
else actual_other = Scalar(1)/other;
|
||||
tmp = PlainObject::Constant(rows(),cols(), actual_other);
|
||||
internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::div_assign_op<Scalar>());
|
||||
return derived();
|
||||
}
|
||||
|
||||
|
||||
150
Eigen/src/Core/Solve.h
Normal file
150
Eigen/src/Core/Solve.h
Normal file
@@ -0,0 +1,150 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2014 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef EIGEN_SOLVE_H
|
||||
#define EIGEN_SOLVE_H
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
template<typename Decomposition, typename RhsType, typename StorageKind> class SolveImpl;
|
||||
|
||||
/** \class Solve
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* \brief Pseudo expression representing a solving operation
|
||||
*
|
||||
* \tparam Decomposition the type of the matrix or decomposion object
|
||||
* \tparam Rhstype the type of the right-hand side
|
||||
*
|
||||
* This class represents an expression of A.solve(B)
|
||||
* and most of the time this is the only way it is used.
|
||||
*
|
||||
*/
|
||||
namespace internal {
|
||||
|
||||
// this solve_traits class permits to determine the evaluation type with respect to storage kind (Dense vs Sparse)
|
||||
template<typename Decomposition, typename RhsType,typename StorageKind> struct solve_traits;
|
||||
|
||||
template<typename Decomposition, typename RhsType>
|
||||
struct solve_traits<Decomposition,RhsType,Dense>
|
||||
{
|
||||
typedef typename Decomposition::MatrixType MatrixType;
|
||||
typedef Matrix<typename RhsType::Scalar,
|
||||
MatrixType::ColsAtCompileTime,
|
||||
RhsType::ColsAtCompileTime,
|
||||
RhsType::PlainObject::Options,
|
||||
MatrixType::MaxColsAtCompileTime,
|
||||
RhsType::MaxColsAtCompileTime> PlainObject;
|
||||
};
|
||||
|
||||
template<typename Decomposition, typename RhsType>
|
||||
struct traits<Solve<Decomposition, RhsType> >
|
||||
: traits<typename solve_traits<Decomposition,RhsType,typename internal::traits<RhsType>::StorageKind>::PlainObject>
|
||||
{
|
||||
typedef typename solve_traits<Decomposition,RhsType,typename internal::traits<RhsType>::StorageKind>::PlainObject PlainObject;
|
||||
typedef typename promote_index_type<typename Decomposition::StorageIndex, typename RhsType::StorageIndex>::type StorageIndex;
|
||||
typedef traits<PlainObject> BaseTraits;
|
||||
enum {
|
||||
Flags = BaseTraits::Flags & RowMajorBit,
|
||||
CoeffReadCost = Dynamic
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
template<typename Decomposition, typename RhsType>
|
||||
class Solve : public SolveImpl<Decomposition,RhsType,typename internal::traits<RhsType>::StorageKind>
|
||||
{
|
||||
public:
|
||||
typedef typename internal::traits<Solve>::PlainObject PlainObject;
|
||||
typedef typename internal::traits<Solve>::StorageIndex StorageIndex;
|
||||
|
||||
Solve(const Decomposition &dec, const RhsType &rhs)
|
||||
: m_dec(dec), m_rhs(rhs)
|
||||
{}
|
||||
|
||||
EIGEN_DEVICE_FUNC Index rows() const { return m_dec.cols(); }
|
||||
EIGEN_DEVICE_FUNC Index cols() const { return m_rhs.cols(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC const Decomposition& dec() const { return m_dec; }
|
||||
EIGEN_DEVICE_FUNC const RhsType& rhs() const { return m_rhs; }
|
||||
|
||||
protected:
|
||||
const Decomposition &m_dec;
|
||||
const RhsType &m_rhs;
|
||||
};
|
||||
|
||||
|
||||
// Specialization of the Solve expression for dense results
|
||||
template<typename Decomposition, typename RhsType>
|
||||
class SolveImpl<Decomposition,RhsType,Dense>
|
||||
: public MatrixBase<Solve<Decomposition,RhsType> >
|
||||
{
|
||||
typedef Solve<Decomposition,RhsType> Derived;
|
||||
|
||||
public:
|
||||
|
||||
typedef MatrixBase<Solve<Decomposition,RhsType> > Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
||||
|
||||
private:
|
||||
|
||||
Scalar coeff(Index row, Index col) const;
|
||||
Scalar coeff(Index i) const;
|
||||
};
|
||||
|
||||
// Generic API dispatcher
|
||||
template<typename Decomposition, typename RhsType, typename StorageKind>
|
||||
class SolveImpl : public internal::generic_xpr_base<Solve<Decomposition,RhsType>, MatrixXpr, StorageKind>::type
|
||||
{
|
||||
public:
|
||||
typedef typename internal::generic_xpr_base<Solve<Decomposition,RhsType>, MatrixXpr, StorageKind>::type Base;
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Evaluator of Solve -> eval into a temporary
|
||||
template<typename Decomposition, typename RhsType>
|
||||
struct evaluator<Solve<Decomposition,RhsType> >
|
||||
: public evaluator<typename Solve<Decomposition,RhsType>::PlainObject>
|
||||
{
|
||||
typedef Solve<Decomposition,RhsType> SolveType;
|
||||
typedef typename SolveType::PlainObject PlainObject;
|
||||
typedef evaluator<PlainObject> Base;
|
||||
|
||||
EIGEN_DEVICE_FUNC explicit evaluator(const SolveType& solve)
|
||||
: m_result(solve.rows(), solve.cols())
|
||||
{
|
||||
::new (static_cast<Base*>(this)) Base(m_result);
|
||||
solve.dec()._solve_impl(solve.rhs(), m_result);
|
||||
}
|
||||
|
||||
protected:
|
||||
PlainObject m_result;
|
||||
};
|
||||
|
||||
// Specialization for "dst = dec.solve(rhs)"
|
||||
// NOTE we need to specialize it for Dense2Dense to avoid ambiguous specialization error and a Sparse2Sparse specialization must exist somewhere
|
||||
template<typename DstXprType, typename DecType, typename RhsType, typename Scalar>
|
||||
struct Assignment<DstXprType, Solve<DecType,RhsType>, internal::assign_op<Scalar>, Dense2Dense, Scalar>
|
||||
{
|
||||
typedef Solve<DecType,RhsType> SrcXprType;
|
||||
static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar> &)
|
||||
{
|
||||
// FIXME shall we resize dst here?
|
||||
src.dec()._solve_impl(src.rhs(), dst);
|
||||
}
|
||||
};
|
||||
|
||||
} // end namepsace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_SOLVE_H
|
||||
@@ -68,7 +68,7 @@ struct triangular_solver_selector<Lhs,Rhs,Side,Mode,NoUnrolling,1>
|
||||
if(!useRhsDirectly)
|
||||
MappedRhs(actualRhs,rhs.size()) = rhs;
|
||||
|
||||
triangular_solve_vector<LhsScalar, RhsScalar, typename Lhs::Index, Side, Mode, LhsProductTraits::NeedToConjugate,
|
||||
triangular_solve_vector<LhsScalar, RhsScalar, Index, Side, Mode, LhsProductTraits::NeedToConjugate,
|
||||
(int(Lhs::Flags) & RowMajorBit) ? RowMajor : ColMajor>
|
||||
::run(actualLhs.cols(), actualLhs.data(), actualLhs.outerStride(), actualRhs);
|
||||
|
||||
@@ -82,7 +82,6 @@ template<typename Lhs, typename Rhs, int Side, int Mode>
|
||||
struct triangular_solver_selector<Lhs,Rhs,Side,Mode,NoUnrolling,Dynamic>
|
||||
{
|
||||
typedef typename Rhs::Scalar Scalar;
|
||||
typedef typename Rhs::Index Index;
|
||||
typedef blas_traits<Lhs> LhsProductTraits;
|
||||
typedef typename LhsProductTraits::DirectLinearAccessType ActualLhsType;
|
||||
|
||||
@@ -96,7 +95,7 @@ struct triangular_solver_selector<Lhs,Rhs,Side,Mode,NoUnrolling,Dynamic>
|
||||
typedef internal::gemm_blocking_space<(Rhs::Flags&RowMajorBit) ? RowMajor : ColMajor,Scalar,Scalar,
|
||||
Rhs::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime, Lhs::MaxRowsAtCompileTime,4> BlockingType;
|
||||
|
||||
BlockingType blocking(rhs.rows(), rhs.cols(), size);
|
||||
BlockingType blocking(rhs.rows(), rhs.cols(), size, 1, false);
|
||||
|
||||
triangular_solve_matrix<Scalar,Index,Side,Mode,LhsProductTraits::NeedToConjugate,(int(Lhs::Flags) & RowMajorBit) ? RowMajor : ColMajor,
|
||||
(Rhs::Flags&RowMajorBit) ? RowMajor : ColMajor>
|
||||
@@ -171,10 +170,10 @@ struct triangular_solver_selector<Lhs,Rhs,OnTheRight,Mode,CompleteUnrolling,1> {
|
||||
*/
|
||||
template<typename MatrixType, unsigned int Mode>
|
||||
template<int Side, typename OtherDerived>
|
||||
void TriangularView<MatrixType,Mode>::solveInPlace(const MatrixBase<OtherDerived>& _other) const
|
||||
void TriangularViewImpl<MatrixType,Mode,Dense>::solveInPlace(const MatrixBase<OtherDerived>& _other) const
|
||||
{
|
||||
OtherDerived& other = _other.const_cast_derived();
|
||||
eigen_assert( cols() == rows() && ((Side==OnTheLeft && cols() == other.rows()) || (Side==OnTheRight && cols() == other.cols())) );
|
||||
eigen_assert( derived().cols() == derived().rows() && ((Side==OnTheLeft && derived().cols() == other.rows()) || (Side==OnTheRight && derived().cols() == other.cols())) );
|
||||
eigen_assert((!(Mode & ZeroDiag)) && bool(Mode & (Upper|Lower)));
|
||||
|
||||
enum { copy = internal::traits<OtherDerived>::Flags & RowMajorBit && OtherDerived::IsVectorAtCompileTime };
|
||||
@@ -183,7 +182,7 @@ void TriangularView<MatrixType,Mode>::solveInPlace(const MatrixBase<OtherDerived
|
||||
OtherCopy otherCopy(other);
|
||||
|
||||
internal::triangular_solver_selector<MatrixType, typename internal::remove_reference<OtherCopy>::type,
|
||||
Side, Mode>::run(nestedExpression(), otherCopy);
|
||||
Side, Mode>::run(derived().nestedExpression(), otherCopy);
|
||||
|
||||
if (copy)
|
||||
other = otherCopy;
|
||||
@@ -199,8 +198,8 @@ void TriangularView<MatrixType,Mode>::solveInPlace(const MatrixBase<OtherDerived
|
||||
* diagonal must be non zero). It works as a forward (resp. backward) substitution if \c *this
|
||||
* is an upper (resp. lower) triangular matrix.
|
||||
*
|
||||
* Example: \include MatrixBase_marked.cpp
|
||||
* Output: \verbinclude MatrixBase_marked.out
|
||||
* Example: \include Triangular_solve.cpp
|
||||
* Output: \verbinclude Triangular_solve.out
|
||||
*
|
||||
* This function returns an expression of the inverse-multiply and can works in-place if it is assigned
|
||||
* to the same matrix or vector \a other.
|
||||
@@ -213,9 +212,9 @@ void TriangularView<MatrixType,Mode>::solveInPlace(const MatrixBase<OtherDerived
|
||||
template<typename Derived, unsigned int Mode>
|
||||
template<int Side, typename Other>
|
||||
const internal::triangular_solve_retval<Side,TriangularView<Derived,Mode>,Other>
|
||||
TriangularView<Derived,Mode>::solve(const MatrixBase<Other>& other) const
|
||||
TriangularViewImpl<Derived,Mode,Dense>::solve(const MatrixBase<Other>& other) const
|
||||
{
|
||||
return internal::triangular_solve_retval<Side,TriangularView,Other>(*this, other.derived());
|
||||
return internal::triangular_solve_retval<Side,TriangularViewType,Other>(derived(), other.derived());
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
@@ -232,7 +231,6 @@ template<int Side, typename TriangularType, typename Rhs> struct triangular_solv
|
||||
{
|
||||
typedef typename remove_all<typename Rhs::Nested>::type RhsNestedCleaned;
|
||||
typedef ReturnByValue<triangular_solve_retval> Base;
|
||||
typedef typename Base::Index Index;
|
||||
|
||||
triangular_solve_retval(const TriangularType& tri, const Rhs& rhs)
|
||||
: m_triangularMatrix(tri), m_rhs(rhs)
|
||||
|
||||
@@ -17,16 +17,37 @@ namespace internal {
|
||||
template<typename ExpressionType, typename Scalar>
|
||||
inline void stable_norm_kernel(const ExpressionType& bl, Scalar& ssq, Scalar& scale, Scalar& invScale)
|
||||
{
|
||||
Scalar max = bl.cwiseAbs().maxCoeff();
|
||||
if (max>scale)
|
||||
Scalar maxCoeff = bl.cwiseAbs().maxCoeff();
|
||||
|
||||
if(maxCoeff>scale)
|
||||
{
|
||||
ssq = ssq * numext::abs2(scale/max);
|
||||
scale = max;
|
||||
invScale = Scalar(1)/scale;
|
||||
ssq = ssq * numext::abs2(scale/maxCoeff);
|
||||
Scalar tmp = Scalar(1)/maxCoeff;
|
||||
if(tmp > NumTraits<Scalar>::highest())
|
||||
{
|
||||
invScale = NumTraits<Scalar>::highest();
|
||||
scale = Scalar(1)/invScale;
|
||||
}
|
||||
else if(maxCoeff>NumTraits<Scalar>::highest()) // we got a INF
|
||||
{
|
||||
invScale = Scalar(1);
|
||||
scale = maxCoeff;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = maxCoeff;
|
||||
invScale = tmp;
|
||||
}
|
||||
}
|
||||
// TODO if the max is much much smaller than the current scale,
|
||||
else if(maxCoeff!=maxCoeff) // we got a NaN
|
||||
{
|
||||
scale = maxCoeff;
|
||||
}
|
||||
|
||||
// TODO if the maxCoeff is much much smaller than the current scale,
|
||||
// then we can neglect this sub vector
|
||||
ssq += (bl*invScale).squaredNorm();
|
||||
if(scale>Scalar(0)) // if scale==0, then bl is 0
|
||||
ssq += (bl*invScale).squaredNorm();
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
@@ -34,15 +55,12 @@ inline typename NumTraits<typename traits<Derived>::Scalar>::Real
|
||||
blueNorm_impl(const EigenBase<Derived>& _vec)
|
||||
{
|
||||
typedef typename Derived::RealScalar RealScalar;
|
||||
typedef typename Derived::Index Index;
|
||||
using std::pow;
|
||||
using std::min;
|
||||
using std::max;
|
||||
using std::sqrt;
|
||||
using std::abs;
|
||||
const Derived& vec(_vec.derived());
|
||||
static bool initialized = false;
|
||||
static RealScalar b1, b2, s1m, s2m, overfl, rbig, relerr;
|
||||
static RealScalar b1, b2, s1m, s2m, rbig, relerr;
|
||||
if(!initialized)
|
||||
{
|
||||
int ibeta, it, iemin, iemax, iexp;
|
||||
@@ -71,7 +89,6 @@ blueNorm_impl(const EigenBase<Derived>& _vec)
|
||||
iexp = - ((iemax+it)/2);
|
||||
s2m = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for upper range
|
||||
|
||||
overfl = rbig*s2m; // overflow boundary for abig
|
||||
eps = RealScalar(pow(double(ibeta), 1-it));
|
||||
relerr = sqrt(eps); // tolerance for neglecting asml
|
||||
initialized = true;
|
||||
@@ -88,13 +105,13 @@ blueNorm_impl(const EigenBase<Derived>& _vec)
|
||||
else if(ax < b1) asml += numext::abs2(ax*s1m);
|
||||
else amed += numext::abs2(ax);
|
||||
}
|
||||
if(amed!=amed)
|
||||
return amed; // we got a NaN
|
||||
if(abig > RealScalar(0))
|
||||
{
|
||||
abig = sqrt(abig);
|
||||
if(abig > overfl)
|
||||
{
|
||||
return rbig;
|
||||
}
|
||||
if(abig > rbig) // overflow, or *this contains INF values
|
||||
return abig; // return INF
|
||||
if(amed > RealScalar(0))
|
||||
{
|
||||
abig = abig/s2m;
|
||||
@@ -115,8 +132,8 @@ blueNorm_impl(const EigenBase<Derived>& _vec)
|
||||
}
|
||||
else
|
||||
return sqrt(amed);
|
||||
asml = (min)(abig, amed);
|
||||
abig = (max)(abig, amed);
|
||||
asml = numext::mini(abig, amed);
|
||||
abig = numext::maxi(abig, amed);
|
||||
if(asml <= abig*relerr)
|
||||
return abig;
|
||||
else
|
||||
@@ -139,21 +156,33 @@ template<typename Derived>
|
||||
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
|
||||
MatrixBase<Derived>::stableNorm() const
|
||||
{
|
||||
using std::min;
|
||||
using std::sqrt;
|
||||
using std::abs;
|
||||
const Index blockSize = 4096;
|
||||
RealScalar scale(0);
|
||||
RealScalar invScale(1);
|
||||
RealScalar ssq(0); // sum of square
|
||||
|
||||
typedef typename internal::nested_eval<Derived,2>::type DerivedCopy;
|
||||
typedef typename internal::remove_all<DerivedCopy>::type DerivedCopyClean;
|
||||
DerivedCopy copy(derived());
|
||||
|
||||
enum {
|
||||
Alignment = (int(Flags)&DirectAccessBit) || (int(Flags)&AlignedBit) ? 1 : 0
|
||||
CanAlign = (int(Flags)&DirectAccessBit) || (int(internal::evaluator<DerivedCopyClean>::Alignment)>0) // FIXME
|
||||
};
|
||||
typedef typename internal::conditional<CanAlign, Ref<const Matrix<Scalar,Dynamic,1,0,blockSize,1>, internal::evaluator<DerivedCopyClean>::Alignment>,
|
||||
typename DerivedCopyClean
|
||||
::ConstSegmentReturnType>::type SegmentWrapper;
|
||||
Index n = size();
|
||||
Index bi = internal::first_aligned(derived());
|
||||
|
||||
if(n==1)
|
||||
return abs(this->coeff(0));
|
||||
|
||||
Index bi = internal::first_default_aligned(copy);
|
||||
if (bi>0)
|
||||
internal::stable_norm_kernel(this->head(bi), ssq, scale, invScale);
|
||||
internal::stable_norm_kernel(copy.head(bi), ssq, scale, invScale);
|
||||
for (; bi<n; bi+=blockSize)
|
||||
internal::stable_norm_kernel(this->segment(bi,(min)(blockSize, n - bi)).template forceAlignedAccessIf<Alignment>(), ssq, scale, invScale);
|
||||
internal::stable_norm_kernel(SegmentWrapper(copy.segment(bi,numext::mini(blockSize, n - bi))), ssq, scale, invScale);
|
||||
return scale * sqrt(ssq);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,13 +44,14 @@ template<int _OuterStrideAtCompileTime, int _InnerStrideAtCompileTime>
|
||||
class Stride
|
||||
{
|
||||
public:
|
||||
typedef DenseIndex Index;
|
||||
typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
|
||||
enum {
|
||||
InnerStrideAtCompileTime = _InnerStrideAtCompileTime,
|
||||
OuterStrideAtCompileTime = _OuterStrideAtCompileTime
|
||||
};
|
||||
|
||||
/** Default constructor, for use when strides are fixed at compile time */
|
||||
EIGEN_DEVICE_FUNC
|
||||
Stride()
|
||||
: m_outer(OuterStrideAtCompileTime), m_inner(InnerStrideAtCompileTime)
|
||||
{
|
||||
@@ -58,6 +59,7 @@ class Stride
|
||||
}
|
||||
|
||||
/** Constructor allowing to pass the strides at runtime */
|
||||
EIGEN_DEVICE_FUNC
|
||||
Stride(Index outerStride, Index innerStride)
|
||||
: m_outer(outerStride), m_inner(innerStride)
|
||||
{
|
||||
@@ -65,13 +67,16 @@ class Stride
|
||||
}
|
||||
|
||||
/** Copy constructor */
|
||||
EIGEN_DEVICE_FUNC
|
||||
Stride(const Stride& other)
|
||||
: m_outer(other.outer()), m_inner(other.inner())
|
||||
{}
|
||||
|
||||
/** \returns the outer stride */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index outer() const { return m_outer.value(); }
|
||||
/** \returns the inner stride */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Index inner() const { return m_inner.value(); }
|
||||
|
||||
protected:
|
||||
@@ -81,26 +86,24 @@ class Stride
|
||||
|
||||
/** \brief Convenience specialization of Stride to specify only an inner stride
|
||||
* See class Map for some examples */
|
||||
template<int Value = Dynamic>
|
||||
template<int Value>
|
||||
class InnerStride : public Stride<0, Value>
|
||||
{
|
||||
typedef Stride<0, Value> Base;
|
||||
public:
|
||||
typedef DenseIndex Index;
|
||||
InnerStride() : Base() {}
|
||||
InnerStride(Index v) : Base(0, v) {}
|
||||
EIGEN_DEVICE_FUNC InnerStride() : Base() {}
|
||||
EIGEN_DEVICE_FUNC InnerStride(Index v) : Base(0, v) {} // FIXME making this explicit could break valid code
|
||||
};
|
||||
|
||||
/** \brief Convenience specialization of Stride to specify only an outer stride
|
||||
* See class Map for some examples */
|
||||
template<int Value = Dynamic>
|
||||
template<int Value>
|
||||
class OuterStride : public Stride<Value, 0>
|
||||
{
|
||||
typedef Stride<Value, 0> Base;
|
||||
public:
|
||||
typedef DenseIndex Index;
|
||||
OuterStride() : Base() {}
|
||||
OuterStride(Index v) : Base(v,0) {}
|
||||
EIGEN_DEVICE_FUNC OuterStride() : Base() {}
|
||||
EIGEN_DEVICE_FUNC OuterStride(Index v) : Base(v,0) {} // FIXME making this explicit could break valid code
|
||||
};
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -12,115 +12,56 @@
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
/** \class SwapWrapper
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* \internal
|
||||
*
|
||||
* \brief Internal helper class for swapping two expressions
|
||||
*/
|
||||
namespace internal {
|
||||
template<typename ExpressionType>
|
||||
struct traits<SwapWrapper<ExpressionType> > : traits<ExpressionType> {};
|
||||
}
|
||||
|
||||
template<typename ExpressionType> class SwapWrapper
|
||||
: public internal::dense_xpr_base<SwapWrapper<ExpressionType> >::type
|
||||
// Overload default assignPacket behavior for swapping them
|
||||
template<typename DstEvaluatorTypeT, typename SrcEvaluatorTypeT>
|
||||
class generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, swap_assign_op<typename DstEvaluatorTypeT::Scalar>, Specialized>
|
||||
: public generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, swap_assign_op<typename DstEvaluatorTypeT::Scalar>, BuiltIn>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename internal::dense_xpr_base<SwapWrapper>::type Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(SwapWrapper)
|
||||
typedef typename internal::packet_traits<Scalar>::type Packet;
|
||||
|
||||
inline SwapWrapper(ExpressionType& xpr) : m_expression(xpr) {}
|
||||
|
||||
inline Index rows() const { return m_expression.rows(); }
|
||||
inline Index cols() const { return m_expression.cols(); }
|
||||
inline Index outerStride() const { return m_expression.outerStride(); }
|
||||
inline Index innerStride() const { return m_expression.innerStride(); }
|
||||
|
||||
typedef typename internal::conditional<
|
||||
internal::is_lvalue<ExpressionType>::value,
|
||||
Scalar,
|
||||
const Scalar
|
||||
>::type ScalarWithConstIfNotLvalue;
|
||||
|
||||
inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
|
||||
inline const Scalar* data() const { return m_expression.data(); }
|
||||
|
||||
inline Scalar& coeffRef(Index rowId, Index colId)
|
||||
{
|
||||
return m_expression.const_cast_derived().coeffRef(rowId, colId);
|
||||
}
|
||||
|
||||
inline Scalar& coeffRef(Index index)
|
||||
{
|
||||
return m_expression.const_cast_derived().coeffRef(index);
|
||||
}
|
||||
|
||||
inline Scalar& coeffRef(Index rowId, Index colId) const
|
||||
{
|
||||
return m_expression.coeffRef(rowId, colId);
|
||||
}
|
||||
|
||||
inline Scalar& coeffRef(Index index) const
|
||||
{
|
||||
return m_expression.coeffRef(index);
|
||||
}
|
||||
|
||||
template<typename OtherDerived>
|
||||
void copyCoeff(Index rowId, Index colId, const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
OtherDerived& _other = other.const_cast_derived();
|
||||
eigen_internal_assert(rowId >= 0 && rowId < rows()
|
||||
&& colId >= 0 && colId < cols());
|
||||
Scalar tmp = m_expression.coeff(rowId, colId);
|
||||
m_expression.coeffRef(rowId, colId) = _other.coeff(rowId, colId);
|
||||
_other.coeffRef(rowId, colId) = tmp;
|
||||
}
|
||||
|
||||
template<typename OtherDerived>
|
||||
void copyCoeff(Index index, const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
OtherDerived& _other = other.const_cast_derived();
|
||||
eigen_internal_assert(index >= 0 && index < m_expression.size());
|
||||
Scalar tmp = m_expression.coeff(index);
|
||||
m_expression.coeffRef(index) = _other.coeff(index);
|
||||
_other.coeffRef(index) = tmp;
|
||||
}
|
||||
|
||||
template<typename OtherDerived, int StoreMode, int LoadMode>
|
||||
void copyPacket(Index rowId, Index colId, const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
OtherDerived& _other = other.const_cast_derived();
|
||||
eigen_internal_assert(rowId >= 0 && rowId < rows()
|
||||
&& colId >= 0 && colId < cols());
|
||||
Packet tmp = m_expression.template packet<StoreMode>(rowId, colId);
|
||||
m_expression.template writePacket<StoreMode>(rowId, colId,
|
||||
_other.template packet<LoadMode>(rowId, colId)
|
||||
);
|
||||
_other.template writePacket<LoadMode>(rowId, colId, tmp);
|
||||
}
|
||||
|
||||
template<typename OtherDerived, int StoreMode, int LoadMode>
|
||||
void copyPacket(Index index, const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
OtherDerived& _other = other.const_cast_derived();
|
||||
eigen_internal_assert(index >= 0 && index < m_expression.size());
|
||||
Packet tmp = m_expression.template packet<StoreMode>(index);
|
||||
m_expression.template writePacket<StoreMode>(index,
|
||||
_other.template packet<LoadMode>(index)
|
||||
);
|
||||
_other.template writePacket<LoadMode>(index, tmp);
|
||||
}
|
||||
|
||||
ExpressionType& expression() const { return m_expression; }
|
||||
|
||||
protected:
|
||||
ExpressionType& m_expression;
|
||||
protected:
|
||||
typedef generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, swap_assign_op<typename DstEvaluatorTypeT::Scalar>, BuiltIn> Base;
|
||||
using Base::m_dst;
|
||||
using Base::m_src;
|
||||
using Base::m_functor;
|
||||
|
||||
public:
|
||||
typedef typename Base::Scalar Scalar;
|
||||
typedef typename Base::DstXprType DstXprType;
|
||||
typedef swap_assign_op<Scalar> Functor;
|
||||
|
||||
EIGEN_DEVICE_FUNC generic_dense_assignment_kernel(DstEvaluatorTypeT &dst, const SrcEvaluatorTypeT &src, const Functor &func, DstXprType& dstExpr)
|
||||
: Base(dst, src, func, dstExpr)
|
||||
{}
|
||||
|
||||
template<int StoreMode, int LoadMode, typename PacketType>
|
||||
void assignPacket(Index row, Index col)
|
||||
{
|
||||
PacketType tmp = m_src.template packet<LoadMode,PacketType>(row,col);
|
||||
const_cast<SrcEvaluatorTypeT&>(m_src).template writePacket<LoadMode>(row,col, m_dst.template packet<StoreMode,PacketType>(row,col));
|
||||
m_dst.template writePacket<StoreMode>(row,col,tmp);
|
||||
}
|
||||
|
||||
template<int StoreMode, int LoadMode, typename PacketType>
|
||||
void assignPacket(Index index)
|
||||
{
|
||||
PacketType tmp = m_src.template packet<LoadMode,PacketType>(index);
|
||||
const_cast<SrcEvaluatorTypeT&>(m_src).template writePacket<LoadMode>(index, m_dst.template packet<StoreMode,PacketType>(index));
|
||||
m_dst.template writePacket<StoreMode>(index,tmp);
|
||||
}
|
||||
|
||||
// TODO find a simple way not to have to copy/paste this function from generic_dense_assignment_kernel, by simple I mean no CRTP (Gael)
|
||||
template<int StoreMode, int LoadMode, typename PacketType>
|
||||
void assignPacketByOuterInner(Index outer, Index inner)
|
||||
{
|
||||
Index row = Base::rowIndexByOuterInner(outer, inner);
|
||||
Index col = Base::colIndexByOuterInner(outer, inner);
|
||||
assignPacket<StoreMode,LoadMode,PacketType>(row, col);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_SWAP_H
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
// Copyright (C) 2009-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
@@ -29,13 +29,10 @@ namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
template<typename MatrixType>
|
||||
struct traits<Transpose<MatrixType> > : traits<MatrixType>
|
||||
struct traits<Transpose<MatrixType> > : public traits<MatrixType>
|
||||
{
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename nested<MatrixType>::type MatrixTypeNested;
|
||||
typedef typename ref_selector<MatrixType>::type MatrixTypeNested;
|
||||
typedef typename remove_reference<MatrixTypeNested>::type MatrixTypeNestedPlain;
|
||||
typedef typename traits<MatrixType>::StorageKind StorageKind;
|
||||
typedef typename traits<MatrixType>::XprKind XprKind;
|
||||
enum {
|
||||
RowsAtCompileTime = MatrixType::ColsAtCompileTime,
|
||||
ColsAtCompileTime = MatrixType::RowsAtCompileTime,
|
||||
@@ -45,7 +42,6 @@ struct traits<Transpose<MatrixType> > : traits<MatrixType>
|
||||
Flags0 = MatrixTypeNestedPlain::Flags & ~(LvalueBit | NestByRefBit),
|
||||
Flags1 = Flags0 | FlagsLvalueBit,
|
||||
Flags = Flags1 ^ RowMajorBit,
|
||||
CoeffReadCost = MatrixTypeNestedPlain::CoeffReadCost,
|
||||
InnerStrideAtCompileTime = inner_stride_at_compile_time<MatrixType>::ret,
|
||||
OuterStrideAtCompileTime = outer_stride_at_compile_time<MatrixType>::ret
|
||||
};
|
||||
@@ -61,19 +57,23 @@ template<typename MatrixType> class Transpose
|
||||
|
||||
typedef typename TransposeImpl<MatrixType,typename internal::traits<MatrixType>::StorageKind>::Base Base;
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(Transpose)
|
||||
typedef typename internal::remove_all<MatrixType>::type NestedExpression;
|
||||
|
||||
inline Transpose(MatrixType& a_matrix) : m_matrix(a_matrix) {}
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit inline Transpose(MatrixType& matrix) : m_matrix(matrix) {}
|
||||
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Transpose)
|
||||
|
||||
inline Index rows() const { return m_matrix.cols(); }
|
||||
inline Index cols() const { return m_matrix.rows(); }
|
||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_matrix.cols(); }
|
||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_matrix.rows(); }
|
||||
|
||||
/** \returns the nested expression */
|
||||
EIGEN_DEVICE_FUNC
|
||||
const typename internal::remove_all<typename MatrixType::Nested>::type&
|
||||
nestedExpression() const { return m_matrix; }
|
||||
|
||||
/** \returns the nested expression */
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename internal::remove_all<typename MatrixType::Nested>::type&
|
||||
nestedExpression() { return m_matrix.const_cast_derived(); }
|
||||
|
||||
@@ -97,17 +97,27 @@ struct TransposeImpl_base<MatrixType, false>
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
// Generic API dispatcher
|
||||
template<typename XprType, typename StorageKind>
|
||||
class TransposeImpl
|
||||
: public internal::generic_xpr_base<Transpose<XprType> >::type
|
||||
{
|
||||
public:
|
||||
typedef typename internal::generic_xpr_base<Transpose<XprType> >::type Base;
|
||||
};
|
||||
|
||||
template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
|
||||
: public internal::TransposeImpl_base<MatrixType>::type
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename internal::TransposeImpl_base<MatrixType>::type Base;
|
||||
using Base::coeffRef;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>)
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TransposeImpl)
|
||||
|
||||
inline Index innerStride() const { return derived().nestedExpression().innerStride(); }
|
||||
inline Index outerStride() const { return derived().nestedExpression().outerStride(); }
|
||||
EIGEN_DEVICE_FUNC inline Index innerStride() const { return derived().nestedExpression().innerStride(); }
|
||||
EIGEN_DEVICE_FUNC inline Index outerStride() const { return derived().nestedExpression().outerStride(); }
|
||||
|
||||
typedef typename internal::conditional<
|
||||
internal::is_lvalue<MatrixType>::value,
|
||||
@@ -115,64 +125,21 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
|
||||
const Scalar
|
||||
>::type ScalarWithConstIfNotLvalue;
|
||||
|
||||
inline ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); }
|
||||
inline const Scalar* data() const { return derived().nestedExpression().data(); }
|
||||
|
||||
inline ScalarWithConstIfNotLvalue& coeffRef(Index rowId, Index colId)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
|
||||
return derived().nestedExpression().const_cast_derived().coeffRef(colId, rowId);
|
||||
}
|
||||
|
||||
inline ScalarWithConstIfNotLvalue& coeffRef(Index index)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
|
||||
return derived().nestedExpression().const_cast_derived().coeffRef(index);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC inline ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); }
|
||||
EIGEN_DEVICE_FUNC inline const Scalar* data() const { return derived().nestedExpression().data(); }
|
||||
|
||||
// FIXME: shall we keep the const version of coeffRef?
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar& coeffRef(Index rowId, Index colId) const
|
||||
{
|
||||
return derived().nestedExpression().coeffRef(colId, rowId);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar& coeffRef(Index index) const
|
||||
{
|
||||
return derived().nestedExpression().coeffRef(index);
|
||||
}
|
||||
|
||||
inline CoeffReturnType coeff(Index rowId, Index colId) const
|
||||
{
|
||||
return derived().nestedExpression().coeff(colId, rowId);
|
||||
}
|
||||
|
||||
inline CoeffReturnType coeff(Index index) const
|
||||
{
|
||||
return derived().nestedExpression().coeff(index);
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
inline const PacketScalar packet(Index rowId, Index colId) const
|
||||
{
|
||||
return derived().nestedExpression().template packet<LoadMode>(colId, rowId);
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
inline void writePacket(Index rowId, Index colId, const PacketScalar& x)
|
||||
{
|
||||
derived().nestedExpression().const_cast_derived().template writePacket<LoadMode>(colId, rowId, x);
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
inline const PacketScalar packet(Index index) const
|
||||
{
|
||||
return derived().nestedExpression().template packet<LoadMode>(index);
|
||||
}
|
||||
|
||||
template<int LoadMode>
|
||||
inline void writePacket(Index index, const PacketScalar& x)
|
||||
{
|
||||
derived().nestedExpression().const_cast_derived().template writePacket<LoadMode>(index, x);
|
||||
}
|
||||
};
|
||||
|
||||
/** \returns an expression of the transpose of *this.
|
||||
@@ -198,7 +165,7 @@ template<typename Derived>
|
||||
inline Transpose<Derived>
|
||||
DenseBase<Derived>::transpose()
|
||||
{
|
||||
return derived();
|
||||
return TransposeReturnType(derived());
|
||||
}
|
||||
|
||||
/** This is the const version of transpose().
|
||||
@@ -236,8 +203,7 @@ template<typename Derived>
|
||||
inline const typename MatrixBase<Derived>::AdjointReturnType
|
||||
MatrixBase<Derived>::adjoint() const
|
||||
{
|
||||
return this->transpose(); // in the complex case, the .conjugate() is be implicit here
|
||||
// due to implicit conversion to return type
|
||||
return AdjointReturnType(this->transpose());
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
@@ -247,18 +213,38 @@ MatrixBase<Derived>::adjoint() const
|
||||
namespace internal {
|
||||
|
||||
template<typename MatrixType,
|
||||
bool IsSquare = (MatrixType::RowsAtCompileTime == MatrixType::ColsAtCompileTime) && MatrixType::RowsAtCompileTime!=Dynamic>
|
||||
bool IsSquare = (MatrixType::RowsAtCompileTime == MatrixType::ColsAtCompileTime) && MatrixType::RowsAtCompileTime!=Dynamic,
|
||||
bool MatchPacketSize =
|
||||
(int(MatrixType::RowsAtCompileTime) == int(internal::packet_traits<typename MatrixType::Scalar>::size))
|
||||
&& (internal::evaluator<MatrixType>::Flags&PacketAccessBit) >
|
||||
struct inplace_transpose_selector;
|
||||
|
||||
template<typename MatrixType>
|
||||
struct inplace_transpose_selector<MatrixType,true> { // square matrix
|
||||
struct inplace_transpose_selector<MatrixType,true,false> { // square matrix
|
||||
static void run(MatrixType& m) {
|
||||
m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose());
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: vectorized path is currently limited to LargestPacketSize x LargestPacketSize cases only.
|
||||
template<typename MatrixType>
|
||||
struct inplace_transpose_selector<MatrixType,false> { // non square matrix
|
||||
struct inplace_transpose_selector<MatrixType,true,true> { // PacketSize x PacketSize
|
||||
static void run(MatrixType& m) {
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename internal::packet_traits<typename MatrixType::Scalar>::type Packet;
|
||||
const Index PacketSize = internal::packet_traits<Scalar>::size;
|
||||
const Index Alignment = internal::evaluator<MatrixType>::Alignment;
|
||||
PacketBlock<Packet> A;
|
||||
for (Index i=0; i<PacketSize; ++i)
|
||||
A.packet[i] = m.template packetByOuterInner<Alignment>(i,0);
|
||||
internal::ptranspose(A);
|
||||
for (Index i=0; i<PacketSize; ++i)
|
||||
m.template writePacket<Alignment>(m.rowIndexByOuterInner(i,0), m.colIndexByOuterInner(i,0), A.packet[i]);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename MatrixType,bool MatchPacketSize>
|
||||
struct inplace_transpose_selector<MatrixType,false,MatchPacketSize> { // non square matrix
|
||||
static void run(MatrixType& m) {
|
||||
if (m.rows()==m.cols())
|
||||
m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose());
|
||||
@@ -284,7 +270,8 @@ struct inplace_transpose_selector<MatrixType,false> { // non square matrix
|
||||
* Notice however that this method is only useful if you want to replace a matrix by its own transpose.
|
||||
* If you just need the transpose of a matrix, use transpose().
|
||||
*
|
||||
* \note if the matrix is not square, then \c *this must be a resizable matrix.
|
||||
* \note if the matrix is not square, then \c *this must be a resizable matrix.
|
||||
* This excludes (non-square) fixed-size matrices, block-expressions and maps.
|
||||
*
|
||||
* \sa transpose(), adjoint(), adjointInPlace() */
|
||||
template<typename Derived>
|
||||
@@ -315,6 +302,7 @@ inline void DenseBase<Derived>::transposeInPlace()
|
||||
* If you just need the adjoint of a matrix, use adjoint().
|
||||
*
|
||||
* \note if the matrix is not square, then \c *this must be a resizable matrix.
|
||||
* This excludes (non-square) fixed-size matrices, block-expressions and maps.
|
||||
*
|
||||
* \sa transpose(), adjoint(), transposeInPlace() */
|
||||
template<typename Derived>
|
||||
@@ -329,14 +317,6 @@ inline void MatrixBase<Derived>::adjointInPlace()
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename BinOp,typename NestedXpr,typename Rhs>
|
||||
struct blas_traits<SelfCwiseBinaryOp<BinOp,NestedXpr,Rhs> >
|
||||
: blas_traits<NestedXpr>
|
||||
{
|
||||
typedef SelfCwiseBinaryOp<BinOp,NestedXpr,Rhs> XprType;
|
||||
static inline const XprType extract(const XprType& x) { return x; }
|
||||
};
|
||||
|
||||
template<bool DestIsTransposed, typename OtherDerived>
|
||||
struct check_transpose_aliasing_compile_time_selector
|
||||
{
|
||||
@@ -402,15 +382,15 @@ struct checkTransposeAliasing_impl<Derived, OtherDerived, false>
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Dst, typename Src>
|
||||
void check_for_aliasing(const Dst &dst, const Src &src)
|
||||
{
|
||||
internal::checkTransposeAliasing_impl<Dst, Src>::run(dst, src);
|
||||
}
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
void DenseBase<Derived>::checkTransposeAliasing(const OtherDerived& other) const
|
||||
{
|
||||
internal::checkTransposeAliasing_impl<Derived, OtherDerived>::run(derived(), other);
|
||||
}
|
||||
#endif
|
||||
#endif // EIGEN_NO_DEBUG
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
|
||||
@@ -41,10 +41,6 @@ namespace Eigen {
|
||||
* \sa class PermutationMatrix
|
||||
*/
|
||||
|
||||
namespace internal {
|
||||
template<typename TranspositionType, typename MatrixType, int Side, bool Transposed=false> struct transposition_matrix_product_retval;
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
class TranspositionsBase
|
||||
{
|
||||
@@ -53,7 +49,8 @@ class TranspositionsBase
|
||||
public:
|
||||
|
||||
typedef typename Traits::IndicesType IndicesType;
|
||||
typedef typename IndicesType::Scalar Index;
|
||||
typedef typename IndicesType::Scalar StorageIndex;
|
||||
typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
|
||||
|
||||
Derived& derived() { return *static_cast<Derived*>(this); }
|
||||
const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
||||
@@ -65,7 +62,7 @@ class TranspositionsBase
|
||||
indices() = other.indices();
|
||||
return derived();
|
||||
}
|
||||
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
/** This is a special case of the templated operator=. Its purpose is to
|
||||
* prevent a default operator= from hiding the templated operator=.
|
||||
@@ -78,20 +75,24 @@ class TranspositionsBase
|
||||
#endif
|
||||
|
||||
/** \returns the number of transpositions */
|
||||
inline Index size() const { return indices().size(); }
|
||||
Index size() const { return indices().size(); }
|
||||
/** \returns the number of rows of the equivalent permutation matrix */
|
||||
Index rows() const { return indices().size(); }
|
||||
/** \returns the number of columns of the equivalent permutation matrix */
|
||||
Index cols() const { return indices().size(); }
|
||||
|
||||
/** Direct access to the underlying index vector */
|
||||
inline const Index& coeff(Index i) const { return indices().coeff(i); }
|
||||
inline const StorageIndex& coeff(Index i) const { return indices().coeff(i); }
|
||||
/** Direct access to the underlying index vector */
|
||||
inline Index& coeffRef(Index i) { return indices().coeffRef(i); }
|
||||
inline StorageIndex& coeffRef(Index i) { return indices().coeffRef(i); }
|
||||
/** Direct access to the underlying index vector */
|
||||
inline const Index& operator()(Index i) const { return indices()(i); }
|
||||
inline const StorageIndex& operator()(Index i) const { return indices()(i); }
|
||||
/** Direct access to the underlying index vector */
|
||||
inline Index& operator()(Index i) { return indices()(i); }
|
||||
inline StorageIndex& operator()(Index i) { return indices()(i); }
|
||||
/** Direct access to the underlying index vector */
|
||||
inline const Index& operator[](Index i) const { return indices()(i); }
|
||||
inline const StorageIndex& operator[](Index i) const { return indices()(i); }
|
||||
/** Direct access to the underlying index vector */
|
||||
inline Index& operator[](Index i) { return indices()(i); }
|
||||
inline StorageIndex& operator[](Index i) { return indices()(i); }
|
||||
|
||||
/** const version of indices(). */
|
||||
const IndicesType& indices() const { return derived().indices(); }
|
||||
@@ -99,7 +100,7 @@ class TranspositionsBase
|
||||
IndicesType& indices() { return derived().indices(); }
|
||||
|
||||
/** Resizes to given size. */
|
||||
inline void resize(int newSize)
|
||||
inline void resize(Index newSize)
|
||||
{
|
||||
indices().resize(newSize);
|
||||
}
|
||||
@@ -107,7 +108,7 @@ class TranspositionsBase
|
||||
/** Sets \c *this to represents an identity transformation */
|
||||
void setIdentity()
|
||||
{
|
||||
for(int i = 0; i < indices().size(); ++i)
|
||||
for(StorageIndex i = 0; i < indices().size(); ++i)
|
||||
coeffRef(i) = i;
|
||||
}
|
||||
|
||||
@@ -144,23 +145,24 @@ class TranspositionsBase
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType>
|
||||
struct traits<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType> >
|
||||
template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex>
|
||||
struct traits<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex> >
|
||||
: traits<PermutationMatrix<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex> >
|
||||
{
|
||||
typedef IndexType Index;
|
||||
typedef Matrix<Index, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType;
|
||||
typedef Matrix<_StorageIndex, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType;
|
||||
typedef TranspositionsStorage StorageKind;
|
||||
};
|
||||
}
|
||||
|
||||
template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType>
|
||||
class Transpositions : public TranspositionsBase<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType> >
|
||||
template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex>
|
||||
class Transpositions : public TranspositionsBase<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex> >
|
||||
{
|
||||
typedef internal::traits<Transpositions> Traits;
|
||||
public:
|
||||
|
||||
typedef TranspositionsBase<Transpositions> Base;
|
||||
typedef typename Traits::IndicesType IndicesType;
|
||||
typedef typename IndicesType::Scalar Index;
|
||||
typedef typename IndicesType::Scalar StorageIndex;
|
||||
|
||||
inline Transpositions() {}
|
||||
|
||||
@@ -177,7 +179,7 @@ class Transpositions : public TranspositionsBase<Transpositions<SizeAtCompileTim
|
||||
|
||||
/** Generic constructor from expression of the transposition indices. */
|
||||
template<typename Other>
|
||||
explicit inline Transpositions(const MatrixBase<Other>& a_indices) : m_indices(a_indices)
|
||||
explicit inline Transpositions(const MatrixBase<Other>& indices) : m_indices(indices)
|
||||
{}
|
||||
|
||||
/** Copies the \a other transpositions into \c *this */
|
||||
@@ -215,30 +217,32 @@ class Transpositions : public TranspositionsBase<Transpositions<SizeAtCompileTim
|
||||
|
||||
|
||||
namespace internal {
|
||||
template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int _PacketAccess>
|
||||
struct traits<Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,_PacketAccess> >
|
||||
template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex, int _PacketAccess>
|
||||
struct traits<Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex>,_PacketAccess> >
|
||||
: traits<PermutationMatrix<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex> >
|
||||
{
|
||||
typedef IndexType Index;
|
||||
typedef Map<const Matrix<Index,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1>, _PacketAccess> IndicesType;
|
||||
typedef Map<const Matrix<_StorageIndex,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1>, _PacketAccess> IndicesType;
|
||||
typedef _StorageIndex StorageIndex;
|
||||
typedef TranspositionsStorage StorageKind;
|
||||
};
|
||||
}
|
||||
|
||||
template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename IndexType, int PacketAccess>
|
||||
class Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,PacketAccess>
|
||||
: public TranspositionsBase<Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,PacketAccess> >
|
||||
template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex, int PacketAccess>
|
||||
class Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex>,PacketAccess>
|
||||
: public TranspositionsBase<Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex>,PacketAccess> >
|
||||
{
|
||||
typedef internal::traits<Map> Traits;
|
||||
public:
|
||||
|
||||
typedef TranspositionsBase<Map> Base;
|
||||
typedef typename Traits::IndicesType IndicesType;
|
||||
typedef typename IndicesType::Scalar Index;
|
||||
typedef typename IndicesType::Scalar StorageIndex;
|
||||
|
||||
inline Map(const Index* indicesPtr)
|
||||
explicit inline Map(const StorageIndex* indicesPtr)
|
||||
: m_indices(indicesPtr)
|
||||
{}
|
||||
|
||||
inline Map(const Index* indicesPtr, Index size)
|
||||
inline Map(const StorageIndex* indicesPtr, Index size)
|
||||
: m_indices(indicesPtr,size)
|
||||
{}
|
||||
|
||||
@@ -274,9 +278,9 @@ class Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,IndexType>,Packe
|
||||
namespace internal {
|
||||
template<typename _IndicesType>
|
||||
struct traits<TranspositionsWrapper<_IndicesType> >
|
||||
: traits<PermutationWrapper<_IndicesType> >
|
||||
{
|
||||
typedef typename _IndicesType::Scalar Index;
|
||||
typedef _IndicesType IndicesType;
|
||||
typedef TranspositionsStorage StorageKind;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -289,10 +293,10 @@ class TranspositionsWrapper
|
||||
|
||||
typedef TranspositionsBase<TranspositionsWrapper> Base;
|
||||
typedef typename Traits::IndicesType IndicesType;
|
||||
typedef typename IndicesType::Scalar Index;
|
||||
typedef typename IndicesType::Scalar StorageIndex;
|
||||
|
||||
inline TranspositionsWrapper(IndicesType& a_indices)
|
||||
: m_indices(a_indices)
|
||||
explicit inline TranspositionsWrapper(IndicesType& indices)
|
||||
: m_indices(indices)
|
||||
{}
|
||||
|
||||
/** Copies the \a other transpositions into \c *this */
|
||||
@@ -324,80 +328,43 @@ class TranspositionsWrapper
|
||||
const typename IndicesType::Nested m_indices;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** \returns the \a matrix with the \a transpositions applied to the columns.
|
||||
*/
|
||||
template<typename Derived, typename TranspositionsDerived>
|
||||
inline const internal::transposition_matrix_product_retval<TranspositionsDerived, Derived, OnTheRight>
|
||||
operator*(const MatrixBase<Derived>& matrix,
|
||||
const TranspositionsBase<TranspositionsDerived> &transpositions)
|
||||
template<typename MatrixDerived, typename TranspositionsDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
const Product<MatrixDerived, TranspositionsDerived, AliasFreeProduct>
|
||||
operator*(const MatrixBase<MatrixDerived> &matrix,
|
||||
const TranspositionsBase<TranspositionsDerived>& transpositions)
|
||||
{
|
||||
return internal::transposition_matrix_product_retval
|
||||
<TranspositionsDerived, Derived, OnTheRight>
|
||||
(transpositions.derived(), matrix.derived());
|
||||
return Product<MatrixDerived, TranspositionsDerived, AliasFreeProduct>
|
||||
(matrix.derived(), transpositions.derived());
|
||||
}
|
||||
|
||||
/** \returns the \a matrix with the \a transpositions applied to the rows.
|
||||
*/
|
||||
template<typename Derived, typename TranspositionDerived>
|
||||
inline const internal::transposition_matrix_product_retval
|
||||
<TranspositionDerived, Derived, OnTheLeft>
|
||||
operator*(const TranspositionsBase<TranspositionDerived> &transpositions,
|
||||
const MatrixBase<Derived>& matrix)
|
||||
template<typename TranspositionsDerived, typename MatrixDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
const Product<TranspositionsDerived, MatrixDerived, AliasFreeProduct>
|
||||
operator*(const TranspositionsBase<TranspositionsDerived> &transpositions,
|
||||
const MatrixBase<MatrixDerived>& matrix)
|
||||
{
|
||||
return internal::transposition_matrix_product_retval
|
||||
<TranspositionDerived, Derived, OnTheLeft>
|
||||
(transpositions.derived(), matrix.derived());
|
||||
return Product<TranspositionsDerived, MatrixDerived, AliasFreeProduct>
|
||||
(transpositions.derived(), matrix.derived());
|
||||
}
|
||||
|
||||
// Template partial specialization for transposed/inverse transpositions
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename TranspositionType, typename MatrixType, int Side, bool Transposed>
|
||||
struct traits<transposition_matrix_product_retval<TranspositionType, MatrixType, Side, Transposed> >
|
||||
{
|
||||
typedef typename MatrixType::PlainObject ReturnType;
|
||||
};
|
||||
|
||||
template<typename TranspositionType, typename MatrixType, int Side, bool Transposed>
|
||||
struct transposition_matrix_product_retval
|
||||
: public ReturnByValue<transposition_matrix_product_retval<TranspositionType, MatrixType, Side, Transposed> >
|
||||
{
|
||||
typedef typename remove_all<typename MatrixType::Nested>::type MatrixTypeNestedCleaned;
|
||||
typedef typename TranspositionType::Index Index;
|
||||
|
||||
transposition_matrix_product_retval(const TranspositionType& tr, const MatrixType& matrix)
|
||||
: m_transpositions(tr), m_matrix(matrix)
|
||||
{}
|
||||
|
||||
inline int rows() const { return m_matrix.rows(); }
|
||||
inline int cols() const { return m_matrix.cols(); }
|
||||
|
||||
template<typename Dest> inline void evalTo(Dest& dst) const
|
||||
{
|
||||
const int size = m_transpositions.size();
|
||||
Index j = 0;
|
||||
|
||||
if(!(is_same<MatrixTypeNestedCleaned,Dest>::value && extract_data(dst) == extract_data(m_matrix)))
|
||||
dst = m_matrix;
|
||||
|
||||
for(int k=(Transposed?size-1:0) ; Transposed?k>=0:k<size ; Transposed?--k:++k)
|
||||
if((j=m_transpositions.coeff(k))!=k)
|
||||
{
|
||||
if(Side==OnTheLeft)
|
||||
dst.row(k).swap(dst.row(j));
|
||||
else if(Side==OnTheRight)
|
||||
dst.col(k).swap(dst.col(j));
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
const TranspositionType& m_transpositions;
|
||||
typename MatrixType::Nested m_matrix;
|
||||
};
|
||||
template<typename Derived>
|
||||
struct traits<Transpose<TranspositionsBase<Derived> > >
|
||||
: traits<Derived>
|
||||
{};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
/* Template partial specialization for transposed/inverse transpositions */
|
||||
|
||||
template<typename TranspositionsDerived>
|
||||
class Transpose<TranspositionsBase<TranspositionsDerived> >
|
||||
{
|
||||
@@ -405,27 +372,31 @@ class Transpose<TranspositionsBase<TranspositionsDerived> >
|
||||
typedef typename TranspositionType::IndicesType IndicesType;
|
||||
public:
|
||||
|
||||
Transpose(const TranspositionType& t) : m_transpositions(t) {}
|
||||
explicit Transpose(const TranspositionType& t) : m_transpositions(t) {}
|
||||
|
||||
inline int size() const { return m_transpositions.size(); }
|
||||
Index size() const { return m_transpositions.size(); }
|
||||
Index rows() const { return m_transpositions.size(); }
|
||||
Index cols() const { return m_transpositions.size(); }
|
||||
|
||||
/** \returns the \a matrix with the inverse transpositions applied to the columns.
|
||||
*/
|
||||
template<typename Derived> friend
|
||||
inline const internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheRight, true>
|
||||
operator*(const MatrixBase<Derived>& matrix, const Transpose& trt)
|
||||
template<typename OtherDerived> friend
|
||||
const Product<OtherDerived, Transpose, AliasFreeProduct>
|
||||
operator*(const MatrixBase<OtherDerived>& matrix, const Transpose& trt)
|
||||
{
|
||||
return internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheRight, true>(trt.m_transpositions, matrix.derived());
|
||||
return Product<OtherDerived, Transpose, AliasFreeProduct>(matrix.derived(), trt.derived());
|
||||
}
|
||||
|
||||
/** \returns the \a matrix with the inverse transpositions applied to the rows.
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline const internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheLeft, true>
|
||||
operator*(const MatrixBase<Derived>& matrix) const
|
||||
template<typename OtherDerived>
|
||||
const Product<Transpose, OtherDerived, AliasFreeProduct>
|
||||
operator*(const MatrixBase<OtherDerived>& matrix) const
|
||||
{
|
||||
return internal::transposition_matrix_product_retval<TranspositionType, Derived, OnTheLeft, true>(m_transpositions, matrix.derived());
|
||||
return Product<Transpose, OtherDerived, AliasFreeProduct>(*this, matrix.derived());
|
||||
}
|
||||
|
||||
const TranspositionType& nestedExpression() const { return m_transpositions; }
|
||||
|
||||
protected:
|
||||
const TranspositionType& m_transpositions;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -72,6 +72,7 @@ template<typename VectorType, int Size> class VectorBlock
|
||||
|
||||
/** Dynamic-size constructor
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline VectorBlock(VectorType& vector, Index start, Index size)
|
||||
: Base(vector,
|
||||
IsColVector ? start : 0, IsColVector ? 0 : start,
|
||||
@@ -82,6 +83,7 @@ template<typename VectorType, int Size> class VectorBlock
|
||||
|
||||
/** Fixed-size constructor
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline VectorBlock(VectorType& vector, Index start)
|
||||
: Base(vector, IsColVector ? start : 0, IsColVector ? 0 : start)
|
||||
{
|
||||
|
||||
@@ -41,31 +41,22 @@ struct traits<PartialReduxExpr<MatrixType, MemberOp, Direction> >
|
||||
typedef typename traits<MatrixType>::StorageKind StorageKind;
|
||||
typedef typename traits<MatrixType>::XprKind XprKind;
|
||||
typedef typename MatrixType::Scalar InputScalar;
|
||||
typedef typename nested<MatrixType>::type MatrixTypeNested;
|
||||
typedef typename ref_selector<MatrixType>::type MatrixTypeNested;
|
||||
typedef typename remove_all<MatrixTypeNested>::type _MatrixTypeNested;
|
||||
enum {
|
||||
RowsAtCompileTime = Direction==Vertical ? 1 : MatrixType::RowsAtCompileTime,
|
||||
ColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::ColsAtCompileTime,
|
||||
MaxRowsAtCompileTime = Direction==Vertical ? 1 : MatrixType::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::MaxColsAtCompileTime,
|
||||
Flags0 = (unsigned int)_MatrixTypeNested::Flags & HereditaryBits,
|
||||
Flags = (Flags0 & ~RowMajorBit) | (RowsAtCompileTime == 1 ? RowMajorBit : 0),
|
||||
TraversalSize = Direction==Vertical ? RowsAtCompileTime : ColsAtCompileTime
|
||||
};
|
||||
#if EIGEN_GNUC_AT_LEAST(3,4)
|
||||
typedef typename MemberOp::template Cost<InputScalar,int(TraversalSize)> CostOpType;
|
||||
#else
|
||||
typedef typename MemberOp::template Cost<InputScalar,TraversalSize> CostOpType;
|
||||
#endif
|
||||
enum {
|
||||
CoeffReadCost = TraversalSize * traits<_MatrixTypeNested>::CoeffReadCost + int(CostOpType::value)
|
||||
Flags = RowsAtCompileTime == 1 ? RowMajorBit : 0,
|
||||
TraversalSize = Direction==Vertical ? MatrixType::RowsAtCompileTime : MatrixType::ColsAtCompileTime
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
template< typename MatrixType, typename MemberOp, int Direction>
|
||||
class PartialReduxExpr : internal::no_assignment_operator,
|
||||
public internal::dense_xpr_base< PartialReduxExpr<MatrixType, MemberOp, Direction> >::type
|
||||
class PartialReduxExpr : public internal::dense_xpr_base< PartialReduxExpr<MatrixType, MemberOp, Direction> >::type,
|
||||
internal::no_assignment_operator
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -74,13 +65,16 @@ class PartialReduxExpr : internal::no_assignment_operator,
|
||||
typedef typename internal::traits<PartialReduxExpr>::MatrixTypeNested MatrixTypeNested;
|
||||
typedef typename internal::traits<PartialReduxExpr>::_MatrixTypeNested _MatrixTypeNested;
|
||||
|
||||
PartialReduxExpr(const MatrixType& mat, const MemberOp& func = MemberOp())
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit PartialReduxExpr(const MatrixType& mat, const MemberOp& func = MemberOp())
|
||||
: m_matrix(mat), m_functor(func) {}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
Index rows() const { return (Direction==Vertical ? 1 : m_matrix.rows()); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
Index cols() const { return (Direction==Horizontal ? 1 : m_matrix.cols()); }
|
||||
|
||||
EIGEN_STRONG_INLINE const Scalar coeff(Index i, Index j) const
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar coeff(Index i, Index j) const
|
||||
{
|
||||
if (Direction==Vertical)
|
||||
return m_functor(m_matrix.col(j));
|
||||
@@ -88,7 +82,7 @@ class PartialReduxExpr : internal::no_assignment_operator,
|
||||
return m_functor(m_matrix.row(i));
|
||||
}
|
||||
|
||||
const Scalar coeff(Index index) const
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
|
||||
{
|
||||
if (Direction==Vertical)
|
||||
return m_functor(m_matrix.col(index));
|
||||
@@ -109,7 +103,8 @@ class PartialReduxExpr : internal::no_assignment_operator,
|
||||
template<typename Scalar, int Size> struct Cost \
|
||||
{ enum { value = COST }; }; \
|
||||
template<typename XprType> \
|
||||
EIGEN_STRONG_INLINE ResultType operator()(const XprType& mat) const \
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
|
||||
ResultType operator()(const XprType& mat) const \
|
||||
{ return mat.MEMBER(); } \
|
||||
}
|
||||
|
||||
@@ -133,13 +128,13 @@ EIGEN_MEMBER_FUNCTOR(prod, (Size-1)*NumTraits<Scalar>::MulCost);
|
||||
template <typename BinaryOp, typename Scalar>
|
||||
struct member_redux {
|
||||
typedef typename result_of<
|
||||
BinaryOp(Scalar)
|
||||
BinaryOp(Scalar,Scalar)
|
||||
>::type result_type;
|
||||
template<typename _Scalar, int Size> struct Cost
|
||||
{ enum { value = (Size-1) * functor_traits<BinaryOp>::Cost }; };
|
||||
member_redux(const BinaryOp func) : m_functor(func) {}
|
||||
EIGEN_DEVICE_FUNC explicit member_redux(const BinaryOp func) : m_functor(func) {}
|
||||
template<typename Derived>
|
||||
inline result_type operator()(const DenseBase<Derived>& mat) const
|
||||
EIGEN_DEVICE_FUNC inline result_type operator()(const DenseBase<Derived>& mat) const
|
||||
{ return mat.redux(m_functor); }
|
||||
const BinaryOp m_functor;
|
||||
};
|
||||
@@ -168,16 +163,15 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
|
||||
typedef typename ExpressionType::Scalar Scalar;
|
||||
typedef typename ExpressionType::RealScalar RealScalar;
|
||||
typedef typename ExpressionType::Index Index;
|
||||
typedef typename internal::conditional<internal::must_nest_by_value<ExpressionType>::ret,
|
||||
ExpressionType, ExpressionType&>::type ExpressionTypeNested;
|
||||
typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
|
||||
typedef typename internal::ref_selector<ExpressionType>::non_const_type ExpressionTypeNested;
|
||||
typedef typename internal::remove_all<ExpressionTypeNested>::type ExpressionTypeNestedCleaned;
|
||||
|
||||
template<template<typename _Scalar> class Functor,
|
||||
typename Scalar=typename internal::traits<ExpressionType>::Scalar> struct ReturnType
|
||||
typename Scalar_=Scalar> struct ReturnType
|
||||
{
|
||||
typedef PartialReduxExpr<ExpressionType,
|
||||
Functor<Scalar>,
|
||||
Functor<Scalar_>,
|
||||
Direction
|
||||
> Type;
|
||||
};
|
||||
@@ -185,23 +179,24 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
template<typename BinaryOp> struct ReduxReturnType
|
||||
{
|
||||
typedef PartialReduxExpr<ExpressionType,
|
||||
internal::member_redux<BinaryOp,typename internal::traits<ExpressionType>::Scalar>,
|
||||
internal::member_redux<BinaryOp,Scalar>,
|
||||
Direction
|
||||
> Type;
|
||||
};
|
||||
|
||||
enum {
|
||||
IsVertical = (Direction==Vertical) ? 1 : 0,
|
||||
IsHorizontal = (Direction==Horizontal) ? 1 : 0
|
||||
isVertical = (Direction==Vertical) ? 1 : 0,
|
||||
isHorizontal = (Direction==Horizontal) ? 1 : 0
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
/** \internal
|
||||
* \returns the i-th subvector according to the \c Direction */
|
||||
typedef typename internal::conditional<Direction==Vertical,
|
||||
typedef typename internal::conditional<isVertical,
|
||||
typename ExpressionType::ColXpr,
|
||||
typename ExpressionType::RowXpr>::type SubVector;
|
||||
EIGEN_DEVICE_FUNC
|
||||
SubVector subVector(Index i)
|
||||
{
|
||||
return SubVector(m_matrix.derived(),i);
|
||||
@@ -209,58 +204,62 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
|
||||
/** \internal
|
||||
* \returns the number of subvectors in the direction \c Direction */
|
||||
EIGEN_DEVICE_FUNC
|
||||
Index subVectors() const
|
||||
{ return Direction==Vertical?m_matrix.cols():m_matrix.rows(); }
|
||||
{ return isVertical?m_matrix.cols():m_matrix.rows(); }
|
||||
|
||||
template<typename OtherDerived> struct ExtendedType {
|
||||
typedef Replicate<OtherDerived,
|
||||
Direction==Vertical ? 1 : ExpressionType::RowsAtCompileTime,
|
||||
Direction==Horizontal ? 1 : ExpressionType::ColsAtCompileTime> Type;
|
||||
isVertical ? 1 : ExpressionType::RowsAtCompileTime,
|
||||
isHorizontal ? 1 : ExpressionType::ColsAtCompileTime> Type;
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* Replicates a vector to match the size of \c *this */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename ExtendedType<OtherDerived>::Type
|
||||
extendedTo(const DenseBase<OtherDerived>& other) const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Vertical, OtherDerived::MaxColsAtCompileTime==1),
|
||||
EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(isVertical, OtherDerived::MaxColsAtCompileTime==1),
|
||||
YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED)
|
||||
EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Horizontal, OtherDerived::MaxRowsAtCompileTime==1),
|
||||
EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(isHorizontal, OtherDerived::MaxRowsAtCompileTime==1),
|
||||
YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED)
|
||||
return typename ExtendedType<OtherDerived>::Type
|
||||
(other.derived(),
|
||||
Direction==Vertical ? 1 : m_matrix.rows(),
|
||||
Direction==Horizontal ? 1 : m_matrix.cols());
|
||||
isVertical ? 1 : m_matrix.rows(),
|
||||
isHorizontal ? 1 : m_matrix.cols());
|
||||
}
|
||||
|
||||
template<typename OtherDerived> struct OppositeExtendedType {
|
||||
typedef Replicate<OtherDerived,
|
||||
Direction==Horizontal ? 1 : ExpressionType::RowsAtCompileTime,
|
||||
Direction==Vertical ? 1 : ExpressionType::ColsAtCompileTime> Type;
|
||||
isHorizontal ? 1 : ExpressionType::RowsAtCompileTime,
|
||||
isVertical ? 1 : ExpressionType::ColsAtCompileTime> Type;
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* Replicates a vector in the opposite direction to match the size of \c *this */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename OppositeExtendedType<OtherDerived>::Type
|
||||
extendedToOpposite(const DenseBase<OtherDerived>& other) const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Horizontal, OtherDerived::MaxColsAtCompileTime==1),
|
||||
EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(isHorizontal, OtherDerived::MaxColsAtCompileTime==1),
|
||||
YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED)
|
||||
EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Vertical, OtherDerived::MaxRowsAtCompileTime==1),
|
||||
EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(isVertical, OtherDerived::MaxRowsAtCompileTime==1),
|
||||
YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED)
|
||||
return typename OppositeExtendedType<OtherDerived>::Type
|
||||
(other.derived(),
|
||||
Direction==Horizontal ? 1 : m_matrix.rows(),
|
||||
Direction==Vertical ? 1 : m_matrix.cols());
|
||||
isHorizontal ? 1 : m_matrix.rows(),
|
||||
isVertical ? 1 : m_matrix.cols());
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
inline VectorwiseOp(ExpressionType& matrix) : m_matrix(matrix) {}
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit inline VectorwiseOp(ExpressionType& matrix) : m_matrix(matrix) {}
|
||||
|
||||
/** \internal */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const ExpressionType& _expression() const { return m_matrix; }
|
||||
|
||||
/** \returns a row or column vector expression of \c *this reduxed by \a func
|
||||
@@ -271,9 +270,25 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
* \sa class VectorwiseOp, DenseBase::colwise(), DenseBase::rowwise()
|
||||
*/
|
||||
template<typename BinaryOp>
|
||||
EIGEN_DEVICE_FUNC
|
||||
const typename ReduxReturnType<BinaryOp>::Type
|
||||
redux(const BinaryOp& func = BinaryOp()) const
|
||||
{ return typename ReduxReturnType<BinaryOp>::Type(_expression(), func); }
|
||||
{ return typename ReduxReturnType<BinaryOp>::Type(_expression(), internal::member_redux<BinaryOp,Scalar>(func)); }
|
||||
|
||||
typedef typename ReturnType<internal::member_minCoeff>::Type MinCoeffReturnType;
|
||||
typedef typename ReturnType<internal::member_maxCoeff>::Type MaxCoeffReturnType;
|
||||
typedef typename ReturnType<internal::member_squaredNorm,RealScalar>::Type SquaredNormReturnType;
|
||||
typedef typename ReturnType<internal::member_norm,RealScalar>::Type NormReturnType;
|
||||
typedef typename ReturnType<internal::member_blueNorm,RealScalar>::Type BlueNormReturnType;
|
||||
typedef typename ReturnType<internal::member_stableNorm,RealScalar>::Type StableNormReturnType;
|
||||
typedef typename ReturnType<internal::member_hypotNorm,RealScalar>::Type HypotNormReturnType;
|
||||
typedef typename ReturnType<internal::member_sum>::Type SumReturnType;
|
||||
typedef typename ReturnType<internal::member_mean>::Type MeanReturnType;
|
||||
typedef typename ReturnType<internal::member_all>::Type AllReturnType;
|
||||
typedef typename ReturnType<internal::member_any>::Type AnyReturnType;
|
||||
typedef PartialReduxExpr<ExpressionType, internal::member_count<Index>, Direction> CountReturnType;
|
||||
typedef typename ReturnType<internal::member_prod>::Type ProdReturnType;
|
||||
typedef Reverse<ExpressionType, Direction> ReverseReturnType;
|
||||
|
||||
/** \returns a row (or column) vector expression of the smallest coefficient
|
||||
* of each column (or row) of the referenced expression.
|
||||
@@ -284,8 +299,9 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
* Output: \verbinclude PartialRedux_minCoeff.out
|
||||
*
|
||||
* \sa DenseBase::minCoeff() */
|
||||
const typename ReturnType<internal::member_minCoeff>::Type minCoeff() const
|
||||
{ return _expression(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
const MinCoeffReturnType minCoeff() const
|
||||
{ return MinCoeffReturnType(_expression()); }
|
||||
|
||||
/** \returns a row (or column) vector expression of the largest coefficient
|
||||
* of each column (or row) of the referenced expression.
|
||||
@@ -296,55 +312,66 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
* Output: \verbinclude PartialRedux_maxCoeff.out
|
||||
*
|
||||
* \sa DenseBase::maxCoeff() */
|
||||
const typename ReturnType<internal::member_maxCoeff>::Type maxCoeff() const
|
||||
{ return _expression(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
const MaxCoeffReturnType maxCoeff() const
|
||||
{ return MaxCoeffReturnType(_expression()); }
|
||||
|
||||
/** \returns a row (or column) vector expression of the squared norm
|
||||
* of each column (or row) of the referenced expression.
|
||||
* This is a vector with real entries, even if the original matrix has complex entries.
|
||||
*
|
||||
* Example: \include PartialRedux_squaredNorm.cpp
|
||||
* Output: \verbinclude PartialRedux_squaredNorm.out
|
||||
*
|
||||
* \sa DenseBase::squaredNorm() */
|
||||
const typename ReturnType<internal::member_squaredNorm,RealScalar>::Type squaredNorm() const
|
||||
{ return _expression(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
const SquaredNormReturnType squaredNorm() const
|
||||
{ return SquaredNormReturnType(_expression()); }
|
||||
|
||||
/** \returns a row (or column) vector expression of the norm
|
||||
* of each column (or row) of the referenced expression.
|
||||
* This is a vector with real entries, even if the original matrix has complex entries.
|
||||
*
|
||||
* Example: \include PartialRedux_norm.cpp
|
||||
* Output: \verbinclude PartialRedux_norm.out
|
||||
*
|
||||
* \sa DenseBase::norm() */
|
||||
const typename ReturnType<internal::member_norm,RealScalar>::Type norm() const
|
||||
{ return _expression(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
const NormReturnType norm() const
|
||||
{ return NormReturnType(_expression()); }
|
||||
|
||||
|
||||
/** \returns a row (or column) vector expression of the norm
|
||||
* of each column (or row) of the referenced expression, using
|
||||
* blue's algorithm.
|
||||
* Blue's algorithm.
|
||||
* This is a vector with real entries, even if the original matrix has complex entries.
|
||||
*
|
||||
* \sa DenseBase::blueNorm() */
|
||||
const typename ReturnType<internal::member_blueNorm,RealScalar>::Type blueNorm() const
|
||||
{ return _expression(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
const BlueNormReturnType blueNorm() const
|
||||
{ return BlueNormReturnType(_expression()); }
|
||||
|
||||
|
||||
/** \returns a row (or column) vector expression of the norm
|
||||
* of each column (or row) of the referenced expression, avoiding
|
||||
* underflow and overflow.
|
||||
* This is a vector with real entries, even if the original matrix has complex entries.
|
||||
*
|
||||
* \sa DenseBase::stableNorm() */
|
||||
const typename ReturnType<internal::member_stableNorm,RealScalar>::Type stableNorm() const
|
||||
{ return _expression(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
const StableNormReturnType stableNorm() const
|
||||
{ return StableNormReturnType(_expression()); }
|
||||
|
||||
|
||||
/** \returns a row (or column) vector expression of the norm
|
||||
* of each column (or row) of the referenced expression, avoiding
|
||||
* underflow and overflow using a concatenation of hypot() calls.
|
||||
* This is a vector with real entries, even if the original matrix has complex entries.
|
||||
*
|
||||
* \sa DenseBase::hypotNorm() */
|
||||
const typename ReturnType<internal::member_hypotNorm,RealScalar>::Type hypotNorm() const
|
||||
{ return _expression(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
const HypotNormReturnType hypotNorm() const
|
||||
{ return HypotNormReturnType(_expression()); }
|
||||
|
||||
/** \returns a row (or column) vector expression of the sum
|
||||
* of each column (or row) of the referenced expression.
|
||||
@@ -353,39 +380,48 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
* Output: \verbinclude PartialRedux_sum.out
|
||||
*
|
||||
* \sa DenseBase::sum() */
|
||||
const typename ReturnType<internal::member_sum>::Type sum() const
|
||||
{ return _expression(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
const SumReturnType sum() const
|
||||
{ return SumReturnType(_expression()); }
|
||||
|
||||
/** \returns a row (or column) vector expression of the mean
|
||||
* of each column (or row) of the referenced expression.
|
||||
*
|
||||
* \sa DenseBase::mean() */
|
||||
const typename ReturnType<internal::member_mean>::Type mean() const
|
||||
{ return _expression(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
const MeanReturnType mean() const
|
||||
{ return MeanReturnType(_expression()); }
|
||||
|
||||
/** \returns a row (or column) vector expression representing
|
||||
* whether \b all coefficients of each respective column (or row) are \c true.
|
||||
* This expression can be assigned to a vector with entries of type \c bool.
|
||||
*
|
||||
* \sa DenseBase::all() */
|
||||
const typename ReturnType<internal::member_all>::Type all() const
|
||||
{ return _expression(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
const AllReturnType all() const
|
||||
{ return AllReturnType(_expression()); }
|
||||
|
||||
/** \returns a row (or column) vector expression representing
|
||||
* whether \b at \b least one coefficient of each respective column (or row) is \c true.
|
||||
* This expression can be assigned to a vector with entries of type \c bool.
|
||||
*
|
||||
* \sa DenseBase::any() */
|
||||
const typename ReturnType<internal::member_any>::Type any() const
|
||||
{ return _expression(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
const AnyReturnType any() const
|
||||
{ return Any(_expression()); }
|
||||
|
||||
/** \returns a row (or column) vector expression representing
|
||||
* the number of \c true coefficients of each respective column (or row).
|
||||
* This expression can be assigned to a vector whose entries have the same type as is used to
|
||||
* index entries of the original matrix; for dense matrices, this is \c std::ptrdiff_t .
|
||||
*
|
||||
* Example: \include PartialRedux_count.cpp
|
||||
* Output: \verbinclude PartialRedux_count.out
|
||||
*
|
||||
* \sa DenseBase::count() */
|
||||
const PartialReduxExpr<ExpressionType, internal::member_count<Index>, Direction> count() const
|
||||
{ return _expression(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
const CountReturnType count() const
|
||||
{ return CountReturnType(_expression()); }
|
||||
|
||||
/** \returns a row (or column) vector expression of the product
|
||||
* of each column (or row) of the referenced expression.
|
||||
@@ -394,8 +430,9 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
* Output: \verbinclude PartialRedux_prod.out
|
||||
*
|
||||
* \sa DenseBase::prod() */
|
||||
const typename ReturnType<internal::member_prod>::Type prod() const
|
||||
{ return _expression(); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
const ProdReturnType prod() const
|
||||
{ return ProdReturnType(_expression()); }
|
||||
|
||||
|
||||
/** \returns a matrix expression
|
||||
@@ -405,10 +442,12 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
* Output: \verbinclude Vectorwise_reverse.out
|
||||
*
|
||||
* \sa DenseBase::reverse() */
|
||||
const Reverse<ExpressionType, Direction> reverse() const
|
||||
{ return Reverse<ExpressionType, Direction>( _expression() ); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
const ReverseReturnType reverse() const
|
||||
{ return ReverseReturnType( _expression() ); }
|
||||
|
||||
typedef Replicate<ExpressionType,Direction==Vertical?Dynamic:1,Direction==Horizontal?Dynamic:1> ReplicateReturnType;
|
||||
typedef Replicate<ExpressionType,(isVertical?Dynamic:1),(isHorizontal?Dynamic:1)> ReplicateReturnType;
|
||||
EIGEN_DEVICE_FUNC
|
||||
const ReplicateReturnType replicate(Index factor) const;
|
||||
|
||||
/**
|
||||
@@ -420,17 +459,20 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
* \sa VectorwiseOp::replicate(Index), DenseBase::replicate(), class Replicate
|
||||
*/
|
||||
// NOTE implemented here because of sunstudio's compilation errors
|
||||
template<int Factor> const Replicate<ExpressionType,(IsVertical?Factor:1),(IsHorizontal?Factor:1)>
|
||||
// isVertical*Factor+isHorizontal instead of (isVertical?Factor:1) to handle CUDA bug with ternary operator
|
||||
template<int Factor> const Replicate<ExpressionType,isVertical*Factor+isHorizontal,isHorizontal*Factor+isVertical>
|
||||
EIGEN_DEVICE_FUNC
|
||||
replicate(Index factor = Factor) const
|
||||
{
|
||||
return Replicate<ExpressionType,Direction==Vertical?Factor:1,Direction==Horizontal?Factor:1>
|
||||
(_expression(),Direction==Vertical?factor:1,Direction==Horizontal?factor:1);
|
||||
return Replicate<ExpressionType,(isVertical?Factor:1),(isHorizontal?Factor:1)>
|
||||
(_expression(),isVertical?factor:1,isHorizontal?factor:1);
|
||||
}
|
||||
|
||||
/////////// Artithmetic operators ///////////
|
||||
|
||||
/** Copies the vector \a other to each subvector of \c *this */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
ExpressionType& operator=(const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
||||
@@ -441,6 +483,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
|
||||
/** Adds the vector \a other to each subvector of \c *this */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
ExpressionType& operator+=(const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
||||
@@ -450,6 +493,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
|
||||
/** Substracts the vector \a other to each subvector of \c *this */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
ExpressionType& operator-=(const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
||||
@@ -459,6 +503,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
|
||||
/** Multiples each subvector of \c *this by the vector \a other */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
ExpressionType& operator*=(const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
||||
@@ -470,6 +515,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
|
||||
/** Divides each subvector of \c *this by the vector \a other */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
ExpressionType& operator/=(const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
||||
@@ -480,7 +526,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
}
|
||||
|
||||
/** Returns the expression of the sum of the vector \a other to each subvector of \c *this */
|
||||
template<typename OtherDerived> EIGEN_STRONG_INLINE
|
||||
template<typename OtherDerived> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||
CwiseBinaryOp<internal::scalar_sum_op<Scalar>,
|
||||
const ExpressionTypeNestedCleaned,
|
||||
const typename ExtendedType<OtherDerived>::Type>
|
||||
@@ -493,6 +539,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
|
||||
/** Returns the expression of the difference between each subvector of \c *this and the vector \a other */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
CwiseBinaryOp<internal::scalar_difference_op<Scalar>,
|
||||
const ExpressionTypeNestedCleaned,
|
||||
const typename ExtendedType<OtherDerived>::Type>
|
||||
@@ -505,10 +552,11 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
|
||||
/** Returns the expression where each subvector is the product of the vector \a other
|
||||
* by the corresponding subvector of \c *this */
|
||||
template<typename OtherDerived> EIGEN_STRONG_INLINE
|
||||
template<typename OtherDerived> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||
CwiseBinaryOp<internal::scalar_product_op<Scalar>,
|
||||
const ExpressionTypeNestedCleaned,
|
||||
const typename ExtendedType<OtherDerived>::Type>
|
||||
EIGEN_DEVICE_FUNC
|
||||
operator*(const DenseBase<OtherDerived>& other) const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
|
||||
@@ -520,6 +568,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
/** Returns the expression where each subvector is the quotient of the corresponding
|
||||
* subvector of \c *this by the vector \a other */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
CwiseBinaryOp<internal::scalar_quotient_op<Scalar>,
|
||||
const ExpressionTypeNestedCleaned,
|
||||
const typename ExtendedType<OtherDerived>::Type>
|
||||
@@ -535,6 +584,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
* The referenced matrix is \b not modified.
|
||||
* \sa MatrixBase::normalized(), normalize()
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
CwiseBinaryOp<internal::scalar_quotient_op<Scalar>,
|
||||
const ExpressionTypeNestedCleaned,
|
||||
const typename OppositeExtendedType<typename ReturnType<internal::member_norm,RealScalar>::Type>::Type>
|
||||
@@ -544,18 +594,20 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
/** Normalize in-place each row or columns of the referenced matrix.
|
||||
* \sa MatrixBase::normalize(), normalized()
|
||||
*/
|
||||
void normalize() {
|
||||
EIGEN_DEVICE_FUNC void normalize() {
|
||||
m_matrix = this->normalized();
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC inline void reverseInPlace();
|
||||
|
||||
/////////// Geometry module ///////////
|
||||
|
||||
#if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS
|
||||
Homogeneous<ExpressionType,Direction> homogeneous() const;
|
||||
#endif
|
||||
typedef Homogeneous<ExpressionType,Direction> HomogeneousReturnType;
|
||||
HomogeneousReturnType homogeneous() const;
|
||||
|
||||
typedef typename ExpressionType::PlainObject CrossReturnType;
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
const CrossReturnType cross(const MatrixBase<OtherDerived>& other) const;
|
||||
|
||||
enum {
|
||||
@@ -586,19 +638,8 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
|
||||
ExpressionTypeNested m_matrix;
|
||||
};
|
||||
|
||||
/** \returns a VectorwiseOp wrapper of *this providing additional partial reduction operations
|
||||
*
|
||||
* Example: \include MatrixBase_colwise.cpp
|
||||
* Output: \verbinclude MatrixBase_colwise.out
|
||||
*
|
||||
* \sa rowwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline const typename DenseBase<Derived>::ConstColwiseReturnType
|
||||
DenseBase<Derived>::colwise() const
|
||||
{
|
||||
return derived();
|
||||
}
|
||||
//const colwise moved to DenseBase.h due to CUDA compiler bug
|
||||
|
||||
|
||||
/** \returns a writable VectorwiseOp wrapper of *this providing additional partial reduction operations
|
||||
*
|
||||
@@ -608,22 +649,11 @@ template<typename Derived>
|
||||
inline typename DenseBase<Derived>::ColwiseReturnType
|
||||
DenseBase<Derived>::colwise()
|
||||
{
|
||||
return derived();
|
||||
return ColwiseReturnType(derived());
|
||||
}
|
||||
|
||||
/** \returns a VectorwiseOp wrapper of *this providing additional partial reduction operations
|
||||
*
|
||||
* Example: \include MatrixBase_rowwise.cpp
|
||||
* Output: \verbinclude MatrixBase_rowwise.out
|
||||
*
|
||||
* \sa colwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline const typename DenseBase<Derived>::ConstRowwiseReturnType
|
||||
DenseBase<Derived>::rowwise() const
|
||||
{
|
||||
return derived();
|
||||
}
|
||||
//const rowwise moved to DenseBase.h due to CUDA compiler bug
|
||||
|
||||
|
||||
/** \returns a writable VectorwiseOp wrapper of *this providing additional partial reduction operations
|
||||
*
|
||||
@@ -633,7 +663,7 @@ template<typename Derived>
|
||||
inline typename DenseBase<Derived>::RowwiseReturnType
|
||||
DenseBase<Derived>::rowwise()
|
||||
{
|
||||
return derived();
|
||||
return RowwiseReturnType(derived());
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -22,6 +22,7 @@ struct visitor_impl
|
||||
row = (UnrollCount-1) % Derived::RowsAtCompileTime
|
||||
};
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline void run(const Derived &mat, Visitor& visitor)
|
||||
{
|
||||
visitor_impl<Visitor, Derived, UnrollCount-1>::run(mat, visitor);
|
||||
@@ -32,6 +33,7 @@ struct visitor_impl
|
||||
template<typename Visitor, typename Derived>
|
||||
struct visitor_impl<Visitor, Derived, 1>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline void run(const Derived &mat, Visitor& visitor)
|
||||
{
|
||||
return visitor.init(mat.coeff(0, 0), 0, 0);
|
||||
@@ -41,7 +43,7 @@ struct visitor_impl<Visitor, Derived, 1>
|
||||
template<typename Visitor, typename Derived>
|
||||
struct visitor_impl<Visitor, Derived, Dynamic>
|
||||
{
|
||||
typedef typename Derived::Index Index;
|
||||
EIGEN_DEVICE_FUNC
|
||||
static inline void run(const Derived& mat, Visitor& visitor)
|
||||
{
|
||||
visitor.init(mat.coeff(0,0), 0, 0);
|
||||
@@ -53,6 +55,33 @@ struct visitor_impl<Visitor, Derived, Dynamic>
|
||||
}
|
||||
};
|
||||
|
||||
// evaluator adaptor
|
||||
template<typename XprType>
|
||||
class visitor_evaluator
|
||||
{
|
||||
public:
|
||||
EIGEN_DEVICE_FUNC
|
||||
explicit visitor_evaluator(const XprType &xpr) : m_evaluator(xpr), m_xpr(xpr) {}
|
||||
|
||||
typedef typename XprType::Scalar Scalar;
|
||||
typedef typename XprType::CoeffReturnType CoeffReturnType;
|
||||
|
||||
enum {
|
||||
RowsAtCompileTime = XprType::RowsAtCompileTime,
|
||||
CoeffReadCost = internal::evaluator<XprType>::CoeffReadCost
|
||||
};
|
||||
|
||||
EIGEN_DEVICE_FUNC Index rows() const { return m_xpr.rows(); }
|
||||
EIGEN_DEVICE_FUNC Index cols() const { return m_xpr.cols(); }
|
||||
EIGEN_DEVICE_FUNC Index size() const { return m_xpr.size(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC CoeffReturnType coeff(Index row, Index col) const
|
||||
{ return m_evaluator.coeff(row, col); }
|
||||
|
||||
protected:
|
||||
internal::evaluator<XprType> m_evaluator;
|
||||
const XprType &m_xpr;
|
||||
};
|
||||
} // end namespace internal
|
||||
|
||||
/** Applies the visitor \a visitor to the whole coefficients of the matrix or vector.
|
||||
@@ -74,16 +103,20 @@ struct visitor_impl<Visitor, Derived, Dynamic>
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename Visitor>
|
||||
EIGEN_DEVICE_FUNC
|
||||
void DenseBase<Derived>::visit(Visitor& visitor) const
|
||||
{
|
||||
enum { unroll = SizeAtCompileTime != Dynamic
|
||||
&& CoeffReadCost != Dynamic
|
||||
&& (SizeAtCompileTime == 1 || internal::functor_traits<Visitor>::Cost != Dynamic)
|
||||
&& SizeAtCompileTime * CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost
|
||||
<= EIGEN_UNROLLING_LIMIT };
|
||||
return internal::visitor_impl<Visitor, Derived,
|
||||
typedef typename internal::visitor_evaluator<Derived> ThisEvaluator;
|
||||
ThisEvaluator thisEval(derived());
|
||||
|
||||
enum { unroll = SizeAtCompileTime != Dynamic
|
||||
&& ThisEvaluator::CoeffReadCost != Dynamic
|
||||
&& (SizeAtCompileTime == 1 || internal::functor_traits<Visitor>::Cost != Dynamic)
|
||||
&& SizeAtCompileTime * ThisEvaluator::CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost
|
||||
<= EIGEN_UNROLLING_LIMIT };
|
||||
return internal::visitor_impl<Visitor, ThisEvaluator,
|
||||
unroll ? int(SizeAtCompileTime) : Dynamic
|
||||
>::run(derived(), visitor);
|
||||
>::run(thisEval, visitor);
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
@@ -94,10 +127,10 @@ namespace internal {
|
||||
template <typename Derived>
|
||||
struct coeff_visitor
|
||||
{
|
||||
typedef typename Derived::Index Index;
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
Index row, col;
|
||||
Scalar res;
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline void init(const Scalar& value, Index i, Index j)
|
||||
{
|
||||
res = value;
|
||||
@@ -114,8 +147,8 @@ struct coeff_visitor
|
||||
template <typename Derived>
|
||||
struct min_coeff_visitor : coeff_visitor<Derived>
|
||||
{
|
||||
typedef typename Derived::Index Index;
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
void operator() (const Scalar& value, Index i, Index j)
|
||||
{
|
||||
if(value < this->res)
|
||||
@@ -142,8 +175,8 @@ struct functor_traits<min_coeff_visitor<Scalar> > {
|
||||
template <typename Derived>
|
||||
struct max_coeff_visitor : coeff_visitor<Derived>
|
||||
{
|
||||
typedef typename Derived::Index Index;
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
EIGEN_DEVICE_FUNC
|
||||
void operator() (const Scalar& value, Index i, Index j)
|
||||
{
|
||||
if(value > this->res)
|
||||
@@ -171,6 +204,7 @@ struct functor_traits<max_coeff_visitor<Scalar> > {
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename IndexType>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename internal::traits<Derived>::Scalar
|
||||
DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
|
||||
{
|
||||
@@ -188,13 +222,14 @@ DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename IndexType>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename internal::traits<Derived>::Scalar
|
||||
DenseBase<Derived>::minCoeff(IndexType* index) const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
internal::min_coeff_visitor<Derived> minVisitor;
|
||||
this->visit(minVisitor);
|
||||
*index = (RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row;
|
||||
*index = IndexType((RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row);
|
||||
return minVisitor.res;
|
||||
}
|
||||
|
||||
@@ -205,6 +240,7 @@ DenseBase<Derived>::minCoeff(IndexType* index) const
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename IndexType>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename internal::traits<Derived>::Scalar
|
||||
DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const
|
||||
{
|
||||
@@ -222,6 +258,7 @@ DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename IndexType>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename internal::traits<Derived>::Scalar
|
||||
DenseBase<Derived>::maxCoeff(IndexType* index) const
|
||||
{
|
||||
|
||||
6
Eigen/src/Core/arch/AVX/CMakeLists.txt
Normal file
6
Eigen/src/Core/arch/AVX/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
FILE(GLOB Eigen_Core_arch_AVX_SRCS "*.h")
|
||||
|
||||
INSTALL(FILES
|
||||
${Eigen_Core_arch_AVX_SRCS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Core/arch/AVX COMPONENT Devel
|
||||
)
|
||||
463
Eigen/src/Core/arch/AVX/Complex.h
Normal file
463
Eigen/src/Core/arch/AVX/Complex.h
Normal file
@@ -0,0 +1,463 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2014 Benoit Steiner (benoit.steiner.goog@gmail.com)
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef EIGEN_COMPLEX_AVX_H
|
||||
#define EIGEN_COMPLEX_AVX_H
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
//---------- float ----------
|
||||
struct Packet4cf
|
||||
{
|
||||
EIGEN_STRONG_INLINE Packet4cf() {}
|
||||
EIGEN_STRONG_INLINE explicit Packet4cf(const __m256& a) : v(a) {}
|
||||
__m256 v;
|
||||
};
|
||||
|
||||
template<> struct packet_traits<std::complex<float> > : default_packet_traits
|
||||
{
|
||||
typedef Packet4cf type;
|
||||
typedef Packet2cf half;
|
||||
enum {
|
||||
Vectorizable = 1,
|
||||
AlignedOnScalar = 1,
|
||||
size = 4,
|
||||
HasHalfPacket = 1,
|
||||
|
||||
HasAdd = 1,
|
||||
HasSub = 1,
|
||||
HasMul = 1,
|
||||
HasDiv = 1,
|
||||
HasNegate = 1,
|
||||
HasAbs = 0,
|
||||
HasAbs2 = 0,
|
||||
HasMin = 0,
|
||||
HasMax = 0,
|
||||
HasSetLinear = 0
|
||||
};
|
||||
};
|
||||
|
||||
template<> struct unpacket_traits<Packet4cf> { typedef std::complex<float> type; enum {size=4, alignment=Aligned32}; typedef Packet2cf half; };
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4cf padd<Packet4cf>(const Packet4cf& a, const Packet4cf& b) { return Packet4cf(_mm256_add_ps(a.v,b.v)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4cf psub<Packet4cf>(const Packet4cf& a, const Packet4cf& b) { return Packet4cf(_mm256_sub_ps(a.v,b.v)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4cf pnegate(const Packet4cf& a)
|
||||
{
|
||||
return Packet4cf(pnegate(a.v));
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet4cf pconj(const Packet4cf& a)
|
||||
{
|
||||
const __m256 mask = _mm256_castsi256_ps(_mm256_setr_epi32(0x00000000,0x80000000,0x00000000,0x80000000,0x00000000,0x80000000,0x00000000,0x80000000));
|
||||
return Packet4cf(_mm256_xor_ps(a.v,mask));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4cf pmul<Packet4cf>(const Packet4cf& a, const Packet4cf& b)
|
||||
{
|
||||
__m256 tmp1 = _mm256_mul_ps(_mm256_moveldup_ps(a.v), b.v);
|
||||
__m256 tmp2 = _mm256_mul_ps(_mm256_movehdup_ps(a.v), _mm256_permute_ps(b.v, _MM_SHUFFLE(2,3,0,1)));
|
||||
__m256 result = _mm256_addsub_ps(tmp1, tmp2);
|
||||
return Packet4cf(result);
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4cf pand <Packet4cf>(const Packet4cf& a, const Packet4cf& b) { return Packet4cf(_mm256_and_ps(a.v,b.v)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4cf por <Packet4cf>(const Packet4cf& a, const Packet4cf& b) { return Packet4cf(_mm256_or_ps(a.v,b.v)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4cf pxor <Packet4cf>(const Packet4cf& a, const Packet4cf& b) { return Packet4cf(_mm256_xor_ps(a.v,b.v)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4cf pandnot<Packet4cf>(const Packet4cf& a, const Packet4cf& b) { return Packet4cf(_mm256_andnot_ps(a.v,b.v)); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4cf pload <Packet4cf>(const std::complex<float>* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet4cf(pload<Packet8f>(&numext::real_ref(*from))); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4cf ploadu<Packet4cf>(const std::complex<float>* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet4cf(ploadu<Packet8f>(&numext::real_ref(*from))); }
|
||||
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4cf pset1<Packet4cf>(const std::complex<float>& from)
|
||||
{
|
||||
return Packet4cf(_mm256_castpd_ps(_mm256_broadcast_sd((const double*)(const void*)&from)));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4cf ploaddup<Packet4cf>(const std::complex<float>* from)
|
||||
{
|
||||
// FIXME The following might be optimized using _mm256_movedup_pd
|
||||
Packet2cf a = ploaddup<Packet2cf>(from);
|
||||
Packet2cf b = ploaddup<Packet2cf>(from+1);
|
||||
return Packet4cf(_mm256_insertf128_ps(_mm256_castps128_ps256(a.v), b.v, 1));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE void pstore <std::complex<float> >(std::complex<float>* to, const Packet4cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore(&numext::real_ref(*to), from.v); }
|
||||
template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float>* to, const Packet4cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu(&numext::real_ref(*to), from.v); }
|
||||
|
||||
template<> EIGEN_DEVICE_FUNC inline Packet4cf pgather<std::complex<float>, Packet4cf>(const std::complex<float>* from, Index stride)
|
||||
{
|
||||
return Packet4cf(_mm256_set_ps(std::imag(from[3*stride]), std::real(from[3*stride]),
|
||||
std::imag(from[2*stride]), std::real(from[2*stride]),
|
||||
std::imag(from[1*stride]), std::real(from[1*stride]),
|
||||
std::imag(from[0*stride]), std::real(from[0*stride])));
|
||||
}
|
||||
|
||||
template<> EIGEN_DEVICE_FUNC inline void pscatter<std::complex<float>, Packet4cf>(std::complex<float>* to, const Packet4cf& from, Index stride)
|
||||
{
|
||||
__m128 low = _mm256_extractf128_ps(from.v, 0);
|
||||
to[stride*0] = std::complex<float>(_mm_cvtss_f32(_mm_shuffle_ps(low, low, 0)),
|
||||
_mm_cvtss_f32(_mm_shuffle_ps(low, low, 1)));
|
||||
to[stride*1] = std::complex<float>(_mm_cvtss_f32(_mm_shuffle_ps(low, low, 2)),
|
||||
_mm_cvtss_f32(_mm_shuffle_ps(low, low, 3)));
|
||||
|
||||
__m128 high = _mm256_extractf128_ps(from.v, 1);
|
||||
to[stride*2] = std::complex<float>(_mm_cvtss_f32(_mm_shuffle_ps(high, high, 0)),
|
||||
_mm_cvtss_f32(_mm_shuffle_ps(high, high, 1)));
|
||||
to[stride*3] = std::complex<float>(_mm_cvtss_f32(_mm_shuffle_ps(high, high, 2)),
|
||||
_mm_cvtss_f32(_mm_shuffle_ps(high, high, 3)));
|
||||
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE std::complex<float> pfirst<Packet4cf>(const Packet4cf& a)
|
||||
{
|
||||
return pfirst(Packet2cf(_mm256_castps256_ps128(a.v)));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4cf preverse(const Packet4cf& a) {
|
||||
__m128 low = _mm256_extractf128_ps(a.v, 0);
|
||||
__m128 high = _mm256_extractf128_ps(a.v, 1);
|
||||
__m128d lowd = _mm_castps_pd(low);
|
||||
__m128d highd = _mm_castps_pd(high);
|
||||
low = _mm_castpd_ps(_mm_shuffle_pd(lowd,lowd,0x1));
|
||||
high = _mm_castpd_ps(_mm_shuffle_pd(highd,highd,0x1));
|
||||
__m256 result = _mm256_setzero_ps();
|
||||
result = _mm256_insertf128_ps(result, low, 1);
|
||||
result = _mm256_insertf128_ps(result, high, 0);
|
||||
return Packet4cf(result);
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE std::complex<float> predux<Packet4cf>(const Packet4cf& a)
|
||||
{
|
||||
return predux(padd(Packet2cf(_mm256_extractf128_ps(a.v,0)),
|
||||
Packet2cf(_mm256_extractf128_ps(a.v,1))));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4cf preduxp<Packet4cf>(const Packet4cf* vecs)
|
||||
{
|
||||
Packet8f t0 = _mm256_shuffle_ps(vecs[0].v, vecs[0].v, _MM_SHUFFLE(3, 1, 2 ,0));
|
||||
Packet8f t1 = _mm256_shuffle_ps(vecs[1].v, vecs[1].v, _MM_SHUFFLE(3, 1, 2 ,0));
|
||||
t0 = _mm256_hadd_ps(t0,t1);
|
||||
Packet8f t2 = _mm256_shuffle_ps(vecs[2].v, vecs[2].v, _MM_SHUFFLE(3, 1, 2 ,0));
|
||||
Packet8f t3 = _mm256_shuffle_ps(vecs[3].v, vecs[3].v, _MM_SHUFFLE(3, 1, 2 ,0));
|
||||
t2 = _mm256_hadd_ps(t2,t3);
|
||||
|
||||
t1 = _mm256_permute2f128_ps(t0,t2, 0 + (2<<4));
|
||||
t3 = _mm256_permute2f128_ps(t0,t2, 1 + (3<<4));
|
||||
|
||||
return Packet4cf(_mm256_add_ps(t1,t3));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE std::complex<float> predux_mul<Packet4cf>(const Packet4cf& a)
|
||||
{
|
||||
return predux_mul(pmul(Packet2cf(_mm256_extractf128_ps(a.v, 0)),
|
||||
Packet2cf(_mm256_extractf128_ps(a.v, 1))));
|
||||
}
|
||||
|
||||
template<int Offset>
|
||||
struct palign_impl<Offset,Packet4cf>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(Packet4cf& first, const Packet4cf& second)
|
||||
{
|
||||
if (Offset==0) return;
|
||||
palign_impl<Offset*2,Packet8f>::run(first.v, second.v);
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct conj_helper<Packet4cf, Packet4cf, false,true>
|
||||
{
|
||||
EIGEN_STRONG_INLINE Packet4cf pmadd(const Packet4cf& x, const Packet4cf& y, const Packet4cf& c) const
|
||||
{ return padd(pmul(x,y),c); }
|
||||
|
||||
EIGEN_STRONG_INLINE Packet4cf pmul(const Packet4cf& a, const Packet4cf& b) const
|
||||
{
|
||||
return internal::pmul(a, pconj(b));
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct conj_helper<Packet4cf, Packet4cf, true,false>
|
||||
{
|
||||
EIGEN_STRONG_INLINE Packet4cf pmadd(const Packet4cf& x, const Packet4cf& y, const Packet4cf& c) const
|
||||
{ return padd(pmul(x,y),c); }
|
||||
|
||||
EIGEN_STRONG_INLINE Packet4cf pmul(const Packet4cf& a, const Packet4cf& b) const
|
||||
{
|
||||
return internal::pmul(pconj(a), b);
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct conj_helper<Packet4cf, Packet4cf, true,true>
|
||||
{
|
||||
EIGEN_STRONG_INLINE Packet4cf pmadd(const Packet4cf& x, const Packet4cf& y, const Packet4cf& c) const
|
||||
{ return padd(pmul(x,y),c); }
|
||||
|
||||
EIGEN_STRONG_INLINE Packet4cf pmul(const Packet4cf& a, const Packet4cf& b) const
|
||||
{
|
||||
return pconj(internal::pmul(a, b));
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct conj_helper<Packet8f, Packet4cf, false,false>
|
||||
{
|
||||
EIGEN_STRONG_INLINE Packet4cf pmadd(const Packet8f& x, const Packet4cf& y, const Packet4cf& c) const
|
||||
{ return padd(c, pmul(x,y)); }
|
||||
|
||||
EIGEN_STRONG_INLINE Packet4cf pmul(const Packet8f& x, const Packet4cf& y) const
|
||||
{ return Packet4cf(Eigen::internal::pmul(x, y.v)); }
|
||||
};
|
||||
|
||||
template<> struct conj_helper<Packet4cf, Packet8f, false,false>
|
||||
{
|
||||
EIGEN_STRONG_INLINE Packet4cf pmadd(const Packet4cf& x, const Packet8f& y, const Packet4cf& c) const
|
||||
{ return padd(c, pmul(x,y)); }
|
||||
|
||||
EIGEN_STRONG_INLINE Packet4cf pmul(const Packet4cf& x, const Packet8f& y) const
|
||||
{ return Packet4cf(Eigen::internal::pmul(x.v, y)); }
|
||||
};
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4cf pdiv<Packet4cf>(const Packet4cf& a, const Packet4cf& b)
|
||||
{
|
||||
Packet4cf num = pmul(a, pconj(b));
|
||||
__m256 tmp = _mm256_mul_ps(b.v, b.v);
|
||||
__m256 tmp2 = _mm256_shuffle_ps(tmp,tmp,0xB1);
|
||||
__m256 denom = _mm256_add_ps(tmp, tmp2);
|
||||
return Packet4cf(_mm256_div_ps(num.v, denom));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4cf pcplxflip<Packet4cf>(const Packet4cf& x)
|
||||
{
|
||||
return Packet4cf(_mm256_shuffle_ps(x.v, x.v, _MM_SHUFFLE(2, 3, 0 ,1)));
|
||||
}
|
||||
|
||||
//---------- double ----------
|
||||
struct Packet2cd
|
||||
{
|
||||
EIGEN_STRONG_INLINE Packet2cd() {}
|
||||
EIGEN_STRONG_INLINE explicit Packet2cd(const __m256d& a) : v(a) {}
|
||||
__m256d v;
|
||||
};
|
||||
|
||||
template<> struct packet_traits<std::complex<double> > : default_packet_traits
|
||||
{
|
||||
typedef Packet2cd type;
|
||||
typedef Packet1cd half;
|
||||
enum {
|
||||
Vectorizable = 1,
|
||||
AlignedOnScalar = 0,
|
||||
size = 2,
|
||||
HasHalfPacket = 1,
|
||||
|
||||
HasAdd = 1,
|
||||
HasSub = 1,
|
||||
HasMul = 1,
|
||||
HasDiv = 1,
|
||||
HasNegate = 1,
|
||||
HasAbs = 0,
|
||||
HasAbs2 = 0,
|
||||
HasMin = 0,
|
||||
HasMax = 0,
|
||||
HasSetLinear = 0
|
||||
};
|
||||
};
|
||||
|
||||
template<> struct unpacket_traits<Packet2cd> { typedef std::complex<double> type; enum {size=2, alignment=Aligned32}; typedef Packet1cd half; };
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2cd padd<Packet2cd>(const Packet2cd& a, const Packet2cd& b) { return Packet2cd(_mm256_add_pd(a.v,b.v)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2cd psub<Packet2cd>(const Packet2cd& a, const Packet2cd& b) { return Packet2cd(_mm256_sub_pd(a.v,b.v)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2cd pnegate(const Packet2cd& a) { return Packet2cd(pnegate(a.v)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2cd pconj(const Packet2cd& a)
|
||||
{
|
||||
const __m256d mask = _mm256_castsi256_pd(_mm256_set_epi32(0x80000000,0x0,0x0,0x0,0x80000000,0x0,0x0,0x0));
|
||||
return Packet2cd(_mm256_xor_pd(a.v,mask));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2cd pmul<Packet2cd>(const Packet2cd& a, const Packet2cd& b)
|
||||
{
|
||||
__m256d tmp1 = _mm256_shuffle_pd(a.v,a.v,0x0);
|
||||
__m256d even = _mm256_mul_pd(tmp1, b.v);
|
||||
__m256d tmp2 = _mm256_shuffle_pd(a.v,a.v,0xF);
|
||||
__m256d tmp3 = _mm256_shuffle_pd(b.v,b.v,0x5);
|
||||
__m256d odd = _mm256_mul_pd(tmp2, tmp3);
|
||||
return Packet2cd(_mm256_addsub_pd(even, odd));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2cd pand <Packet2cd>(const Packet2cd& a, const Packet2cd& b) { return Packet2cd(_mm256_and_pd(a.v,b.v)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2cd por <Packet2cd>(const Packet2cd& a, const Packet2cd& b) { return Packet2cd(_mm256_or_pd(a.v,b.v)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2cd pxor <Packet2cd>(const Packet2cd& a, const Packet2cd& b) { return Packet2cd(_mm256_xor_pd(a.v,b.v)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2cd pandnot<Packet2cd>(const Packet2cd& a, const Packet2cd& b) { return Packet2cd(_mm256_andnot_pd(a.v,b.v)); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2cd pload <Packet2cd>(const std::complex<double>* from)
|
||||
{ EIGEN_DEBUG_ALIGNED_LOAD return Packet2cd(pload<Packet4d>((const double*)from)); }
|
||||
template<> EIGEN_STRONG_INLINE Packet2cd ploadu<Packet2cd>(const std::complex<double>* from)
|
||||
{ EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cd(ploadu<Packet4d>((const double*)from)); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2cd pset1<Packet2cd>(const std::complex<double>& from)
|
||||
{
|
||||
// in case casting to a __m128d* is really not safe, then we can still fallback to this version: (much slower though)
|
||||
// return Packet2cd(_mm256_loadu2_m128d((const double*)&from,(const double*)&from));
|
||||
return Packet2cd(_mm256_broadcast_pd((const __m128d*)(const void*)&from));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2cd ploaddup<Packet2cd>(const std::complex<double>* from) { return pset1<Packet2cd>(*from); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE void pstore <std::complex<double> >(std::complex<double> * to, const Packet2cd& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((double*)to, from.v); }
|
||||
template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<double> >(std::complex<double> * to, const Packet2cd& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, from.v); }
|
||||
|
||||
template<> EIGEN_DEVICE_FUNC inline Packet2cd pgather<std::complex<double>, Packet2cd>(const std::complex<double>* from, Index stride)
|
||||
{
|
||||
return Packet2cd(_mm256_set_pd(std::imag(from[1*stride]), std::real(from[1*stride]),
|
||||
std::imag(from[0*stride]), std::real(from[0*stride])));
|
||||
}
|
||||
|
||||
template<> EIGEN_DEVICE_FUNC inline void pscatter<std::complex<double>, Packet2cd>(std::complex<double>* to, const Packet2cd& from, Index stride)
|
||||
{
|
||||
__m128d low = _mm256_extractf128_pd(from.v, 0);
|
||||
to[stride*0] = std::complex<double>(_mm_cvtsd_f64(low), _mm_cvtsd_f64(_mm_shuffle_pd(low, low, 1)));
|
||||
__m128d high = _mm256_extractf128_pd(from.v, 1);
|
||||
to[stride*1] = std::complex<double>(_mm_cvtsd_f64(high), _mm_cvtsd_f64(_mm_shuffle_pd(high, high, 1)));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE std::complex<double> pfirst<Packet2cd>(const Packet2cd& a)
|
||||
{
|
||||
__m128d low = _mm256_extractf128_pd(a.v, 0);
|
||||
EIGEN_ALIGN16 double res[2];
|
||||
_mm_store_pd(res, low);
|
||||
return std::complex<double>(res[0],res[1]);
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2cd preverse(const Packet2cd& a) {
|
||||
__m256d result = _mm256_permute2f128_pd(a.v, a.v, 1);
|
||||
return Packet2cd(result);
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE std::complex<double> predux<Packet2cd>(const Packet2cd& a)
|
||||
{
|
||||
return predux(padd(Packet1cd(_mm256_extractf128_pd(a.v,0)),
|
||||
Packet1cd(_mm256_extractf128_pd(a.v,1))));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2cd preduxp<Packet2cd>(const Packet2cd* vecs)
|
||||
{
|
||||
Packet4d t0 = _mm256_permute2f128_pd(vecs[0].v,vecs[1].v, 0 + (2<<4));
|
||||
Packet4d t1 = _mm256_permute2f128_pd(vecs[0].v,vecs[1].v, 1 + (3<<4));
|
||||
|
||||
return Packet2cd(_mm256_add_pd(t0,t1));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE std::complex<double> predux_mul<Packet2cd>(const Packet2cd& a)
|
||||
{
|
||||
return predux(pmul(Packet1cd(_mm256_extractf128_pd(a.v,0)),
|
||||
Packet1cd(_mm256_extractf128_pd(a.v,1))));
|
||||
}
|
||||
|
||||
template<int Offset>
|
||||
struct palign_impl<Offset,Packet2cd>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(Packet2cd& first, const Packet2cd& second)
|
||||
{
|
||||
if (Offset==0) return;
|
||||
palign_impl<Offset*2,Packet4d>::run(first.v, second.v);
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct conj_helper<Packet2cd, Packet2cd, false,true>
|
||||
{
|
||||
EIGEN_STRONG_INLINE Packet2cd pmadd(const Packet2cd& x, const Packet2cd& y, const Packet2cd& c) const
|
||||
{ return padd(pmul(x,y),c); }
|
||||
|
||||
EIGEN_STRONG_INLINE Packet2cd pmul(const Packet2cd& a, const Packet2cd& b) const
|
||||
{
|
||||
return internal::pmul(a, pconj(b));
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct conj_helper<Packet2cd, Packet2cd, true,false>
|
||||
{
|
||||
EIGEN_STRONG_INLINE Packet2cd pmadd(const Packet2cd& x, const Packet2cd& y, const Packet2cd& c) const
|
||||
{ return padd(pmul(x,y),c); }
|
||||
|
||||
EIGEN_STRONG_INLINE Packet2cd pmul(const Packet2cd& a, const Packet2cd& b) const
|
||||
{
|
||||
return internal::pmul(pconj(a), b);
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct conj_helper<Packet2cd, Packet2cd, true,true>
|
||||
{
|
||||
EIGEN_STRONG_INLINE Packet2cd pmadd(const Packet2cd& x, const Packet2cd& y, const Packet2cd& c) const
|
||||
{ return padd(pmul(x,y),c); }
|
||||
|
||||
EIGEN_STRONG_INLINE Packet2cd pmul(const Packet2cd& a, const Packet2cd& b) const
|
||||
{
|
||||
return pconj(internal::pmul(a, b));
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct conj_helper<Packet4d, Packet2cd, false,false>
|
||||
{
|
||||
EIGEN_STRONG_INLINE Packet2cd pmadd(const Packet4d& x, const Packet2cd& y, const Packet2cd& c) const
|
||||
{ return padd(c, pmul(x,y)); }
|
||||
|
||||
EIGEN_STRONG_INLINE Packet2cd pmul(const Packet4d& x, const Packet2cd& y) const
|
||||
{ return Packet2cd(Eigen::internal::pmul(x, y.v)); }
|
||||
};
|
||||
|
||||
template<> struct conj_helper<Packet2cd, Packet4d, false,false>
|
||||
{
|
||||
EIGEN_STRONG_INLINE Packet2cd pmadd(const Packet2cd& x, const Packet4d& y, const Packet2cd& c) const
|
||||
{ return padd(c, pmul(x,y)); }
|
||||
|
||||
EIGEN_STRONG_INLINE Packet2cd pmul(const Packet2cd& x, const Packet4d& y) const
|
||||
{ return Packet2cd(Eigen::internal::pmul(x.v, y)); }
|
||||
};
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2cd pdiv<Packet2cd>(const Packet2cd& a, const Packet2cd& b)
|
||||
{
|
||||
Packet2cd num = pmul(a, pconj(b));
|
||||
__m256d tmp = _mm256_mul_pd(b.v, b.v);
|
||||
__m256d denom = _mm256_hadd_pd(tmp, tmp);
|
||||
return Packet2cd(_mm256_div_pd(num.v, denom));
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2cd pcplxflip<Packet2cd>(const Packet2cd& x)
|
||||
{
|
||||
return Packet2cd(_mm256_shuffle_pd(x.v, x.v, 0x5));
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC inline void
|
||||
ptranspose(PacketBlock<Packet4cf,4>& kernel) {
|
||||
__m256d P0 = _mm256_castps_pd(kernel.packet[0].v);
|
||||
__m256d P1 = _mm256_castps_pd(kernel.packet[1].v);
|
||||
__m256d P2 = _mm256_castps_pd(kernel.packet[2].v);
|
||||
__m256d P3 = _mm256_castps_pd(kernel.packet[3].v);
|
||||
|
||||
__m256d T0 = _mm256_shuffle_pd(P0, P1, 15);
|
||||
__m256d T1 = _mm256_shuffle_pd(P0, P1, 0);
|
||||
__m256d T2 = _mm256_shuffle_pd(P2, P3, 15);
|
||||
__m256d T3 = _mm256_shuffle_pd(P2, P3, 0);
|
||||
|
||||
kernel.packet[1].v = _mm256_castpd_ps(_mm256_permute2f128_pd(T0, T2, 32));
|
||||
kernel.packet[3].v = _mm256_castpd_ps(_mm256_permute2f128_pd(T0, T2, 49));
|
||||
kernel.packet[0].v = _mm256_castpd_ps(_mm256_permute2f128_pd(T1, T3, 32));
|
||||
kernel.packet[2].v = _mm256_castpd_ps(_mm256_permute2f128_pd(T1, T3, 49));
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC inline void
|
||||
ptranspose(PacketBlock<Packet2cd,2>& kernel) {
|
||||
__m256d tmp = _mm256_permute2f128_pd(kernel.packet[0].v, kernel.packet[1].v, 0+(2<<4));
|
||||
kernel.packet[1].v = _mm256_permute2f128_pd(kernel.packet[0].v, kernel.packet[1].v, 1+(3<<4));
|
||||
kernel.packet[0].v = tmp;
|
||||
}
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_COMPLEX_AVX_H
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user